diff --git a/mk/tests.mk b/mk/tests.mk
index 1ded5b0e643..d1924c67b2e 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -622,7 +622,6 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) = \
         --rustc-path $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
         --rustdoc-path $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
         --llvm-filecheck $(CFG_LLVM_INST_DIR_$(CFG_BUILD))/bin/FileCheck \
-        --aux-base $$(S)src/test/auxiliary/ \
         --stage-id stage$(1)-$(2) \
         --target $(2) \
         --host $(3) \
diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs
index a376b021a8a..b53a0a895af 100644
--- a/src/bootstrap/build/check.rs
+++ b/src/bootstrap/build/check.rs
@@ -70,7 +70,6 @@ pub fn compiletest(build: &Build,
     cmd.arg("--rustc-path").arg(build.compiler_path(compiler));
     cmd.arg("--rustdoc-path").arg(build.rustdoc(compiler));
     cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
-    cmd.arg("--aux-base").arg(build.src.join("src/test/auxiliary"));
     cmd.arg("--build-base").arg(testdir(build, compiler.host).join(suite));
     cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
     cmd.arg("--mode").arg(mode);
diff --git a/src/test/auxiliary/cgu_export_trait_method.rs b/src/test/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs
similarity index 100%
rename from src/test/auxiliary/cgu_export_trait_method.rs
rename to src/test/codegen-units/item-collection/auxiliary/cgu_export_trait_method.rs
diff --git a/src/test/auxiliary/cgu_extern_closures.rs b/src/test/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs
similarity index 100%
rename from src/test/auxiliary/cgu_extern_closures.rs
rename to src/test/codegen-units/item-collection/auxiliary/cgu_extern_closures.rs
diff --git a/src/test/auxiliary/cgu_generic_function.rs b/src/test/codegen-units/item-collection/auxiliary/cgu_generic_function.rs
similarity index 100%
rename from src/test/auxiliary/cgu_generic_function.rs
rename to src/test/codegen-units/item-collection/auxiliary/cgu_generic_function.rs
diff --git a/src/test/auxiliary/cgu_explicit_inlining.rs b/src/test/codegen-units/partitioning/auxiliary/cgu_explicit_inlining.rs
similarity index 100%
rename from src/test/auxiliary/cgu_explicit_inlining.rs
rename to src/test/codegen-units/partitioning/auxiliary/cgu_explicit_inlining.rs
diff --git a/src/test/auxiliary/cgu_extern_drop_glue.rs b/src/test/codegen-units/partitioning/auxiliary/cgu_extern_drop_glue.rs
similarity index 100%
rename from src/test/auxiliary/cgu_extern_drop_glue.rs
rename to src/test/codegen-units/partitioning/auxiliary/cgu_extern_drop_glue.rs
diff --git a/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs b/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs
new file mode 100644
index 00000000000..04c68748eca
--- /dev/null
+++ b/src/test/codegen-units/partitioning/auxiliary/cgu_generic_function.rs
@@ -0,0 +1,37 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "lib"]
+
+struct Struct(u32);
+
+#[inline(never)]
+pub fn foo<T>(x: T) -> (T, u32, i8) {
+    let (x, Struct(y)) = bar(x);
+    (x, y, 2)
+}
+
+#[inline(never)]
+fn bar<T>(x: T) -> (T, Struct) {
+    let _ = not_exported_and_not_generic(0);
+    (x, Struct(1))
+}
+
+// These should not contribute to the codegen items of other crates.
+#[inline(never)]
+pub fn exported_but_not_generic(x: i32) -> i64 {
+    x as i64
+}
+
+#[inline(never)]
+fn not_exported_and_not_generic(x: u32) -> u64 {
+    x as u64
+}
+
diff --git a/src/test/auxiliary/attr_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/attr_plugin_test.rs
similarity index 100%
rename from src/test/auxiliary/attr_plugin_test.rs
rename to src/test/compile-fail-fulldeps/auxiliary/attr_plugin_test.rs
diff --git a/src/test/auxiliary/lint_for_crate.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
similarity index 100%
rename from src/test/auxiliary/lint_for_crate.rs
rename to src/test/compile-fail-fulldeps/auxiliary/lint_for_crate.rs
diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
similarity index 100%
rename from src/test/auxiliary/lint_group_plugin_test.rs
rename to src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
diff --git a/src/test/auxiliary/lint_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
similarity index 100%
rename from src/test/auxiliary/lint_plugin_test.rs
rename to src/test/compile-fail-fulldeps/auxiliary/lint_plugin_test.rs
diff --git a/src/test/auxiliary/macro_crate_MacroRulesTT.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_MacroRulesTT.rs
similarity index 100%
rename from src/test/auxiliary/macro_crate_MacroRulesTT.rs
rename to src/test/compile-fail-fulldeps/auxiliary/macro_crate_MacroRulesTT.rs
diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
similarity index 100%
rename from src/test/auxiliary/macro_crate_test.rs
rename to src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
diff --git a/src/test/auxiliary/macro_reexport_1.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_reexport_1.rs
similarity index 100%
rename from src/test/auxiliary/macro_reexport_1.rs
rename to src/test/compile-fail-fulldeps/auxiliary/macro_reexport_1.rs
diff --git a/src/test/auxiliary/rlib_crate_test.rs b/src/test/compile-fail-fulldeps/auxiliary/rlib_crate_test.rs
similarity index 100%
rename from src/test/auxiliary/rlib_crate_test.rs
rename to src/test/compile-fail-fulldeps/auxiliary/rlib_crate_test.rs
diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/compile-fail-fulldeps/auxiliary/use_from_trait_xc.rs
similarity index 100%
rename from src/test/auxiliary/use_from_trait_xc.rs
rename to src/test/compile-fail-fulldeps/auxiliary/use_from_trait_xc.rs
diff --git a/src/test/auxiliary/allocator-dylib.rs b/src/test/compile-fail/auxiliary/allocator-dylib.rs
similarity index 100%
rename from src/test/auxiliary/allocator-dylib.rs
rename to src/test/compile-fail/auxiliary/allocator-dylib.rs
diff --git a/src/test/auxiliary/allocator-dylib2.rs b/src/test/compile-fail/auxiliary/allocator-dylib2.rs
similarity index 100%
rename from src/test/auxiliary/allocator-dylib2.rs
rename to src/test/compile-fail/auxiliary/allocator-dylib2.rs
diff --git a/src/test/auxiliary/allocator1.rs b/src/test/compile-fail/auxiliary/allocator1.rs
similarity index 100%
rename from src/test/auxiliary/allocator1.rs
rename to src/test/compile-fail/auxiliary/allocator1.rs
diff --git a/src/test/auxiliary/allocator2.rs b/src/test/compile-fail/auxiliary/allocator2.rs
similarity index 100%
rename from src/test/auxiliary/allocator2.rs
rename to src/test/compile-fail/auxiliary/allocator2.rs
diff --git a/src/test/auxiliary/allocator3.rs b/src/test/compile-fail/auxiliary/allocator3.rs
similarity index 100%
rename from src/test/auxiliary/allocator3.rs
rename to src/test/compile-fail/auxiliary/allocator3.rs
diff --git a/src/test/auxiliary/ambig_impl_2_lib.rs b/src/test/compile-fail/auxiliary/ambig_impl_2_lib.rs
similarity index 100%
rename from src/test/auxiliary/ambig_impl_2_lib.rs
rename to src/test/compile-fail/auxiliary/ambig_impl_2_lib.rs
diff --git a/src/test/auxiliary/cci_class.rs b/src/test/compile-fail/auxiliary/cci_class.rs
similarity index 100%
rename from src/test/auxiliary/cci_class.rs
rename to src/test/compile-fail/auxiliary/cci_class.rs
diff --git a/src/test/auxiliary/cci_class_5.rs b/src/test/compile-fail/auxiliary/cci_class_5.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_5.rs
rename to src/test/compile-fail/auxiliary/cci_class_5.rs
diff --git a/src/test/auxiliary/changing-crates-a1.rs b/src/test/compile-fail/auxiliary/changing-crates-a1.rs
similarity index 100%
rename from src/test/auxiliary/changing-crates-a1.rs
rename to src/test/compile-fail/auxiliary/changing-crates-a1.rs
diff --git a/src/test/auxiliary/changing-crates-a2.rs b/src/test/compile-fail/auxiliary/changing-crates-a2.rs
similarity index 100%
rename from src/test/auxiliary/changing-crates-a2.rs
rename to src/test/compile-fail/auxiliary/changing-crates-a2.rs
diff --git a/src/test/auxiliary/changing-crates-b.rs b/src/test/compile-fail/auxiliary/changing-crates-b.rs
similarity index 100%
rename from src/test/auxiliary/changing-crates-b.rs
rename to src/test/compile-fail/auxiliary/changing-crates-b.rs
diff --git a/src/test/auxiliary/coherence_copy_like_lib.rs b/src/test/compile-fail/auxiliary/coherence_copy_like_lib.rs
similarity index 100%
rename from src/test/auxiliary/coherence_copy_like_lib.rs
rename to src/test/compile-fail/auxiliary/coherence_copy_like_lib.rs
diff --git a/src/test/auxiliary/coherence_inherent_cc_lib.rs b/src/test/compile-fail/auxiliary/coherence_inherent_cc_lib.rs
similarity index 100%
rename from src/test/auxiliary/coherence_inherent_cc_lib.rs
rename to src/test/compile-fail/auxiliary/coherence_inherent_cc_lib.rs
diff --git a/src/test/auxiliary/coherence_lib.rs b/src/test/compile-fail/auxiliary/coherence_lib.rs
similarity index 100%
rename from src/test/auxiliary/coherence_lib.rs
rename to src/test/compile-fail/auxiliary/coherence_lib.rs
diff --git a/src/test/auxiliary/coherence_orphan_lib.rs b/src/test/compile-fail/auxiliary/coherence_orphan_lib.rs
similarity index 100%
rename from src/test/auxiliary/coherence_orphan_lib.rs
rename to src/test/compile-fail/auxiliary/coherence_orphan_lib.rs
diff --git a/src/test/auxiliary/const_fn_lib.rs b/src/test/compile-fail/auxiliary/const_fn_lib.rs
similarity index 100%
rename from src/test/auxiliary/const_fn_lib.rs
rename to src/test/compile-fail/auxiliary/const_fn_lib.rs
diff --git a/src/test/auxiliary/crate_a1.rs b/src/test/compile-fail/auxiliary/crate_a1.rs
similarity index 100%
rename from src/test/auxiliary/crate_a1.rs
rename to src/test/compile-fail/auxiliary/crate_a1.rs
diff --git a/src/test/auxiliary/crate_a2.rs b/src/test/compile-fail/auxiliary/crate_a2.rs
similarity index 100%
rename from src/test/auxiliary/crate_a2.rs
rename to src/test/compile-fail/auxiliary/crate_a2.rs
diff --git a/src/test/auxiliary/crateresolve1-1.rs b/src/test/compile-fail/auxiliary/crateresolve1-1.rs
similarity index 100%
rename from src/test/auxiliary/crateresolve1-1.rs
rename to src/test/compile-fail/auxiliary/crateresolve1-1.rs
diff --git a/src/test/auxiliary/crateresolve1-2.rs b/src/test/compile-fail/auxiliary/crateresolve1-2.rs
similarity index 100%
rename from src/test/auxiliary/crateresolve1-2.rs
rename to src/test/compile-fail/auxiliary/crateresolve1-2.rs
diff --git a/src/test/auxiliary/crateresolve1-3.rs b/src/test/compile-fail/auxiliary/crateresolve1-3.rs
similarity index 100%
rename from src/test/auxiliary/crateresolve1-3.rs
rename to src/test/compile-fail/auxiliary/crateresolve1-3.rs
diff --git a/src/test/auxiliary/default_ty_param_cross_crate_crate.rs b/src/test/compile-fail/auxiliary/default_ty_param_cross_crate_crate.rs
similarity index 100%
rename from src/test/auxiliary/default_ty_param_cross_crate_crate.rs
rename to src/test/compile-fail/auxiliary/default_ty_param_cross_crate_crate.rs
diff --git a/src/test/auxiliary/deprecation-lint.rs b/src/test/compile-fail/auxiliary/deprecation-lint.rs
similarity index 100%
rename from src/test/auxiliary/deprecation-lint.rs
rename to src/test/compile-fail/auxiliary/deprecation-lint.rs
diff --git a/src/test/auxiliary/empty-struct.rs b/src/test/compile-fail/auxiliary/empty-struct.rs
similarity index 100%
rename from src/test/auxiliary/empty-struct.rs
rename to src/test/compile-fail/auxiliary/empty-struct.rs
diff --git a/src/test/auxiliary/go_trait.rs b/src/test/compile-fail/auxiliary/go_trait.rs
similarity index 100%
rename from src/test/auxiliary/go_trait.rs
rename to src/test/compile-fail/auxiliary/go_trait.rs
diff --git a/src/test/auxiliary/inherited_stability.rs b/src/test/compile-fail/auxiliary/inherited_stability.rs
similarity index 100%
rename from src/test/auxiliary/inherited_stability.rs
rename to src/test/compile-fail/auxiliary/inherited_stability.rs
diff --git a/src/test/auxiliary/internal_unstable.rs b/src/test/compile-fail/auxiliary/internal_unstable.rs
similarity index 100%
rename from src/test/auxiliary/internal_unstable.rs
rename to src/test/compile-fail/auxiliary/internal_unstable.rs
diff --git a/src/test/auxiliary/issue-19163.rs b/src/test/compile-fail/auxiliary/issue-19163.rs
similarity index 100%
rename from src/test/auxiliary/issue-19163.rs
rename to src/test/compile-fail/auxiliary/issue-19163.rs
diff --git a/src/test/auxiliary/issue-21146-inc.rs b/src/test/compile-fail/auxiliary/issue-21146-inc.rs
similarity index 100%
rename from src/test/auxiliary/issue-21146-inc.rs
rename to src/test/compile-fail/auxiliary/issue-21146-inc.rs
diff --git a/src/test/auxiliary/issue-21221-3.rs b/src/test/compile-fail/auxiliary/issue-21221-3.rs
similarity index 100%
rename from src/test/auxiliary/issue-21221-3.rs
rename to src/test/compile-fail/auxiliary/issue-21221-3.rs
diff --git a/src/test/auxiliary/issue-21221-4.rs b/src/test/compile-fail/auxiliary/issue-21221-4.rs
similarity index 100%
rename from src/test/auxiliary/issue-21221-4.rs
rename to src/test/compile-fail/auxiliary/issue-21221-4.rs
diff --git a/src/test/auxiliary/issue-29181.rs b/src/test/compile-fail/auxiliary/issue-29181.rs
similarity index 100%
rename from src/test/auxiliary/issue-29181.rs
rename to src/test/compile-fail/auxiliary/issue-29181.rs
diff --git a/src/test/auxiliary/issue-30535.rs b/src/test/compile-fail/auxiliary/issue-30535.rs
similarity index 100%
rename from src/test/auxiliary/issue-30535.rs
rename to src/test/compile-fail/auxiliary/issue-30535.rs
diff --git a/src/test/auxiliary/issue_11680.rs b/src/test/compile-fail/auxiliary/issue_11680.rs
similarity index 100%
rename from src/test/auxiliary/issue_11680.rs
rename to src/test/compile-fail/auxiliary/issue_11680.rs
diff --git a/src/test/auxiliary/issue_12612_1.rs b/src/test/compile-fail/auxiliary/issue_12612_1.rs
similarity index 100%
rename from src/test/auxiliary/issue_12612_1.rs
rename to src/test/compile-fail/auxiliary/issue_12612_1.rs
diff --git a/src/test/auxiliary/issue_16725.rs b/src/test/compile-fail/auxiliary/issue_16725.rs
similarity index 100%
rename from src/test/auxiliary/issue_16725.rs
rename to src/test/compile-fail/auxiliary/issue_16725.rs
diff --git a/src/test/auxiliary/issue_17718_const_privacy.rs b/src/test/compile-fail/auxiliary/issue_17718_const_privacy.rs
similarity index 100%
rename from src/test/auxiliary/issue_17718_const_privacy.rs
rename to src/test/compile-fail/auxiliary/issue_17718_const_privacy.rs
diff --git a/src/test/auxiliary/issue_21202.rs b/src/test/compile-fail/auxiliary/issue_21202.rs
similarity index 100%
rename from src/test/auxiliary/issue_21202.rs
rename to src/test/compile-fail/auxiliary/issue_21202.rs
diff --git a/src/test/auxiliary/issue_30123_aux.rs b/src/test/compile-fail/auxiliary/issue_30123_aux.rs
similarity index 100%
rename from src/test/auxiliary/issue_30123_aux.rs
rename to src/test/compile-fail/auxiliary/issue_30123_aux.rs
diff --git a/src/test/auxiliary/issue_3907.rs b/src/test/compile-fail/auxiliary/issue_3907.rs
similarity index 100%
rename from src/test/auxiliary/issue_3907.rs
rename to src/test/compile-fail/auxiliary/issue_3907.rs
diff --git a/src/test/auxiliary/issue_5844_aux.rs b/src/test/compile-fail/auxiliary/issue_5844_aux.rs
similarity index 100%
rename from src/test/auxiliary/issue_5844_aux.rs
rename to src/test/compile-fail/auxiliary/issue_5844_aux.rs
diff --git a/src/test/auxiliary/lifetime_bound_will_change_warning_lib.rs b/src/test/compile-fail/auxiliary/lifetime_bound_will_change_warning_lib.rs
similarity index 100%
rename from src/test/auxiliary/lifetime_bound_will_change_warning_lib.rs
rename to src/test/compile-fail/auxiliary/lifetime_bound_will_change_warning_lib.rs
diff --git a/src/test/auxiliary/lint_output_format.rs b/src/test/compile-fail/auxiliary/lint_output_format.rs
similarity index 100%
rename from src/test/auxiliary/lint_output_format.rs
rename to src/test/compile-fail/auxiliary/lint_output_format.rs
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/compile-fail/auxiliary/lint_stability.rs
similarity index 100%
rename from src/test/auxiliary/lint_stability.rs
rename to src/test/compile-fail/auxiliary/lint_stability.rs
diff --git a/src/test/auxiliary/lint_stability_fields.rs b/src/test/compile-fail/auxiliary/lint_stability_fields.rs
similarity index 100%
rename from src/test/auxiliary/lint_stability_fields.rs
rename to src/test/compile-fail/auxiliary/lint_stability_fields.rs
diff --git a/src/test/auxiliary/lint_unused_extern_crate.rs b/src/test/compile-fail/auxiliary/lint_unused_extern_crate.rs
similarity index 100%
rename from src/test/auxiliary/lint_unused_extern_crate.rs
rename to src/test/compile-fail/auxiliary/lint_unused_extern_crate.rs
diff --git a/src/test/auxiliary/macro_crate_nonterminal.rs b/src/test/compile-fail/auxiliary/macro_crate_nonterminal.rs
similarity index 100%
rename from src/test/auxiliary/macro_crate_nonterminal.rs
rename to src/test/compile-fail/auxiliary/macro_crate_nonterminal.rs
diff --git a/src/test/auxiliary/macro_non_reexport_2.rs b/src/test/compile-fail/auxiliary/macro_non_reexport_2.rs
similarity index 100%
rename from src/test/auxiliary/macro_non_reexport_2.rs
rename to src/test/compile-fail/auxiliary/macro_non_reexport_2.rs
diff --git a/src/test/auxiliary/no_std_crate.rs b/src/test/compile-fail/auxiliary/macro_reexport_1.rs
similarity index 84%
rename from src/test/auxiliary/no_std_crate.rs
rename to src/test/compile-fail/auxiliary/macro_reexport_1.rs
index 7cfae6d121d..aaeccc6e898 100644
--- a/src/test/auxiliary/no_std_crate.rs
+++ b/src/test/compile-fail/auxiliary/macro_reexport_1.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![no_std]
-
-pub fn foo() {}
+#![crate_type = "dylib"]
+#[macro_export]
+macro_rules! reexported {
+    () => ( 3 )
+}
diff --git a/src/test/auxiliary/namespaced_enums.rs b/src/test/compile-fail/auxiliary/namespaced_enums.rs
similarity index 100%
rename from src/test/auxiliary/namespaced_enums.rs
rename to src/test/compile-fail/auxiliary/namespaced_enums.rs
diff --git a/src/test/auxiliary/needs_allocator.rs b/src/test/compile-fail/auxiliary/needs_allocator.rs
similarity index 100%
rename from src/test/auxiliary/needs_allocator.rs
rename to src/test/compile-fail/auxiliary/needs_allocator.rs
diff --git a/src/test/auxiliary/no_method_suggested_traits.rs b/src/test/compile-fail/auxiliary/no_method_suggested_traits.rs
similarity index 100%
rename from src/test/auxiliary/no_method_suggested_traits.rs
rename to src/test/compile-fail/auxiliary/no_method_suggested_traits.rs
diff --git a/src/test/auxiliary/noexporttypelib.rs b/src/test/compile-fail/auxiliary/noexporttypelib.rs
similarity index 100%
rename from src/test/auxiliary/noexporttypelib.rs
rename to src/test/compile-fail/auxiliary/noexporttypelib.rs
diff --git a/src/test/auxiliary/orphan_check_diagnostics.rs b/src/test/compile-fail/auxiliary/orphan_check_diagnostics.rs
similarity index 100%
rename from src/test/auxiliary/orphan_check_diagnostics.rs
rename to src/test/compile-fail/auxiliary/orphan_check_diagnostics.rs
diff --git a/src/test/auxiliary/privacy_tuple_struct.rs b/src/test/compile-fail/auxiliary/privacy_tuple_struct.rs
similarity index 100%
rename from src/test/auxiliary/privacy_tuple_struct.rs
rename to src/test/compile-fail/auxiliary/privacy_tuple_struct.rs
diff --git a/src/test/auxiliary/private_trait_xc.rs b/src/test/compile-fail/auxiliary/private_trait_xc.rs
similarity index 100%
rename from src/test/auxiliary/private_trait_xc.rs
rename to src/test/compile-fail/auxiliary/private_trait_xc.rs
diff --git a/src/test/auxiliary/pub_static_array.rs b/src/test/compile-fail/auxiliary/pub_static_array.rs
similarity index 100%
rename from src/test/auxiliary/pub_static_array.rs
rename to src/test/compile-fail/auxiliary/pub_static_array.rs
diff --git a/src/test/auxiliary/rbmtp_cross_crate_lib.rs b/src/test/compile-fail/auxiliary/rbmtp_cross_crate_lib.rs
similarity index 100%
rename from src/test/auxiliary/rbmtp_cross_crate_lib.rs
rename to src/test/compile-fail/auxiliary/rbmtp_cross_crate_lib.rs
diff --git a/src/test/auxiliary/stability_attribute_issue.rs b/src/test/compile-fail/auxiliary/stability_attribute_issue.rs
similarity index 100%
rename from src/test/auxiliary/stability_attribute_issue.rs
rename to src/test/compile-fail/auxiliary/stability_attribute_issue.rs
diff --git a/src/test/auxiliary/stability_cfg1.rs b/src/test/compile-fail/auxiliary/stability_cfg1.rs
similarity index 100%
rename from src/test/auxiliary/stability_cfg1.rs
rename to src/test/compile-fail/auxiliary/stability_cfg1.rs
diff --git a/src/test/auxiliary/stability_cfg2.rs b/src/test/compile-fail/auxiliary/stability_cfg2.rs
similarity index 100%
rename from src/test/auxiliary/stability_cfg2.rs
rename to src/test/compile-fail/auxiliary/stability_cfg2.rs
diff --git a/src/test/auxiliary/static_priv_by_default.rs b/src/test/compile-fail/auxiliary/static_priv_by_default.rs
similarity index 100%
rename from src/test/auxiliary/static_priv_by_default.rs
rename to src/test/compile-fail/auxiliary/static_priv_by_default.rs
diff --git a/src/test/auxiliary/struct_field_privacy.rs b/src/test/compile-fail/auxiliary/struct_field_privacy.rs
similarity index 100%
rename from src/test/auxiliary/struct_field_privacy.rs
rename to src/test/compile-fail/auxiliary/struct_field_privacy.rs
diff --git a/src/test/auxiliary/struct_variant_privacy.rs b/src/test/compile-fail/auxiliary/struct_variant_privacy.rs
similarity index 100%
rename from src/test/auxiliary/struct_variant_privacy.rs
rename to src/test/compile-fail/auxiliary/struct_variant_privacy.rs
diff --git a/src/test/auxiliary/svh-a-base.rs b/src/test/compile-fail/auxiliary/svh-a-base.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-base.rs
rename to src/test/compile-fail/auxiliary/svh-a-base.rs
diff --git a/src/test/auxiliary/svh-a-change-lit.rs b/src/test/compile-fail/auxiliary/svh-a-change-lit.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-change-lit.rs
rename to src/test/compile-fail/auxiliary/svh-a-change-lit.rs
diff --git a/src/test/auxiliary/svh-a-change-significant-cfg.rs b/src/test/compile-fail/auxiliary/svh-a-change-significant-cfg.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-change-significant-cfg.rs
rename to src/test/compile-fail/auxiliary/svh-a-change-significant-cfg.rs
diff --git a/src/test/auxiliary/svh-a-change-trait-bound.rs b/src/test/compile-fail/auxiliary/svh-a-change-trait-bound.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-change-trait-bound.rs
rename to src/test/compile-fail/auxiliary/svh-a-change-trait-bound.rs
diff --git a/src/test/auxiliary/svh-a-change-type-arg.rs b/src/test/compile-fail/auxiliary/svh-a-change-type-arg.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-change-type-arg.rs
rename to src/test/compile-fail/auxiliary/svh-a-change-type-arg.rs
diff --git a/src/test/auxiliary/svh-a-change-type-ret.rs b/src/test/compile-fail/auxiliary/svh-a-change-type-ret.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-change-type-ret.rs
rename to src/test/compile-fail/auxiliary/svh-a-change-type-ret.rs
diff --git a/src/test/auxiliary/svh-a-change-type-static.rs b/src/test/compile-fail/auxiliary/svh-a-change-type-static.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-change-type-static.rs
rename to src/test/compile-fail/auxiliary/svh-a-change-type-static.rs
diff --git a/src/test/auxiliary/svh-b.rs b/src/test/compile-fail/auxiliary/svh-b.rs
similarity index 100%
rename from src/test/auxiliary/svh-b.rs
rename to src/test/compile-fail/auxiliary/svh-b.rs
diff --git a/src/test/auxiliary/svh-uta-base.rs b/src/test/compile-fail/auxiliary/svh-uta-base.rs
similarity index 100%
rename from src/test/auxiliary/svh-uta-base.rs
rename to src/test/compile-fail/auxiliary/svh-uta-base.rs
diff --git a/src/test/auxiliary/svh-uta-change-use-trait.rs b/src/test/compile-fail/auxiliary/svh-uta-change-use-trait.rs
similarity index 100%
rename from src/test/auxiliary/svh-uta-change-use-trait.rs
rename to src/test/compile-fail/auxiliary/svh-uta-change-use-trait.rs
diff --git a/src/test/auxiliary/svh-utb.rs b/src/test/compile-fail/auxiliary/svh-utb.rs
similarity index 100%
rename from src/test/auxiliary/svh-utb.rs
rename to src/test/compile-fail/auxiliary/svh-utb.rs
diff --git a/src/test/auxiliary/tdticc_coherence_lib.rs b/src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs
similarity index 100%
rename from src/test/auxiliary/tdticc_coherence_lib.rs
rename to src/test/compile-fail/auxiliary/tdticc_coherence_lib.rs
diff --git a/src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs b/src/test/compile-fail/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
similarity index 100%
rename from src/test/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
rename to src/test/compile-fail/auxiliary/trait_bounds_on_structs_and_enums_xc.rs
diff --git a/src/test/auxiliary/trait_impl_conflict.rs b/src/test/compile-fail/auxiliary/trait_impl_conflict.rs
similarity index 100%
rename from src/test/auxiliary/trait_impl_conflict.rs
rename to src/test/compile-fail/auxiliary/trait_impl_conflict.rs
diff --git a/src/test/auxiliary/trait_safety_lib.rs b/src/test/compile-fail/auxiliary/trait_safety_lib.rs
similarity index 100%
rename from src/test/auxiliary/trait_safety_lib.rs
rename to src/test/compile-fail/auxiliary/trait_safety_lib.rs
diff --git a/src/test/auxiliary/trait_superkinds_in_metadata.rs b/src/test/compile-fail/auxiliary/trait_superkinds_in_metadata.rs
similarity index 100%
rename from src/test/auxiliary/trait_superkinds_in_metadata.rs
rename to src/test/compile-fail/auxiliary/trait_superkinds_in_metadata.rs
diff --git a/src/test/auxiliary/two_macros.rs b/src/test/compile-fail/auxiliary/two_macros.rs
similarity index 100%
rename from src/test/auxiliary/two_macros.rs
rename to src/test/compile-fail/auxiliary/two_macros.rs
diff --git a/src/test/auxiliary/unreachable_variant.rs b/src/test/compile-fail/auxiliary/unreachable_variant.rs
similarity index 100%
rename from src/test/auxiliary/unreachable_variant.rs
rename to src/test/compile-fail/auxiliary/unreachable_variant.rs
diff --git a/src/test/compile-fail/auxiliary/use_from_trait_xc.rs b/src/test/compile-fail/auxiliary/use_from_trait_xc.rs
new file mode 100644
index 00000000000..7024c9dad7c
--- /dev/null
+++ b/src/test/compile-fail/auxiliary/use_from_trait_xc.rs
@@ -0,0 +1,41 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_consts)]
+
+pub use self::sub::{Bar, Baz};
+
+pub trait Trait {
+    fn foo(&self);
+    type Assoc;
+    const CONST: u32;
+}
+
+struct Foo;
+
+impl Foo {
+    pub fn new() {}
+
+    pub const C: u32 = 0;
+}
+
+mod sub {
+    pub struct Bar;
+
+    impl Bar {
+        pub fn new() {}
+    }
+
+    pub enum Baz {}
+
+    impl Baz {
+        pub fn new() {}
+    }
+}
diff --git a/src/test/auxiliary/variant-namespacing.rs b/src/test/compile-fail/auxiliary/variant-namespacing.rs
similarity index 100%
rename from src/test/auxiliary/variant-namespacing.rs
rename to src/test/compile-fail/auxiliary/variant-namespacing.rs
diff --git a/src/test/auxiliary/weak-lang-items.rs b/src/test/compile-fail/auxiliary/weak-lang-items.rs
similarity index 100%
rename from src/test/auxiliary/weak-lang-items.rs
rename to src/test/compile-fail/auxiliary/weak-lang-items.rs
diff --git a/src/test/auxiliary/xc_private_method_lib.rs b/src/test/compile-fail/auxiliary/xc_private_method_lib.rs
similarity index 100%
rename from src/test/auxiliary/xc_private_method_lib.rs
rename to src/test/compile-fail/auxiliary/xc_private_method_lib.rs
diff --git a/src/test/auxiliary/xcrate_unit_struct.rs b/src/test/compile-fail/auxiliary/xcrate_unit_struct.rs
similarity index 100%
rename from src/test/auxiliary/xcrate_unit_struct.rs
rename to src/test/compile-fail/auxiliary/xcrate_unit_struct.rs
diff --git a/src/test/compile-fail/issue-21146.rs b/src/test/compile-fail/issue-21146.rs
index 4c6059c132a..02f128e1f56 100644
--- a/src/test/compile-fail/issue-21146.rs
+++ b/src/test/compile-fail/issue-21146.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 // error-pattern: expected item, found `parse_error`
-include!("../auxiliary/issue-21146-inc.rs");
+include!("auxiliary/issue-21146-inc.rs");
 fn main() {}
diff --git a/src/test/auxiliary/pub_restricted.rs b/src/test/compile-fail/privacy/restricted/auxiliary/pub_restricted.rs
similarity index 100%
rename from src/test/auxiliary/pub_restricted.rs
rename to src/test/compile-fail/privacy/restricted/auxiliary/pub_restricted.rs
diff --git a/src/test/auxiliary/cross_crate_debuginfo_type_uniquing.rs b/src/test/debuginfo/auxiliary/cross_crate_debuginfo_type_uniquing.rs
similarity index 100%
rename from src/test/auxiliary/cross_crate_debuginfo_type_uniquing.rs
rename to src/test/debuginfo/auxiliary/cross_crate_debuginfo_type_uniquing.rs
diff --git a/src/test/auxiliary/cross_crate_spans.rs b/src/test/debuginfo/auxiliary/cross_crate_spans.rs
similarity index 100%
rename from src/test/auxiliary/cross_crate_spans.rs
rename to src/test/debuginfo/auxiliary/cross_crate_spans.rs
diff --git a/src/test/auxiliary/issue13213aux.rs b/src/test/debuginfo/auxiliary/issue13213aux.rs
similarity index 100%
rename from src/test/auxiliary/issue13213aux.rs
rename to src/test/debuginfo/auxiliary/issue13213aux.rs
diff --git a/src/test/auxiliary/custom_derive_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs
similarity index 100%
rename from src/test/auxiliary/custom_derive_plugin.rs
rename to src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin.rs
diff --git a/src/test/auxiliary/custom_derive_plugin_attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs
similarity index 100%
rename from src/test/auxiliary/custom_derive_plugin_attr.rs
rename to src/test/run-pass-fulldeps/auxiliary/custom_derive_plugin_attr.rs
diff --git a/src/test/auxiliary/dummy_mir_pass.rs b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
similarity index 100%
rename from src/test/auxiliary/dummy_mir_pass.rs
rename to src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
diff --git a/src/test/auxiliary/issue-13560-1.rs b/src/test/run-pass-fulldeps/auxiliary/issue-13560-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-13560-1.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue-13560-1.rs
diff --git a/src/test/auxiliary/issue-13560-2.rs b/src/test/run-pass-fulldeps/auxiliary/issue-13560-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-13560-2.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue-13560-2.rs
diff --git a/src/test/auxiliary/issue-13560-3.rs b/src/test/run-pass-fulldeps/auxiliary/issue-13560-3.rs
similarity index 100%
rename from src/test/auxiliary/issue-13560-3.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue-13560-3.rs
diff --git a/src/test/auxiliary/issue-16822.rs b/src/test/run-pass-fulldeps/auxiliary/issue-16822.rs
similarity index 100%
rename from src/test/auxiliary/issue-16822.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue-16822.rs
diff --git a/src/test/auxiliary/issue-18502.rs b/src/test/run-pass-fulldeps/auxiliary/issue-18502.rs
similarity index 100%
rename from src/test/auxiliary/issue-18502.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue-18502.rs
diff --git a/src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs b/src/test/run-pass-fulldeps/auxiliary/issue_16723_multiple_items_syntax_ext.rs
similarity index 100%
rename from src/test/auxiliary/issue_16723_multiple_items_syntax_ext.rs
rename to src/test/run-pass-fulldeps/auxiliary/issue_16723_multiple_items_syntax_ext.rs
diff --git a/src/test/auxiliary/linkage-visibility.rs b/src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs
similarity index 100%
rename from src/test/auxiliary/linkage-visibility.rs
rename to src/test/run-pass-fulldeps/auxiliary/linkage-visibility.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
new file mode 100644
index 00000000000..a424517da12
--- /dev/null
+++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs
@@ -0,0 +1,47 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar, rustc_private)]
+#![feature(box_syntax)]
+
+#[macro_use] extern crate rustc;
+extern crate rustc_plugin;
+extern crate syntax;
+
+use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
+use rustc_plugin::Registry;
+use rustc::hir;
+use syntax::attr;
+
+declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");
+
+struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(CRATE_NOT_OKAY)
+    }
+}
+
+impl LateLintPass for Pass {
+    fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) {
+        if !attr::contains_name(&krate.attrs, "crate_okay") {
+            cx.span_lint(CRATE_NOT_OKAY, krate.span,
+                         "crate is not marked with #![crate_okay]");
+        }
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_late_lint_pass(box Pass as LateLintPassObject);
+}
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/run-pass-fulldeps/auxiliary/lint_group_plugin_test.rs
new file mode 100644
index 00000000000..1e9a77724a8
--- /dev/null
+++ b/src/test/run-pass-fulldeps/auxiliary/lint_group_plugin_test.rs
@@ -0,0 +1,51 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar)]
+#![feature(box_syntax, rustc_private)]
+
+// Load rustc as a plugin to get macros
+#[macro_use]
+extern crate rustc;
+extern crate rustc_plugin;
+
+use rustc::hir;
+use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
+use rustc_plugin::Registry;
+
+declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
+
+declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'");
+
+struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(TEST_LINT, PLEASE_LINT)
+    }
+}
+
+impl LateLintPass for Pass {
+    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
+        match &*it.name.as_str() {
+            "lintme" => cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"),
+            "pleaselintme" => cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"),
+            _ => {}
+        }
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_late_lint_pass(box Pass as LateLintPassObject);
+    reg.register_lint_group("lint_me", vec![TEST_LINT, PLEASE_LINT]);
+}
diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_plugin_test.rs b/src/test/run-pass-fulldeps/auxiliary/lint_plugin_test.rs
new file mode 100644
index 00000000000..8ea131da338
--- /dev/null
+++ b/src/test/run-pass-fulldeps/auxiliary/lint_plugin_test.rs
@@ -0,0 +1,48 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar)]
+#![feature(box_syntax, rustc_private)]
+
+extern crate syntax;
+
+// Load rustc as a plugin to get macros
+#[macro_use]
+extern crate rustc;
+extern crate rustc_plugin;
+
+use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
+                  EarlyLintPassObject, LintArray};
+use rustc_plugin::Registry;
+use syntax::ast;
+declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
+
+struct Pass;
+
+impl LintPass for Pass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(TEST_LINT)
+    }
+}
+
+impl EarlyLintPass for Pass {
+    fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
+        if it.ident.name.as_str() == "lintme" {
+            cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
+        }
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_early_lint_pass(box Pass as EarlyLintPassObject);
+}
diff --git a/src/test/auxiliary/llvm_pass_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs
similarity index 100%
rename from src/test/auxiliary/llvm_pass_plugin.rs
rename to src/test/run-pass-fulldeps/auxiliary/llvm_pass_plugin.rs
diff --git a/src/test/auxiliary/logging_right_crate.rs b/src/test/run-pass-fulldeps/auxiliary/logging_right_crate.rs
similarity index 100%
rename from src/test/auxiliary/logging_right_crate.rs
rename to src/test/run-pass-fulldeps/auxiliary/logging_right_crate.rs
diff --git a/src/test/auxiliary/lto-syntax-extension-lib.rs b/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-lib.rs
similarity index 100%
rename from src/test/auxiliary/lto-syntax-extension-lib.rs
rename to src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-lib.rs
diff --git a/src/test/auxiliary/lto-syntax-extension-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
similarity index 100%
rename from src/test/auxiliary/lto-syntax-extension-plugin.rs
rename to src/test/run-pass-fulldeps/auxiliary/lto-syntax-extension-plugin.rs
diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
new file mode 100644
index 00000000000..3516f566e8a
--- /dev/null
+++ b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
@@ -0,0 +1,141 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// force-host
+
+#![feature(plugin_registrar, quote, rustc_private)]
+
+extern crate syntax;
+extern crate rustc;
+extern crate rustc_plugin;
+
+use syntax::ast::{self, TokenTree, Item, MetaItem, ImplItem, TraitItem, ItemKind};
+use syntax::codemap::Span;
+use syntax::ext::base::*;
+use syntax::parse::{self, token};
+use syntax::ptr::P;
+use rustc_plugin::Registry;
+
+#[macro_export]
+macro_rules! exported_macro { () => (2) }
+macro_rules! unexported_macro { () => (3) }
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_macro("make_a_1", expand_make_a_1);
+    reg.register_macro("identity", expand_identity);
+    reg.register_syntax_extension(
+        token::intern("into_multi_foo"),
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        MultiModifier(Box::new(expand_into_foo_multi)));
+    reg.register_syntax_extension(
+        token::intern("duplicate"),
+        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+        MultiDecorator(Box::new(expand_duplicate)));
+}
+
+fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
+                   -> Box<MacResult+'static> {
+    if !tts.is_empty() {
+        cx.span_fatal(sp, "make_a_1 takes no arguments");
+    }
+    MacEager::expr(quote_expr!(cx, 1))
+}
+
+// See Issue #15750
+fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
+                   -> Box<MacResult+'static> {
+    // Parse an expression and emit it unchanged.
+    let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
+        cx.cfg(), tts.to_vec());
+    let expr = parser.parse_expr().unwrap();
+    MacEager::expr(quote_expr!(&mut *cx, $expr))
+}
+
+fn expand_into_foo_multi(cx: &mut ExtCtxt,
+                         sp: Span,
+                         attr: &MetaItem,
+                         it: Annotatable) -> Annotatable {
+    match it {
+        Annotatable::Item(it) => {
+            Annotatable::Item(P(Item {
+                attrs: it.attrs.clone(),
+                ..(*quote_item!(cx, enum Foo2 { Bar2, Baz2 }).unwrap()).clone()
+            }))
+        }
+        Annotatable::ImplItem(it) => {
+            quote_item!(cx, impl X { fn foo(&self) -> i32 { 42 } }).unwrap().and_then(|i| {
+                match i.node {
+                    ItemKind::Impl(_, _, _, _, _, mut items) => {
+                        Annotatable::ImplItem(P(items.pop().expect("impl method not found")))
+                    }
+                    _ => unreachable!("impl parsed to something other than impl")
+                }
+            })
+        }
+        Annotatable::TraitItem(it) => {
+            quote_item!(cx, trait X { fn foo(&self) -> i32 { 0 } }).unwrap().and_then(|i| {
+                match i.node {
+                    ItemKind::Trait(_, _, _, mut items) => {
+                        Annotatable::TraitItem(P(items.pop().expect("trait method not found")))
+                    }
+                    _ => unreachable!("trait parsed to something other than trait")
+                }
+            })
+        }
+    }
+}
+
+// Create a duplicate of the annotatable, based on the MetaItem
+fn expand_duplicate(cx: &mut ExtCtxt,
+                    sp: Span,
+                    mi: &MetaItem,
+                    it: &Annotatable,
+                    push: &mut FnMut(Annotatable))
+{
+    let copy_name = match mi.node {
+        ast::MetaItemKind::List(_, ref xs) => {
+            if let ast::MetaItemKind::Word(ref w) = xs[0].node {
+                token::str_to_ident(&w)
+            } else {
+                cx.span_err(mi.span, "Expected word");
+                return;
+            }
+        }
+        _ => {
+            cx.span_err(mi.span, "Expected list");
+            return;
+        }
+    };
+
+    // Duplicate the item but replace its ident by the MetaItem
+    match it.clone() {
+        Annotatable::Item(it) => {
+            let mut new_it = (*it).clone();
+            new_it.attrs.clear();
+            new_it.ident = copy_name;
+            push(Annotatable::Item(P(new_it)));
+        }
+        Annotatable::ImplItem(it) => {
+            let mut new_it = (*it).clone();
+            new_it.attrs.clear();
+            new_it.ident = copy_name;
+            push(Annotatable::ImplItem(P(new_it)));
+        }
+        Annotatable::TraitItem(tt) => {
+            let mut new_it = (*tt).clone();
+            new_it.attrs.clear();
+            new_it.ident = copy_name;
+            push(Annotatable::TraitItem(P(new_it)));
+        }
+    }
+}
+
+pub fn foo() {}
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs
similarity index 100%
rename from src/test/auxiliary/plugin_args.rs
rename to src/test/run-pass-fulldeps/auxiliary/plugin_args.rs
diff --git a/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs b/src/test/run-pass-fulldeps/auxiliary/plugin_crate_outlive_expansion_phase.rs
similarity index 100%
rename from src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs
rename to src/test/run-pass-fulldeps/auxiliary/plugin_crate_outlive_expansion_phase.rs
diff --git a/src/test/auxiliary/plugin_with_plugin_lib.rs b/src/test/run-pass-fulldeps/auxiliary/plugin_with_plugin_lib.rs
similarity index 100%
rename from src/test/auxiliary/plugin_with_plugin_lib.rs
rename to src/test/run-pass-fulldeps/auxiliary/plugin_with_plugin_lib.rs
diff --git a/src/test/auxiliary/procedural_mbe_matching.rs b/src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs
similarity index 100%
rename from src/test/auxiliary/procedural_mbe_matching.rs
rename to src/test/run-pass-fulldeps/auxiliary/procedural_mbe_matching.rs
diff --git a/src/test/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
similarity index 100%
rename from src/test/auxiliary/roman_numerals.rs
rename to src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs
diff --git a/src/test/auxiliary/syntax_extension_with_dll_deps_1.rs b/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs
similarity index 100%
rename from src/test/auxiliary/syntax_extension_with_dll_deps_1.rs
rename to src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_1.rs
diff --git a/src/test/auxiliary/syntax_extension_with_dll_deps_2.rs b/src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_2.rs
similarity index 100%
rename from src/test/auxiliary/syntax_extension_with_dll_deps_2.rs
rename to src/test/run-pass-fulldeps/auxiliary/syntax_extension_with_dll_deps_2.rs
diff --git a/src/test/auxiliary/allocator-dummy.rs b/src/test/run-pass/auxiliary/allocator-dummy.rs
similarity index 100%
rename from src/test/auxiliary/allocator-dummy.rs
rename to src/test/run-pass/auxiliary/allocator-dummy.rs
diff --git a/src/test/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs
similarity index 100%
rename from src/test/auxiliary/anon-extern-mod-cross-crate-1.rs
rename to src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/auxiliary/anon_trait_static_method_lib.rs b/src/test/run-pass/auxiliary/anon_trait_static_method_lib.rs
similarity index 100%
rename from src/test/auxiliary/anon_trait_static_method_lib.rs
rename to src/test/run-pass/auxiliary/anon_trait_static_method_lib.rs
diff --git a/src/test/auxiliary/associated-const-cc-lib.rs b/src/test/run-pass/auxiliary/associated-const-cc-lib.rs
similarity index 100%
rename from src/test/auxiliary/associated-const-cc-lib.rs
rename to src/test/run-pass/auxiliary/associated-const-cc-lib.rs
diff --git a/src/test/auxiliary/associated-types-cc-lib.rs b/src/test/run-pass/auxiliary/associated-types-cc-lib.rs
similarity index 100%
rename from src/test/auxiliary/associated-types-cc-lib.rs
rename to src/test/run-pass/auxiliary/associated-types-cc-lib.rs
diff --git a/src/test/auxiliary/augmented_assignments.rs b/src/test/run-pass/auxiliary/augmented_assignments.rs
similarity index 100%
rename from src/test/auxiliary/augmented_assignments.rs
rename to src/test/run-pass/auxiliary/augmented_assignments.rs
diff --git a/src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs b/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs
similarity index 100%
rename from src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs
rename to src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo.rs
diff --git a/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
similarity index 100%
rename from src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
rename to src/test/run-pass/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
diff --git a/src/test/auxiliary/cci_borrow_lib.rs b/src/test/run-pass/auxiliary/cci_borrow_lib.rs
similarity index 100%
rename from src/test/auxiliary/cci_borrow_lib.rs
rename to src/test/run-pass/auxiliary/cci_borrow_lib.rs
diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/run-pass/auxiliary/cci_capture_clause.rs
similarity index 100%
rename from src/test/auxiliary/cci_capture_clause.rs
rename to src/test/run-pass/auxiliary/cci_capture_clause.rs
diff --git a/src/test/run-pass/auxiliary/cci_class.rs b/src/test/run-pass/auxiliary/cci_class.rs
new file mode 100644
index 00000000000..08a13fd8bcc
--- /dev/null
+++ b/src/test/run-pass/auxiliary/cci_class.rs
@@ -0,0 +1,24 @@
+// 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.
+
+pub mod kitties {
+    pub struct cat {
+      meows : usize,
+
+      pub how_hungry : isize,
+    }
+
+    pub fn cat(in_x : usize, in_y : isize) -> cat  {
+        cat {
+            meows: in_x,
+            how_hungry: in_y
+        }
+    }
+}
diff --git a/src/test/auxiliary/cci_class_2.rs b/src/test/run-pass/auxiliary/cci_class_2.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_2.rs
rename to src/test/run-pass/auxiliary/cci_class_2.rs
diff --git a/src/test/auxiliary/cci_class_3.rs b/src/test/run-pass/auxiliary/cci_class_3.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_3.rs
rename to src/test/run-pass/auxiliary/cci_class_3.rs
diff --git a/src/test/auxiliary/cci_class_4.rs b/src/test/run-pass/auxiliary/cci_class_4.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_4.rs
rename to src/test/run-pass/auxiliary/cci_class_4.rs
diff --git a/src/test/auxiliary/cci_class_6.rs b/src/test/run-pass/auxiliary/cci_class_6.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_6.rs
rename to src/test/run-pass/auxiliary/cci_class_6.rs
diff --git a/src/test/auxiliary/cci_class_cast.rs b/src/test/run-pass/auxiliary/cci_class_cast.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_cast.rs
rename to src/test/run-pass/auxiliary/cci_class_cast.rs
diff --git a/src/test/auxiliary/cci_class_trait.rs b/src/test/run-pass/auxiliary/cci_class_trait.rs
similarity index 100%
rename from src/test/auxiliary/cci_class_trait.rs
rename to src/test/run-pass/auxiliary/cci_class_trait.rs
diff --git a/src/test/auxiliary/cci_const.rs b/src/test/run-pass/auxiliary/cci_const.rs
similarity index 100%
rename from src/test/auxiliary/cci_const.rs
rename to src/test/run-pass/auxiliary/cci_const.rs
diff --git a/src/test/auxiliary/cci_const_block.rs b/src/test/run-pass/auxiliary/cci_const_block.rs
similarity index 100%
rename from src/test/auxiliary/cci_const_block.rs
rename to src/test/run-pass/auxiliary/cci_const_block.rs
diff --git a/src/test/auxiliary/cci_impl_lib.rs b/src/test/run-pass/auxiliary/cci_impl_lib.rs
similarity index 100%
rename from src/test/auxiliary/cci_impl_lib.rs
rename to src/test/run-pass/auxiliary/cci_impl_lib.rs
diff --git a/src/test/auxiliary/cci_intrinsic.rs b/src/test/run-pass/auxiliary/cci_intrinsic.rs
similarity index 100%
rename from src/test/auxiliary/cci_intrinsic.rs
rename to src/test/run-pass/auxiliary/cci_intrinsic.rs
diff --git a/src/test/auxiliary/cci_iter_lib.rs b/src/test/run-pass/auxiliary/cci_iter_lib.rs
similarity index 100%
rename from src/test/auxiliary/cci_iter_lib.rs
rename to src/test/run-pass/auxiliary/cci_iter_lib.rs
diff --git a/src/test/auxiliary/cci_nested_lib.rs b/src/test/run-pass/auxiliary/cci_nested_lib.rs
similarity index 100%
rename from src/test/auxiliary/cci_nested_lib.rs
rename to src/test/run-pass/auxiliary/cci_nested_lib.rs
diff --git a/src/test/auxiliary/cci_no_inline_lib.rs b/src/test/run-pass/auxiliary/cci_no_inline_lib.rs
similarity index 100%
rename from src/test/auxiliary/cci_no_inline_lib.rs
rename to src/test/run-pass/auxiliary/cci_no_inline_lib.rs
diff --git a/src/test/auxiliary/cfg_inner_static.rs b/src/test/run-pass/auxiliary/cfg_inner_static.rs
similarity index 100%
rename from src/test/auxiliary/cfg_inner_static.rs
rename to src/test/run-pass/auxiliary/cfg_inner_static.rs
diff --git a/src/test/auxiliary/cgu_test.rs b/src/test/run-pass/auxiliary/cgu_test.rs
similarity index 100%
rename from src/test/auxiliary/cgu_test.rs
rename to src/test/run-pass/auxiliary/cgu_test.rs
diff --git a/src/test/auxiliary/cgu_test_a.rs b/src/test/run-pass/auxiliary/cgu_test_a.rs
similarity index 100%
rename from src/test/auxiliary/cgu_test_a.rs
rename to src/test/run-pass/auxiliary/cgu_test_a.rs
diff --git a/src/test/auxiliary/cgu_test_b.rs b/src/test/run-pass/auxiliary/cgu_test_b.rs
similarity index 100%
rename from src/test/auxiliary/cgu_test_b.rs
rename to src/test/run-pass/auxiliary/cgu_test_b.rs
diff --git a/src/test/auxiliary/check_static_recursion_foreign_helper.rs b/src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs
similarity index 100%
rename from src/test/auxiliary/check_static_recursion_foreign_helper.rs
rename to src/test/run-pass/auxiliary/check_static_recursion_foreign_helper.rs
diff --git a/src/test/run-pass/auxiliary/coherence_copy_like_lib.rs b/src/test/run-pass/auxiliary/coherence_copy_like_lib.rs
new file mode 100644
index 00000000000..d3d389c6a8b
--- /dev/null
+++ b/src/test/run-pass/auxiliary/coherence_copy_like_lib.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
+#![feature(fundamental)]
+
+pub trait MyCopy { }
+impl MyCopy for i32 { }
+
+pub struct MyStruct<T>(T);
+
+#[fundamental]
+pub struct MyFundamentalStruct<T>(T);
diff --git a/src/test/run-pass/auxiliary/coherence_lib.rs b/src/test/run-pass/auxiliary/coherence_lib.rs
new file mode 100644
index 00000000000..daa123849e4
--- /dev/null
+++ b/src/test/run-pass/auxiliary/coherence_lib.rs
@@ -0,0 +1,25 @@
+// 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.
+
+#![crate_type="lib"]
+
+pub trait Remote {
+    fn foo(&self) { }
+}
+
+pub trait Remote1<T> {
+    fn foo(&self, t: T) { }
+}
+
+pub trait Remote2<T, U> {
+    fn foo(&self, t: T, u: U) { }
+}
+
+pub struct Pair<T,U>(T,U);
diff --git a/src/test/run-pass/auxiliary/const_fn_lib.rs b/src/test/run-pass/auxiliary/const_fn_lib.rs
new file mode 100644
index 00000000000..b0d5a6b1272
--- /dev/null
+++ b/src/test/run-pass/auxiliary/const_fn_lib.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Crate that exports a const fn. Used for testing cross-crate.
+
+#![crate_type="rlib"]
+#![feature(const_fn)]
+
+pub const fn foo() -> usize { 22 } //~ ERROR const fn is unstable
diff --git a/src/test/auxiliary/crate-attributes-using-cfg_attr.rs b/src/test/run-pass/auxiliary/crate-attributes-using-cfg_attr.rs
similarity index 100%
rename from src/test/auxiliary/crate-attributes-using-cfg_attr.rs
rename to src/test/run-pass/auxiliary/crate-attributes-using-cfg_attr.rs
diff --git a/src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs b/src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs
similarity index 100%
rename from src/test/auxiliary/crate-method-reexport-grrrrrrr2.rs
rename to src/test/run-pass/auxiliary/crate-method-reexport-grrrrrrr2.rs
diff --git a/src/test/auxiliary/default_type_params_xc.rs b/src/test/run-pass/auxiliary/default_type_params_xc.rs
similarity index 100%
rename from src/test/auxiliary/default_type_params_xc.rs
rename to src/test/run-pass/auxiliary/default_type_params_xc.rs
diff --git a/src/test/auxiliary/derive-no-std.rs b/src/test/run-pass/auxiliary/derive-no-std.rs
similarity index 100%
rename from src/test/auxiliary/derive-no-std.rs
rename to src/test/run-pass/auxiliary/derive-no-std.rs
diff --git a/src/test/run-pass/auxiliary/empty-struct.rs b/src/test/run-pass/auxiliary/empty-struct.rs
new file mode 100644
index 00000000000..22f65c2b0d8
--- /dev/null
+++ b/src/test/run-pass/auxiliary/empty-struct.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct XEmpty1 {}
+pub struct XEmpty2;
+
+pub enum XE {
+    XEmpty3 {},
+    XEmpty4,
+}
diff --git a/src/test/auxiliary/explicit_self_xcrate.rs b/src/test/run-pass/auxiliary/explicit_self_xcrate.rs
similarity index 100%
rename from src/test/auxiliary/explicit_self_xcrate.rs
rename to src/test/run-pass/auxiliary/explicit_self_xcrate.rs
diff --git a/src/test/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/auxiliary/extern-crosscrate-source.rs
similarity index 100%
rename from src/test/auxiliary/extern-crosscrate-source.rs
rename to src/test/run-pass/auxiliary/extern-crosscrate-source.rs
diff --git a/src/test/auxiliary/extern-take-value.rs b/src/test/run-pass/auxiliary/extern-take-value.rs
similarity index 100%
rename from src/test/auxiliary/extern-take-value.rs
rename to src/test/run-pass/auxiliary/extern-take-value.rs
diff --git a/src/test/auxiliary/extern_calling_convention.rs b/src/test/run-pass/auxiliary/extern_calling_convention.rs
similarity index 100%
rename from src/test/auxiliary/extern_calling_convention.rs
rename to src/test/run-pass/auxiliary/extern_calling_convention.rs
diff --git a/src/test/auxiliary/extern_mod_ordering_lib.rs b/src/test/run-pass/auxiliary/extern_mod_ordering_lib.rs
similarity index 100%
rename from src/test/auxiliary/extern_mod_ordering_lib.rs
rename to src/test/run-pass/auxiliary/extern_mod_ordering_lib.rs
diff --git a/src/test/auxiliary/fat_drop.rs b/src/test/run-pass/auxiliary/fat_drop.rs
similarity index 100%
rename from src/test/auxiliary/fat_drop.rs
rename to src/test/run-pass/auxiliary/fat_drop.rs
diff --git a/src/test/auxiliary/fn-abi.rs b/src/test/run-pass/auxiliary/fn-abi.rs
similarity index 100%
rename from src/test/auxiliary/fn-abi.rs
rename to src/test/run-pass/auxiliary/fn-abi.rs
diff --git a/src/test/auxiliary/foreign_lib.rs b/src/test/run-pass/auxiliary/foreign_lib.rs
similarity index 100%
rename from src/test/auxiliary/foreign_lib.rs
rename to src/test/run-pass/auxiliary/foreign_lib.rs
diff --git a/src/test/run-pass/auxiliary/go_trait.rs b/src/test/run-pass/auxiliary/go_trait.rs
new file mode 100644
index 00000000000..044bb606b40
--- /dev/null
+++ b/src/test/run-pass/auxiliary/go_trait.rs
@@ -0,0 +1,53 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(specialization)]
+
+// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
+
+pub trait Go {
+    fn go(&self, arg: isize);
+}
+
+pub fn go<G:Go>(this: &G, arg: isize) {
+    this.go(arg)
+}
+
+pub trait GoMut {
+    fn go_mut(&mut self, arg: isize);
+}
+
+pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) {
+    this.go_mut(arg)
+}
+
+pub trait GoOnce {
+    fn go_once(self, arg: isize);
+}
+
+pub fn go_once<G:GoOnce>(this: G, arg: isize) {
+    this.go_once(arg)
+}
+
+impl<G> GoMut for G
+    where G : Go
+{
+    default fn go_mut(&mut self, arg: isize) {
+        go(&*self, arg)
+    }
+}
+
+impl<G> GoOnce for G
+    where G : GoMut
+{
+    default fn go_once(mut self, arg: isize) {
+        go_mut(&mut self, arg)
+    }
+}
diff --git a/src/test/auxiliary/i8.rs b/src/test/run-pass/auxiliary/i8.rs
similarity index 100%
rename from src/test/auxiliary/i8.rs
rename to src/test/run-pass/auxiliary/i8.rs
diff --git a/src/test/auxiliary/impl_privacy_xc_1.rs b/src/test/run-pass/auxiliary/impl_privacy_xc_1.rs
similarity index 100%
rename from src/test/auxiliary/impl_privacy_xc_1.rs
rename to src/test/run-pass/auxiliary/impl_privacy_xc_1.rs
diff --git a/src/test/auxiliary/impl_privacy_xc_2.rs b/src/test/run-pass/auxiliary/impl_privacy_xc_2.rs
similarity index 100%
rename from src/test/auxiliary/impl_privacy_xc_2.rs
rename to src/test/run-pass/auxiliary/impl_privacy_xc_2.rs
diff --git a/src/test/auxiliary/inline_dtor.rs b/src/test/run-pass/auxiliary/inline_dtor.rs
similarity index 100%
rename from src/test/auxiliary/inline_dtor.rs
rename to src/test/run-pass/auxiliary/inline_dtor.rs
diff --git a/src/test/auxiliary/inner_static.rs b/src/test/run-pass/auxiliary/inner_static.rs
similarity index 100%
rename from src/test/auxiliary/inner_static.rs
rename to src/test/run-pass/auxiliary/inner_static.rs
diff --git a/src/test/auxiliary/iss.rs b/src/test/run-pass/auxiliary/iss.rs
similarity index 100%
rename from src/test/auxiliary/iss.rs
rename to src/test/run-pass/auxiliary/iss.rs
diff --git a/src/test/auxiliary/issue-10028.rs b/src/test/run-pass/auxiliary/issue-10028.rs
similarity index 100%
rename from src/test/auxiliary/issue-10028.rs
rename to src/test/run-pass/auxiliary/issue-10028.rs
diff --git a/src/test/auxiliary/issue-11224.rs b/src/test/run-pass/auxiliary/issue-11224.rs
similarity index 100%
rename from src/test/auxiliary/issue-11224.rs
rename to src/test/run-pass/auxiliary/issue-11224.rs
diff --git a/src/test/auxiliary/issue-11225-1.rs b/src/test/run-pass/auxiliary/issue-11225-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-11225-1.rs
rename to src/test/run-pass/auxiliary/issue-11225-1.rs
diff --git a/src/test/auxiliary/issue-11225-2.rs b/src/test/run-pass/auxiliary/issue-11225-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-11225-2.rs
rename to src/test/run-pass/auxiliary/issue-11225-2.rs
diff --git a/src/test/auxiliary/issue-11225-3.rs b/src/test/run-pass/auxiliary/issue-11225-3.rs
similarity index 100%
rename from src/test/auxiliary/issue-11225-3.rs
rename to src/test/run-pass/auxiliary/issue-11225-3.rs
diff --git a/src/test/auxiliary/issue-11508.rs b/src/test/run-pass/auxiliary/issue-11508.rs
similarity index 100%
rename from src/test/auxiliary/issue-11508.rs
rename to src/test/run-pass/auxiliary/issue-11508.rs
diff --git a/src/test/auxiliary/issue-11529.rs b/src/test/run-pass/auxiliary/issue-11529.rs
similarity index 100%
rename from src/test/auxiliary/issue-11529.rs
rename to src/test/run-pass/auxiliary/issue-11529.rs
diff --git a/src/test/auxiliary/issue-12133-dylib.rs b/src/test/run-pass/auxiliary/issue-12133-dylib.rs
similarity index 100%
rename from src/test/auxiliary/issue-12133-dylib.rs
rename to src/test/run-pass/auxiliary/issue-12133-dylib.rs
diff --git a/src/test/auxiliary/issue-12133-dylib2.rs b/src/test/run-pass/auxiliary/issue-12133-dylib2.rs
similarity index 100%
rename from src/test/auxiliary/issue-12133-dylib2.rs
rename to src/test/run-pass/auxiliary/issue-12133-dylib2.rs
diff --git a/src/test/auxiliary/issue-12133-rlib.rs b/src/test/run-pass/auxiliary/issue-12133-rlib.rs
similarity index 100%
rename from src/test/auxiliary/issue-12133-rlib.rs
rename to src/test/run-pass/auxiliary/issue-12133-rlib.rs
diff --git a/src/test/auxiliary/issue-12660-aux.rs b/src/test/run-pass/auxiliary/issue-12660-aux.rs
similarity index 100%
rename from src/test/auxiliary/issue-12660-aux.rs
rename to src/test/run-pass/auxiliary/issue-12660-aux.rs
diff --git a/src/test/auxiliary/issue-13620-1.rs b/src/test/run-pass/auxiliary/issue-13620-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-13620-1.rs
rename to src/test/run-pass/auxiliary/issue-13620-1.rs
diff --git a/src/test/auxiliary/issue-13620-2.rs b/src/test/run-pass/auxiliary/issue-13620-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-13620-2.rs
rename to src/test/run-pass/auxiliary/issue-13620-2.rs
diff --git a/src/test/auxiliary/issue-13872-1.rs b/src/test/run-pass/auxiliary/issue-13872-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-13872-1.rs
rename to src/test/run-pass/auxiliary/issue-13872-1.rs
diff --git a/src/test/auxiliary/issue-13872-2.rs b/src/test/run-pass/auxiliary/issue-13872-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-13872-2.rs
rename to src/test/run-pass/auxiliary/issue-13872-2.rs
diff --git a/src/test/auxiliary/issue-13872-3.rs b/src/test/run-pass/auxiliary/issue-13872-3.rs
similarity index 100%
rename from src/test/auxiliary/issue-13872-3.rs
rename to src/test/run-pass/auxiliary/issue-13872-3.rs
diff --git a/src/test/auxiliary/issue-14344-1.rs b/src/test/run-pass/auxiliary/issue-14344-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-14344-1.rs
rename to src/test/run-pass/auxiliary/issue-14344-1.rs
diff --git a/src/test/auxiliary/issue-14344-2.rs b/src/test/run-pass/auxiliary/issue-14344-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-14344-2.rs
rename to src/test/run-pass/auxiliary/issue-14344-2.rs
diff --git a/src/test/auxiliary/issue-14421.rs b/src/test/run-pass/auxiliary/issue-14421.rs
similarity index 100%
rename from src/test/auxiliary/issue-14421.rs
rename to src/test/run-pass/auxiliary/issue-14421.rs
diff --git a/src/test/auxiliary/issue-14422.rs b/src/test/run-pass/auxiliary/issue-14422.rs
similarity index 100%
rename from src/test/auxiliary/issue-14422.rs
rename to src/test/run-pass/auxiliary/issue-14422.rs
diff --git a/src/test/auxiliary/issue-15562.rs b/src/test/run-pass/auxiliary/issue-15562.rs
similarity index 100%
rename from src/test/auxiliary/issue-15562.rs
rename to src/test/run-pass/auxiliary/issue-15562.rs
diff --git a/src/test/auxiliary/issue-16643.rs b/src/test/run-pass/auxiliary/issue-16643.rs
similarity index 100%
rename from src/test/auxiliary/issue-16643.rs
rename to src/test/run-pass/auxiliary/issue-16643.rs
diff --git a/src/test/auxiliary/issue-17662.rs b/src/test/run-pass/auxiliary/issue-17662.rs
similarity index 100%
rename from src/test/auxiliary/issue-17662.rs
rename to src/test/run-pass/auxiliary/issue-17662.rs
diff --git a/src/test/auxiliary/issue-17718-aux.rs b/src/test/run-pass/auxiliary/issue-17718-aux.rs
similarity index 100%
rename from src/test/auxiliary/issue-17718-aux.rs
rename to src/test/run-pass/auxiliary/issue-17718-aux.rs
diff --git a/src/test/auxiliary/issue-18501.rs b/src/test/run-pass/auxiliary/issue-18501.rs
similarity index 100%
rename from src/test/auxiliary/issue-18501.rs
rename to src/test/run-pass/auxiliary/issue-18501.rs
diff --git a/src/test/auxiliary/issue-18514.rs b/src/test/run-pass/auxiliary/issue-18514.rs
similarity index 100%
rename from src/test/auxiliary/issue-18514.rs
rename to src/test/run-pass/auxiliary/issue-18514.rs
diff --git a/src/test/auxiliary/issue-18711.rs b/src/test/run-pass/auxiliary/issue-18711.rs
similarity index 100%
rename from src/test/auxiliary/issue-18711.rs
rename to src/test/run-pass/auxiliary/issue-18711.rs
diff --git a/src/test/auxiliary/issue-18913-1.rs b/src/test/run-pass/auxiliary/issue-18913-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-18913-1.rs
rename to src/test/run-pass/auxiliary/issue-18913-1.rs
diff --git a/src/test/auxiliary/issue-18913-2.rs b/src/test/run-pass/auxiliary/issue-18913-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-18913-2.rs
rename to src/test/run-pass/auxiliary/issue-18913-2.rs
diff --git a/src/test/auxiliary/issue-19340-1.rs b/src/test/run-pass/auxiliary/issue-19340-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-19340-1.rs
rename to src/test/run-pass/auxiliary/issue-19340-1.rs
diff --git a/src/test/auxiliary/issue-2380.rs b/src/test/run-pass/auxiliary/issue-2380.rs
similarity index 100%
rename from src/test/auxiliary/issue-2380.rs
rename to src/test/run-pass/auxiliary/issue-2380.rs
diff --git a/src/test/auxiliary/issue-2414-a.rs b/src/test/run-pass/auxiliary/issue-2414-a.rs
similarity index 100%
rename from src/test/auxiliary/issue-2414-a.rs
rename to src/test/run-pass/auxiliary/issue-2414-a.rs
diff --git a/src/test/auxiliary/issue-2414-b.rs b/src/test/run-pass/auxiliary/issue-2414-b.rs
similarity index 100%
rename from src/test/auxiliary/issue-2414-b.rs
rename to src/test/run-pass/auxiliary/issue-2414-b.rs
diff --git a/src/test/auxiliary/issue-25185-1.rs b/src/test/run-pass/auxiliary/issue-25185-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-25185-1.rs
rename to src/test/run-pass/auxiliary/issue-25185-1.rs
diff --git a/src/test/auxiliary/issue-25185-2.rs b/src/test/run-pass/auxiliary/issue-25185-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-25185-2.rs
rename to src/test/run-pass/auxiliary/issue-25185-2.rs
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/run-pass/auxiliary/issue-2526.rs
similarity index 100%
rename from src/test/auxiliary/issue-2526.rs
rename to src/test/run-pass/auxiliary/issue-2526.rs
diff --git a/src/test/auxiliary/issue-25467.rs b/src/test/run-pass/auxiliary/issue-25467.rs
similarity index 100%
rename from src/test/auxiliary/issue-25467.rs
rename to src/test/run-pass/auxiliary/issue-25467.rs
diff --git a/src/test/auxiliary/issue-2631-a.rs b/src/test/run-pass/auxiliary/issue-2631-a.rs
similarity index 100%
rename from src/test/auxiliary/issue-2631-a.rs
rename to src/test/run-pass/auxiliary/issue-2631-a.rs
diff --git a/src/test/auxiliary/issue-29485.rs b/src/test/run-pass/auxiliary/issue-29485.rs
similarity index 100%
rename from src/test/auxiliary/issue-29485.rs
rename to src/test/run-pass/auxiliary/issue-29485.rs
diff --git a/src/test/auxiliary/issue-3012-1.rs b/src/test/run-pass/auxiliary/issue-3012-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-3012-1.rs
rename to src/test/run-pass/auxiliary/issue-3012-1.rs
diff --git a/src/test/auxiliary/issue-31702-1.rs b/src/test/run-pass/auxiliary/issue-31702-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-31702-1.rs
rename to src/test/run-pass/auxiliary/issue-31702-1.rs
diff --git a/src/test/auxiliary/issue-31702-2.rs b/src/test/run-pass/auxiliary/issue-31702-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-31702-2.rs
rename to src/test/run-pass/auxiliary/issue-31702-2.rs
diff --git a/src/test/auxiliary/issue-4208-cc.rs b/src/test/run-pass/auxiliary/issue-4208-cc.rs
similarity index 100%
rename from src/test/auxiliary/issue-4208-cc.rs
rename to src/test/run-pass/auxiliary/issue-4208-cc.rs
diff --git a/src/test/auxiliary/issue-4545.rs b/src/test/run-pass/auxiliary/issue-4545.rs
similarity index 100%
rename from src/test/auxiliary/issue-4545.rs
rename to src/test/run-pass/auxiliary/issue-4545.rs
diff --git a/src/test/auxiliary/issue-5518.rs b/src/test/run-pass/auxiliary/issue-5518.rs
similarity index 100%
rename from src/test/auxiliary/issue-5518.rs
rename to src/test/run-pass/auxiliary/issue-5518.rs
diff --git a/src/test/auxiliary/issue-5521.rs b/src/test/run-pass/auxiliary/issue-5521.rs
similarity index 100%
rename from src/test/auxiliary/issue-5521.rs
rename to src/test/run-pass/auxiliary/issue-5521.rs
diff --git a/src/test/auxiliary/issue-7178.rs b/src/test/run-pass/auxiliary/issue-7178.rs
similarity index 100%
rename from src/test/auxiliary/issue-7178.rs
rename to src/test/run-pass/auxiliary/issue-7178.rs
diff --git a/src/test/auxiliary/issue-7899.rs b/src/test/run-pass/auxiliary/issue-7899.rs
similarity index 100%
rename from src/test/auxiliary/issue-7899.rs
rename to src/test/run-pass/auxiliary/issue-7899.rs
diff --git a/src/test/auxiliary/issue-8044.rs b/src/test/run-pass/auxiliary/issue-8044.rs
similarity index 100%
rename from src/test/auxiliary/issue-8044.rs
rename to src/test/run-pass/auxiliary/issue-8044.rs
diff --git a/src/test/auxiliary/issue-8259.rs b/src/test/run-pass/auxiliary/issue-8259.rs
similarity index 100%
rename from src/test/auxiliary/issue-8259.rs
rename to src/test/run-pass/auxiliary/issue-8259.rs
diff --git a/src/test/auxiliary/issue-9906.rs b/src/test/run-pass/auxiliary/issue-9906.rs
similarity index 100%
rename from src/test/auxiliary/issue-9906.rs
rename to src/test/run-pass/auxiliary/issue-9906.rs
diff --git a/src/test/auxiliary/issue-9968.rs b/src/test/run-pass/auxiliary/issue-9968.rs
similarity index 100%
rename from src/test/auxiliary/issue-9968.rs
rename to src/test/run-pass/auxiliary/issue-9968.rs
diff --git a/src/test/auxiliary/issue13507.rs b/src/test/run-pass/auxiliary/issue13507.rs
similarity index 100%
rename from src/test/auxiliary/issue13507.rs
rename to src/test/run-pass/auxiliary/issue13507.rs
diff --git a/src/test/auxiliary/issue2170lib.rs b/src/test/run-pass/auxiliary/issue2170lib.rs
similarity index 100%
rename from src/test/auxiliary/issue2170lib.rs
rename to src/test/run-pass/auxiliary/issue2170lib.rs
diff --git a/src/test/auxiliary/issue_10031_aux.rs b/src/test/run-pass/auxiliary/issue_10031_aux.rs
similarity index 100%
rename from src/test/auxiliary/issue_10031_aux.rs
rename to src/test/run-pass/auxiliary/issue_10031_aux.rs
diff --git a/src/test/auxiliary/issue_3907_1.rs b/src/test/run-pass/auxiliary/issue_12612_1.rs
similarity index 93%
rename from src/test/auxiliary/issue_3907_1.rs
rename to src/test/run-pass/auxiliary/issue_12612_1.rs
index 25d2e3399cf..a0234c1185a 100644
--- a/src/test/auxiliary/issue_3907_1.rs
+++ b/src/test/run-pass/auxiliary/issue_12612_1.rs
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo {
-        fn bar();
+pub mod bar {
+    pub fn foo() {}
 }
diff --git a/src/test/auxiliary/issue_12612_2.rs b/src/test/run-pass/auxiliary/issue_12612_2.rs
similarity index 100%
rename from src/test/auxiliary/issue_12612_2.rs
rename to src/test/run-pass/auxiliary/issue_12612_2.rs
diff --git a/src/test/auxiliary/issue_19293.rs b/src/test/run-pass/auxiliary/issue_19293.rs
similarity index 100%
rename from src/test/auxiliary/issue_19293.rs
rename to src/test/run-pass/auxiliary/issue_19293.rs
diff --git a/src/test/auxiliary/issue_20389.rs b/src/test/run-pass/auxiliary/issue_20389.rs
similarity index 100%
rename from src/test/auxiliary/issue_20389.rs
rename to src/test/run-pass/auxiliary/issue_20389.rs
diff --git a/src/test/auxiliary/issue_2316_a.rs b/src/test/run-pass/auxiliary/issue_2316_a.rs
similarity index 100%
rename from src/test/auxiliary/issue_2316_a.rs
rename to src/test/run-pass/auxiliary/issue_2316_a.rs
diff --git a/src/test/auxiliary/issue_2316_b.rs b/src/test/run-pass/auxiliary/issue_2316_b.rs
similarity index 100%
rename from src/test/auxiliary/issue_2316_b.rs
rename to src/test/run-pass/auxiliary/issue_2316_b.rs
diff --git a/src/test/auxiliary/issue_2472_b.rs b/src/test/run-pass/auxiliary/issue_2472_b.rs
similarity index 100%
rename from src/test/auxiliary/issue_2472_b.rs
rename to src/test/run-pass/auxiliary/issue_2472_b.rs
diff --git a/src/test/auxiliary/issue_2723_a.rs b/src/test/run-pass/auxiliary/issue_2723_a.rs
similarity index 100%
rename from src/test/auxiliary/issue_2723_a.rs
rename to src/test/run-pass/auxiliary/issue_2723_a.rs
diff --git a/src/test/auxiliary/issue_3136_a.rc b/src/test/run-pass/auxiliary/issue_3136_a.rc
similarity index 100%
rename from src/test/auxiliary/issue_3136_a.rc
rename to src/test/run-pass/auxiliary/issue_3136_a.rc
diff --git a/src/test/auxiliary/issue_3136_a.rs b/src/test/run-pass/auxiliary/issue_3136_a.rs
similarity index 100%
rename from src/test/auxiliary/issue_3136_a.rs
rename to src/test/run-pass/auxiliary/issue_3136_a.rs
diff --git a/src/test/auxiliary/issue_3979_traits.rs b/src/test/run-pass/auxiliary/issue_3979_traits.rs
similarity index 100%
rename from src/test/auxiliary/issue_3979_traits.rs
rename to src/test/run-pass/auxiliary/issue_3979_traits.rs
diff --git a/src/test/auxiliary/issue_8401.rs b/src/test/run-pass/auxiliary/issue_8401.rs
similarity index 100%
rename from src/test/auxiliary/issue_8401.rs
rename to src/test/run-pass/auxiliary/issue_8401.rs
diff --git a/src/test/auxiliary/issue_9123.rs b/src/test/run-pass/auxiliary/issue_9123.rs
similarity index 100%
rename from src/test/auxiliary/issue_9123.rs
rename to src/test/run-pass/auxiliary/issue_9123.rs
diff --git a/src/test/auxiliary/issue_9155.rs b/src/test/run-pass/auxiliary/issue_9155.rs
similarity index 100%
rename from src/test/auxiliary/issue_9155.rs
rename to src/test/run-pass/auxiliary/issue_9155.rs
diff --git a/src/test/auxiliary/issue_9188.rs b/src/test/run-pass/auxiliary/issue_9188.rs
similarity index 100%
rename from src/test/auxiliary/issue_9188.rs
rename to src/test/run-pass/auxiliary/issue_9188.rs
diff --git a/src/test/auxiliary/kinds_in_metadata.rs b/src/test/run-pass/auxiliary/kinds_in_metadata.rs
similarity index 100%
rename from src/test/auxiliary/kinds_in_metadata.rs
rename to src/test/run-pass/auxiliary/kinds_in_metadata.rs
diff --git a/src/test/auxiliary/linkage1.rs b/src/test/run-pass/auxiliary/linkage1.rs
similarity index 100%
rename from src/test/auxiliary/linkage1.rs
rename to src/test/run-pass/auxiliary/linkage1.rs
diff --git a/src/test/auxiliary/macro-include-items-expr.rs b/src/test/run-pass/auxiliary/macro-include-items-expr.rs
similarity index 100%
rename from src/test/auxiliary/macro-include-items-expr.rs
rename to src/test/run-pass/auxiliary/macro-include-items-expr.rs
diff --git a/src/test/auxiliary/macro-include-items-item.rs b/src/test/run-pass/auxiliary/macro-include-items-item.rs
similarity index 100%
rename from src/test/auxiliary/macro-include-items-item.rs
rename to src/test/run-pass/auxiliary/macro-include-items-item.rs
diff --git a/src/test/auxiliary/macro_crate_def_only.rs b/src/test/run-pass/auxiliary/macro_crate_def_only.rs
similarity index 100%
rename from src/test/auxiliary/macro_crate_def_only.rs
rename to src/test/run-pass/auxiliary/macro_crate_def_only.rs
diff --git a/src/test/run-pass/auxiliary/macro_crate_nonterminal.rs b/src/test/run-pass/auxiliary/macro_crate_nonterminal.rs
new file mode 100644
index 00000000000..4f75e2b5d75
--- /dev/null
+++ b/src/test/run-pass/auxiliary/macro_crate_nonterminal.rs
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub fn increment(x: usize) -> usize {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! increment {
+    ($x:expr) => ($crate::increment($x))
+}
+
+pub fn check_local() {
+    assert_eq!(increment!(3), 4);
+}
diff --git a/src/test/auxiliary/macro_export_inner_module.rs b/src/test/run-pass/auxiliary/macro_export_inner_module.rs
similarity index 100%
rename from src/test/auxiliary/macro_export_inner_module.rs
rename to src/test/run-pass/auxiliary/macro_export_inner_module.rs
diff --git a/src/test/run-pass/auxiliary/macro_reexport_1.rs b/src/test/run-pass/auxiliary/macro_reexport_1.rs
new file mode 100644
index 00000000000..aaeccc6e898
--- /dev/null
+++ b/src/test/run-pass/auxiliary/macro_reexport_1.rs
@@ -0,0 +1,15 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "dylib"]
+#[macro_export]
+macro_rules! reexported {
+    () => ( 3 )
+}
diff --git a/src/test/auxiliary/macro_reexport_2.rs b/src/test/run-pass/auxiliary/macro_reexport_2.rs
similarity index 100%
rename from src/test/auxiliary/macro_reexport_2.rs
rename to src/test/run-pass/auxiliary/macro_reexport_2.rs
diff --git a/src/test/auxiliary/macro_reexport_2_no_use.rs b/src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs
similarity index 100%
rename from src/test/auxiliary/macro_reexport_2_no_use.rs
rename to src/test/run-pass/auxiliary/macro_reexport_2_no_use.rs
diff --git a/src/test/auxiliary/macro_with_super_1.rs b/src/test/run-pass/auxiliary/macro_with_super_1.rs
similarity index 100%
rename from src/test/auxiliary/macro_with_super_1.rs
rename to src/test/run-pass/auxiliary/macro_with_super_1.rs
diff --git a/src/test/auxiliary/method_self_arg1.rs b/src/test/run-pass/auxiliary/method_self_arg1.rs
similarity index 100%
rename from src/test/auxiliary/method_self_arg1.rs
rename to src/test/run-pass/auxiliary/method_self_arg1.rs
diff --git a/src/test/auxiliary/method_self_arg2.rs b/src/test/run-pass/auxiliary/method_self_arg2.rs
similarity index 100%
rename from src/test/auxiliary/method_self_arg2.rs
rename to src/test/run-pass/auxiliary/method_self_arg2.rs
diff --git a/src/test/auxiliary/mir_external_refs.rs b/src/test/run-pass/auxiliary/mir_external_refs.rs
similarity index 100%
rename from src/test/auxiliary/mir_external_refs.rs
rename to src/test/run-pass/auxiliary/mir_external_refs.rs
diff --git a/src/test/auxiliary/moves_based_on_type_lib.rs b/src/test/run-pass/auxiliary/moves_based_on_type_lib.rs
similarity index 100%
rename from src/test/auxiliary/moves_based_on_type_lib.rs
rename to src/test/run-pass/auxiliary/moves_based_on_type_lib.rs
diff --git a/src/test/auxiliary/msvc-data-only-lib.rs b/src/test/run-pass/auxiliary/msvc-data-only-lib.rs
similarity index 100%
rename from src/test/auxiliary/msvc-data-only-lib.rs
rename to src/test/run-pass/auxiliary/msvc-data-only-lib.rs
diff --git a/src/test/auxiliary/namespaced_enum_emulate_flat.rs b/src/test/run-pass/auxiliary/namespaced_enum_emulate_flat.rs
similarity index 100%
rename from src/test/auxiliary/namespaced_enum_emulate_flat.rs
rename to src/test/run-pass/auxiliary/namespaced_enum_emulate_flat.rs
diff --git a/src/test/run-pass/auxiliary/namespaced_enums.rs b/src/test/run-pass/auxiliary/namespaced_enums.rs
new file mode 100644
index 00000000000..3bf39b788db
--- /dev/null
+++ b/src/test/run-pass/auxiliary/namespaced_enums.rs
@@ -0,0 +1,20 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub enum Foo {
+    A,
+    B(isize),
+    C { a: isize },
+}
+
+impl Foo {
+    pub fn foo() {}
+    pub fn bar(&self) {}
+}
diff --git a/src/test/auxiliary/nested_item.rs b/src/test/run-pass/auxiliary/nested_item.rs
similarity index 100%
rename from src/test/auxiliary/nested_item.rs
rename to src/test/run-pass/auxiliary/nested_item.rs
diff --git a/src/test/auxiliary/newtype_struct_xc.rs b/src/test/run-pass/auxiliary/newtype_struct_xc.rs
similarity index 100%
rename from src/test/auxiliary/newtype_struct_xc.rs
rename to src/test/run-pass/auxiliary/newtype_struct_xc.rs
diff --git a/src/test/auxiliary/overloaded_autoderef_xc.rs b/src/test/run-pass/auxiliary/overloaded_autoderef_xc.rs
similarity index 100%
rename from src/test/auxiliary/overloaded_autoderef_xc.rs
rename to src/test/run-pass/auxiliary/overloaded_autoderef_xc.rs
diff --git a/src/test/auxiliary/packed.rs b/src/test/run-pass/auxiliary/packed.rs
similarity index 100%
rename from src/test/auxiliary/packed.rs
rename to src/test/run-pass/auxiliary/packed.rs
diff --git a/src/test/auxiliary/priv-impl-prim-ty.rs b/src/test/run-pass/auxiliary/priv-impl-prim-ty.rs
similarity index 100%
rename from src/test/auxiliary/priv-impl-prim-ty.rs
rename to src/test/run-pass/auxiliary/priv-impl-prim-ty.rs
diff --git a/src/test/auxiliary/privacy_reexport.rs b/src/test/run-pass/auxiliary/privacy_reexport.rs
similarity index 100%
rename from src/test/auxiliary/privacy_reexport.rs
rename to src/test/run-pass/auxiliary/privacy_reexport.rs
diff --git a/src/test/auxiliary/pub_use_mods_xcrate.rs b/src/test/run-pass/auxiliary/pub_use_mods_xcrate.rs
similarity index 100%
rename from src/test/auxiliary/pub_use_mods_xcrate.rs
rename to src/test/run-pass/auxiliary/pub_use_mods_xcrate.rs
diff --git a/src/test/auxiliary/pub_use_xcrate1.rs b/src/test/run-pass/auxiliary/pub_use_xcrate1.rs
similarity index 100%
rename from src/test/auxiliary/pub_use_xcrate1.rs
rename to src/test/run-pass/auxiliary/pub_use_xcrate1.rs
diff --git a/src/test/auxiliary/pub_use_xcrate2.rs b/src/test/run-pass/auxiliary/pub_use_xcrate2.rs
similarity index 100%
rename from src/test/auxiliary/pub_use_xcrate2.rs
rename to src/test/run-pass/auxiliary/pub_use_xcrate2.rs
diff --git a/src/test/auxiliary/reachable-unnameable-items.rs b/src/test/run-pass/auxiliary/reachable-unnameable-items.rs
similarity index 100%
rename from src/test/auxiliary/reachable-unnameable-items.rs
rename to src/test/run-pass/auxiliary/reachable-unnameable-items.rs
diff --git a/src/test/auxiliary/reexport-should-still-link.rs b/src/test/run-pass/auxiliary/reexport-should-still-link.rs
similarity index 100%
rename from src/test/auxiliary/reexport-should-still-link.rs
rename to src/test/run-pass/auxiliary/reexport-should-still-link.rs
diff --git a/src/test/auxiliary/reexported_static_methods.rs b/src/test/run-pass/auxiliary/reexported_static_methods.rs
similarity index 100%
rename from src/test/auxiliary/reexported_static_methods.rs
rename to src/test/run-pass/auxiliary/reexported_static_methods.rs
diff --git a/src/test/auxiliary/sepcomp-extern-lib.rs b/src/test/run-pass/auxiliary/sepcomp-extern-lib.rs
similarity index 100%
rename from src/test/auxiliary/sepcomp-extern-lib.rs
rename to src/test/run-pass/auxiliary/sepcomp-extern-lib.rs
diff --git a/src/test/auxiliary/sepcomp_cci_lib.rs b/src/test/run-pass/auxiliary/sepcomp_cci_lib.rs
similarity index 100%
rename from src/test/auxiliary/sepcomp_cci_lib.rs
rename to src/test/run-pass/auxiliary/sepcomp_cci_lib.rs
diff --git a/src/test/auxiliary/sepcomp_lib.rs b/src/test/run-pass/auxiliary/sepcomp_lib.rs
similarity index 100%
rename from src/test/auxiliary/sepcomp_lib.rs
rename to src/test/run-pass/auxiliary/sepcomp_lib.rs
diff --git a/src/test/auxiliary/static-function-pointer-aux.rs b/src/test/run-pass/auxiliary/static-function-pointer-aux.rs
similarity index 100%
rename from src/test/auxiliary/static-function-pointer-aux.rs
rename to src/test/run-pass/auxiliary/static-function-pointer-aux.rs
diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/run-pass/auxiliary/static-methods-crate.rs
similarity index 100%
rename from src/test/auxiliary/static-methods-crate.rs
rename to src/test/run-pass/auxiliary/static-methods-crate.rs
diff --git a/src/test/auxiliary/static_fn_inline_xc_aux.rs b/src/test/run-pass/auxiliary/static_fn_inline_xc_aux.rs
similarity index 100%
rename from src/test/auxiliary/static_fn_inline_xc_aux.rs
rename to src/test/run-pass/auxiliary/static_fn_inline_xc_aux.rs
diff --git a/src/test/auxiliary/static_fn_trait_xc_aux.rs b/src/test/run-pass/auxiliary/static_fn_trait_xc_aux.rs
similarity index 100%
rename from src/test/auxiliary/static_fn_trait_xc_aux.rs
rename to src/test/run-pass/auxiliary/static_fn_trait_xc_aux.rs
diff --git a/src/test/auxiliary/static_mut_xc.rs b/src/test/run-pass/auxiliary/static_mut_xc.rs
similarity index 100%
rename from src/test/auxiliary/static_mut_xc.rs
rename to src/test/run-pass/auxiliary/static_mut_xc.rs
diff --git a/src/test/auxiliary/struct_destructuring_cross_crate.rs b/src/test/run-pass/auxiliary/struct_destructuring_cross_crate.rs
similarity index 100%
rename from src/test/auxiliary/struct_destructuring_cross_crate.rs
rename to src/test/run-pass/auxiliary/struct_destructuring_cross_crate.rs
diff --git a/src/test/auxiliary/struct_variant_xc_aux.rs b/src/test/run-pass/auxiliary/struct_variant_xc_aux.rs
similarity index 100%
rename from src/test/auxiliary/struct_variant_xc_aux.rs
rename to src/test/run-pass/auxiliary/struct_variant_xc_aux.rs
diff --git a/src/test/auxiliary/svh-a-no-change.rs b/src/test/run-pass/auxiliary/svh-a-base.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-no-change.rs
rename to src/test/run-pass/auxiliary/svh-a-base.rs
diff --git a/src/test/auxiliary/svh-a-comment.rs b/src/test/run-pass/auxiliary/svh-a-comment.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-comment.rs
rename to src/test/run-pass/auxiliary/svh-a-comment.rs
diff --git a/src/test/auxiliary/svh-a-doc.rs b/src/test/run-pass/auxiliary/svh-a-doc.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-doc.rs
rename to src/test/run-pass/auxiliary/svh-a-doc.rs
diff --git a/src/test/auxiliary/svh-a-macro.rs b/src/test/run-pass/auxiliary/svh-a-macro.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-macro.rs
rename to src/test/run-pass/auxiliary/svh-a-macro.rs
diff --git a/src/test/run-pass/auxiliary/svh-a-no-change.rs b/src/test/run-pass/auxiliary/svh-a-no-change.rs
new file mode 100644
index 00000000000..31a97f695f0
--- /dev/null
+++ b/src/test/run-pass/auxiliary/svh-a-no-change.rs
@@ -0,0 +1,35 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! The `svh-a-*.rs` files are all deviations from the base file
+//! svh-a-base.rs with some difference (usually in `fn foo`) that
+//! should not affect the strict version hash (SVH) computation
+//! (#14132).
+
+#![crate_name = "a"]
+
+macro_rules! three {
+    () => { 3 }
+}
+
+pub trait U {}
+pub trait V {}
+impl U for () {}
+impl V for () {}
+
+static A_CONSTANT : isize = 2;
+
+pub fn foo<T:U>(_: isize) -> isize {
+    3
+}
+
+pub fn an_unused_name() -> isize {
+    4
+}
diff --git a/src/test/auxiliary/svh-a-redundant-cfg.rs b/src/test/run-pass/auxiliary/svh-a-redundant-cfg.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-redundant-cfg.rs
rename to src/test/run-pass/auxiliary/svh-a-redundant-cfg.rs
diff --git a/src/test/auxiliary/svh-a-whitespace.rs b/src/test/run-pass/auxiliary/svh-a-whitespace.rs
similarity index 100%
rename from src/test/auxiliary/svh-a-whitespace.rs
rename to src/test/run-pass/auxiliary/svh-a-whitespace.rs
diff --git a/src/test/run-pass/auxiliary/svh-b.rs b/src/test/run-pass/auxiliary/svh-b.rs
new file mode 100644
index 00000000000..b8946fdc995
--- /dev/null
+++ b/src/test/run-pass/auxiliary/svh-b.rs
@@ -0,0 +1,23 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This is a client of the `a` crate defined in "svn-a-base.rs".  The
+//! rpass and cfail tests (such as "run-pass/svh-add-comment.rs") use
+//! it by swapping in a different object code library crate built from
+//! some variant of "svn-a-base.rs", and then we are checking if the
+//! compiler properly ignores or accepts the change, based on whether
+//! the change could affect the downstream crate content or not
+//! (#14132).
+
+#![crate_name = "b"]
+
+extern crate a;
+
+pub fn foo() { assert_eq!(a::foo::<()>(0), 3); }
diff --git a/src/test/auxiliary/thread-local-extern-static.rs b/src/test/run-pass/auxiliary/thread-local-extern-static.rs
similarity index 100%
rename from src/test/auxiliary/thread-local-extern-static.rs
rename to src/test/run-pass/auxiliary/thread-local-extern-static.rs
diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/run-pass/auxiliary/trait_default_method_xc_aux.rs
similarity index 100%
rename from src/test/auxiliary/trait_default_method_xc_aux.rs
rename to src/test/run-pass/auxiliary/trait_default_method_xc_aux.rs
diff --git a/src/test/auxiliary/trait_default_method_xc_aux_2.rs b/src/test/run-pass/auxiliary/trait_default_method_xc_aux_2.rs
similarity index 100%
rename from src/test/auxiliary/trait_default_method_xc_aux_2.rs
rename to src/test/run-pass/auxiliary/trait_default_method_xc_aux_2.rs
diff --git a/src/test/auxiliary/trait_inheritance_auto_xc_2_aux.rs b/src/test/run-pass/auxiliary/trait_inheritance_auto_xc_2_aux.rs
similarity index 100%
rename from src/test/auxiliary/trait_inheritance_auto_xc_2_aux.rs
rename to src/test/run-pass/auxiliary/trait_inheritance_auto_xc_2_aux.rs
diff --git a/src/test/auxiliary/trait_inheritance_auto_xc_aux.rs b/src/test/run-pass/auxiliary/trait_inheritance_auto_xc_aux.rs
similarity index 100%
rename from src/test/auxiliary/trait_inheritance_auto_xc_aux.rs
rename to src/test/run-pass/auxiliary/trait_inheritance_auto_xc_aux.rs
diff --git a/src/test/auxiliary/trait_inheritance_cross_trait_call_xc_aux.rs b/src/test/run-pass/auxiliary/trait_inheritance_cross_trait_call_xc_aux.rs
similarity index 100%
rename from src/test/auxiliary/trait_inheritance_cross_trait_call_xc_aux.rs
rename to src/test/run-pass/auxiliary/trait_inheritance_cross_trait_call_xc_aux.rs
diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/run-pass/auxiliary/trait_inheritance_overloading_xc.rs
similarity index 100%
rename from src/test/auxiliary/trait_inheritance_overloading_xc.rs
rename to src/test/run-pass/auxiliary/trait_inheritance_overloading_xc.rs
diff --git a/src/test/run-pass/auxiliary/trait_safety_lib.rs b/src/test/run-pass/auxiliary/trait_safety_lib.rs
new file mode 100644
index 00000000000..585a756fd07
--- /dev/null
+++ b/src/test/run-pass/auxiliary/trait_safety_lib.rs
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Simple smoke test that unsafe traits can be compiled etc.
+
+pub unsafe trait Foo {
+    fn foo(&self) -> isize;
+}
+
+unsafe impl Foo for isize {
+    fn foo(&self) -> isize { *self }
+}
diff --git a/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs b/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs
new file mode 100644
index 00000000000..0fa2d3459f4
--- /dev/null
+++ b/src/test/run-pass/auxiliary/trait_superkinds_in_metadata.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// Test library crate for cross-crate usages of traits inheriting
+// from the builtin kinds. Mostly tests metadata correctness.
+
+#![crate_type="lib"]
+
+pub trait RequiresShare : Sync { }
+pub trait RequiresRequiresShareAndSend : RequiresShare + Send { }
+pub trait RequiresCopy : Copy { }
diff --git a/src/test/auxiliary/traitimpl.rs b/src/test/run-pass/auxiliary/traitimpl.rs
similarity index 100%
rename from src/test/auxiliary/traitimpl.rs
rename to src/test/run-pass/auxiliary/traitimpl.rs
diff --git a/src/test/run-pass/auxiliary/two_macros.rs b/src/test/run-pass/auxiliary/two_macros.rs
new file mode 100644
index 00000000000..060960f0dbc
--- /dev/null
+++ b/src/test/run-pass/auxiliary/two_macros.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_export]
+macro_rules! macro_one { () => ("one") }
+
+#[macro_export]
+macro_rules! macro_two { () => ("two") }
diff --git a/src/test/auxiliary/typeid-intrinsic-aux1.rs b/src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
similarity index 100%
rename from src/test/auxiliary/typeid-intrinsic-aux1.rs
rename to src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
diff --git a/src/test/auxiliary/typeid-intrinsic-aux2.rs b/src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
similarity index 100%
rename from src/test/auxiliary/typeid-intrinsic-aux2.rs
rename to src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
diff --git a/src/test/auxiliary/unboxed-closures-cross-crate.rs b/src/test/run-pass/auxiliary/unboxed-closures-cross-crate.rs
similarity index 100%
rename from src/test/auxiliary/unboxed-closures-cross-crate.rs
rename to src/test/run-pass/auxiliary/unboxed-closures-cross-crate.rs
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/run-pass/auxiliary/weak-lang-items.rs
similarity index 57%
rename from src/test/auxiliary/lang-item-public.rs
rename to src/test/run-pass/auxiliary/weak-lang-items.rs
index 41ceb924ab3..6434e62b6f7 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/run-pass/auxiliary/weak-lang-items.rs
@@ -8,21 +8,25 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(libc)]
+// no-prefer-dynamic
+
+// This aux-file will require the eh_personality function to be codegen'd, but
+// it hasn't been defined just yet. Make sure we don't explode.
+
 #![no_std]
-#![feature(lang_items)]
+#![crate_type = "rlib"]
 
-extern crate core;
-extern crate libc;
+struct A;
 
-#[lang = "eh_personality"]
-extern fn eh_personality() {}
-
-#[lang = "eh_unwind_resume"]
-extern fn eh_unwind_resume() {}
-
-#[lang = "panic_fmt"]
-extern fn rust_begin_unwind(msg: core::fmt::Arguments, file: &'static str,
-                            line: u32) -> ! {
-    loop {}
+impl core::ops::Drop for A {
+    fn drop(&mut self) {}
+}
+
+pub fn foo() {
+    let _a = A;
+    panic!("wut");
+}
+
+mod std {
+    pub use core::{option, fmt};
 }
diff --git a/src/test/auxiliary/where_clauses_xc.rs b/src/test/run-pass/auxiliary/where_clauses_xc.rs
similarity index 100%
rename from src/test/auxiliary/where_clauses_xc.rs
rename to src/test/run-pass/auxiliary/where_clauses_xc.rs
diff --git a/src/test/auxiliary/xcrate-trait-lifetime-param.rs b/src/test/run-pass/auxiliary/xcrate-trait-lifetime-param.rs
similarity index 100%
rename from src/test/auxiliary/xcrate-trait-lifetime-param.rs
rename to src/test/run-pass/auxiliary/xcrate-trait-lifetime-param.rs
diff --git a/src/test/auxiliary/xcrate_address_insignificant.rs b/src/test/run-pass/auxiliary/xcrate_address_insignificant.rs
similarity index 100%
rename from src/test/auxiliary/xcrate_address_insignificant.rs
rename to src/test/run-pass/auxiliary/xcrate_address_insignificant.rs
diff --git a/src/test/auxiliary/xcrate_associated_type_defaults.rs b/src/test/run-pass/auxiliary/xcrate_associated_type_defaults.rs
similarity index 100%
rename from src/test/auxiliary/xcrate_associated_type_defaults.rs
rename to src/test/run-pass/auxiliary/xcrate_associated_type_defaults.rs
diff --git a/src/test/auxiliary/xcrate_static_addresses.rs b/src/test/run-pass/auxiliary/xcrate_static_addresses.rs
similarity index 100%
rename from src/test/auxiliary/xcrate_static_addresses.rs
rename to src/test/run-pass/auxiliary/xcrate_static_addresses.rs
diff --git a/src/test/auxiliary/xcrate_struct_aliases.rs b/src/test/run-pass/auxiliary/xcrate_struct_aliases.rs
similarity index 100%
rename from src/test/auxiliary/xcrate_struct_aliases.rs
rename to src/test/run-pass/auxiliary/xcrate_struct_aliases.rs
diff --git a/src/test/run-pass/auxiliary/xcrate_unit_struct.rs b/src/test/run-pass/auxiliary/xcrate_unit_struct.rs
new file mode 100644
index 00000000000..7a69be2b06c
--- /dev/null
+++ b/src/test/run-pass/auxiliary/xcrate_unit_struct.rs
@@ -0,0 +1,38 @@
+// 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"]
+
+// used by the rpass test
+
+#[derive(Copy, Clone)]
+pub struct Struct;
+
+#[derive(Copy, Clone)]
+pub enum Unit {
+    UnitVariant,
+    Argument(Struct)
+}
+
+#[derive(Copy, Clone)]
+pub struct TupleStruct(pub usize, pub &'static str);
+
+// used by the cfail test
+
+#[derive(Copy, Clone)]
+pub struct StructWithFields {
+    foo: isize,
+}
+
+#[derive(Copy, Clone)]
+pub enum EnumWithVariants {
+    EnumVariant,
+    EnumVariantArg(isize)
+}
diff --git a/src/test/auxiliary/crate_with_invalid_spans.rs b/src/test/run-pass/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs
similarity index 100%
rename from src/test/auxiliary/crate_with_invalid_spans.rs
rename to src/test/run-pass/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans.rs
diff --git a/src/test/auxiliary/crate_with_invalid_spans_macros.rs b/src/test/run-pass/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs
similarity index 100%
rename from src/test/auxiliary/crate_with_invalid_spans_macros.rs
rename to src/test/run-pass/import-crate-with-invalid-spans/auxiliary/crate_with_invalid_spans_macros.rs
diff --git a/src/test/run-pass/import-crate-with-invalid-spans.rs b/src/test/run-pass/import-crate-with-invalid-spans/main.rs
similarity index 100%
rename from src/test/run-pass/import-crate-with-invalid-spans.rs
rename to src/test/run-pass/import-crate-with-invalid-spans/main.rs
diff --git a/src/test/auxiliary/issue24687_lib.rs b/src/test/run-pass/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs
similarity index 100%
rename from src/test/auxiliary/issue24687_lib.rs
rename to src/test/run-pass/issue24687-embed-debuginfo/auxiliary/issue24687_lib.rs
diff --git a/src/test/auxiliary/issue24687_mbcs_in_comments.rs b/src/test/run-pass/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs
similarity index 100%
rename from src/test/auxiliary/issue24687_mbcs_in_comments.rs
rename to src/test/run-pass/issue24687-embed-debuginfo/auxiliary/issue24687_mbcs_in_comments.rs
diff --git a/src/test/run-pass/issue24687-embed-debuginfo.rs b/src/test/run-pass/issue24687-embed-debuginfo/main.rs
similarity index 100%
rename from src/test/run-pass/issue24687-embed-debuginfo.rs
rename to src/test/run-pass/issue24687-embed-debuginfo/main.rs
diff --git a/src/test/run-pass/macro-include-items.rs b/src/test/run-pass/macro-include-items.rs
index 9e2f431c3ec..1e31c85afad 100644
--- a/src/test/run-pass/macro-include-items.rs
+++ b/src/test/run-pass/macro-include-items.rs
@@ -12,9 +12,9 @@
 
 fn bar() {}
 
-include!(concat!("", "", "../auxiliary/", "macro-include-items-item.rs"));
+include!(concat!("", "", "auxiliary/", "macro-include-items-item.rs"));
 
 fn main() {
     foo();
-    assert_eq!(include!(concat!("", "../auxiliary/", "macro-include-items-expr.rs")), 1_usize);
+    assert_eq!(include!(concat!("", "auxiliary/", "macro-include-items-expr.rs")), 1_usize);
 }
diff --git a/src/test/run-pass/specialization/auxiliary/go_trait.rs b/src/test/run-pass/specialization/auxiliary/go_trait.rs
new file mode 100644
index 00000000000..044bb606b40
--- /dev/null
+++ b/src/test/run-pass/specialization/auxiliary/go_trait.rs
@@ -0,0 +1,53 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(specialization)]
+
+// Common code used for tests that model the Fn/FnMut/FnOnce hierarchy.
+
+pub trait Go {
+    fn go(&self, arg: isize);
+}
+
+pub fn go<G:Go>(this: &G, arg: isize) {
+    this.go(arg)
+}
+
+pub trait GoMut {
+    fn go_mut(&mut self, arg: isize);
+}
+
+pub fn go_mut<G:GoMut>(this: &mut G, arg: isize) {
+    this.go_mut(arg)
+}
+
+pub trait GoOnce {
+    fn go_once(self, arg: isize);
+}
+
+pub fn go_once<G:GoOnce>(this: G, arg: isize) {
+    this.go_once(arg)
+}
+
+impl<G> GoMut for G
+    where G : Go
+{
+    default fn go_mut(&mut self, arg: isize) {
+        go(&*self, arg)
+    }
+}
+
+impl<G> GoOnce for G
+    where G : GoMut
+{
+    default fn go_once(mut self, arg: isize) {
+        go_mut(&mut self, arg)
+    }
+}
diff --git a/src/test/auxiliary/specialization_cross_crate.rs b/src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs
similarity index 100%
rename from src/test/auxiliary/specialization_cross_crate.rs
rename to src/test/run-pass/specialization/auxiliary/specialization_cross_crate.rs
diff --git a/src/test/auxiliary/specialization_cross_crate_defaults.rs b/src/test/run-pass/specialization/auxiliary/specialization_cross_crate_defaults.rs
similarity index 100%
rename from src/test/auxiliary/specialization_cross_crate_defaults.rs
rename to src/test/run-pass/specialization/auxiliary/specialization_cross_crate_defaults.rs
diff --git a/src/test/auxiliary/empty.rs b/src/test/rustdoc/auxiliary/empty.rs
similarity index 100%
rename from src/test/auxiliary/empty.rs
rename to src/test/rustdoc/auxiliary/empty.rs
diff --git a/src/test/auxiliary/inline-default-methods.rs b/src/test/rustdoc/auxiliary/inline-default-methods.rs
similarity index 100%
rename from src/test/auxiliary/inline-default-methods.rs
rename to src/test/rustdoc/auxiliary/inline-default-methods.rs
diff --git a/src/test/auxiliary/issue-13698.rs b/src/test/rustdoc/auxiliary/issue-13698.rs
similarity index 100%
rename from src/test/auxiliary/issue-13698.rs
rename to src/test/rustdoc/auxiliary/issue-13698.rs
diff --git a/src/test/auxiliary/issue-15318.rs b/src/test/rustdoc/auxiliary/issue-15318.rs
similarity index 100%
rename from src/test/auxiliary/issue-15318.rs
rename to src/test/rustdoc/auxiliary/issue-15318.rs
diff --git a/src/test/auxiliary/issue-17476.rs b/src/test/rustdoc/auxiliary/issue-17476.rs
similarity index 100%
rename from src/test/auxiliary/issue-17476.rs
rename to src/test/rustdoc/auxiliary/issue-17476.rs
diff --git a/src/test/auxiliary/issue-19190-3.rs b/src/test/rustdoc/auxiliary/issue-19190-3.rs
similarity index 100%
rename from src/test/auxiliary/issue-19190-3.rs
rename to src/test/rustdoc/auxiliary/issue-19190-3.rs
diff --git a/src/test/auxiliary/issue-20646.rs b/src/test/rustdoc/auxiliary/issue-20646.rs
similarity index 100%
rename from src/test/auxiliary/issue-20646.rs
rename to src/test/rustdoc/auxiliary/issue-20646.rs
diff --git a/src/test/auxiliary/issue-20727.rs b/src/test/rustdoc/auxiliary/issue-20727.rs
similarity index 100%
rename from src/test/auxiliary/issue-20727.rs
rename to src/test/rustdoc/auxiliary/issue-20727.rs
diff --git a/src/test/auxiliary/issue-21092.rs b/src/test/rustdoc/auxiliary/issue-21092.rs
similarity index 100%
rename from src/test/auxiliary/issue-21092.rs
rename to src/test/rustdoc/auxiliary/issue-21092.rs
diff --git a/src/test/auxiliary/issue-21801.rs b/src/test/rustdoc/auxiliary/issue-21801.rs
similarity index 100%
rename from src/test/auxiliary/issue-21801.rs
rename to src/test/rustdoc/auxiliary/issue-21801.rs
diff --git a/src/test/auxiliary/issue-22025.rs b/src/test/rustdoc/auxiliary/issue-22025.rs
similarity index 100%
rename from src/test/auxiliary/issue-22025.rs
rename to src/test/rustdoc/auxiliary/issue-22025.rs
diff --git a/src/test/auxiliary/issue-23207-1.rs b/src/test/rustdoc/auxiliary/issue-23207-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-23207-1.rs
rename to src/test/rustdoc/auxiliary/issue-23207-1.rs
diff --git a/src/test/auxiliary/issue-23207-2.rs b/src/test/rustdoc/auxiliary/issue-23207-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-23207-2.rs
rename to src/test/rustdoc/auxiliary/issue-23207-2.rs
diff --git a/src/test/auxiliary/issue-26606-macro.rs b/src/test/rustdoc/auxiliary/issue-26606-macro.rs
similarity index 100%
rename from src/test/auxiliary/issue-26606-macro.rs
rename to src/test/rustdoc/auxiliary/issue-26606-macro.rs
diff --git a/src/test/auxiliary/issue-27362.rs b/src/test/rustdoc/auxiliary/issue-27362.rs
similarity index 100%
rename from src/test/auxiliary/issue-27362.rs
rename to src/test/rustdoc/auxiliary/issue-27362.rs
diff --git a/src/test/auxiliary/issue-28927-1.rs b/src/test/rustdoc/auxiliary/issue-28927-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-28927-1.rs
rename to src/test/rustdoc/auxiliary/issue-28927-1.rs
diff --git a/src/test/auxiliary/issue-28927-2.rs b/src/test/rustdoc/auxiliary/issue-28927-2.rs
similarity index 100%
rename from src/test/auxiliary/issue-28927-2.rs
rename to src/test/rustdoc/auxiliary/issue-28927-2.rs
diff --git a/src/test/auxiliary/issue-29584.rs b/src/test/rustdoc/auxiliary/issue-29584.rs
similarity index 100%
rename from src/test/auxiliary/issue-29584.rs
rename to src/test/rustdoc/auxiliary/issue-29584.rs
diff --git a/src/test/auxiliary/issue-30109-1.rs b/src/test/rustdoc/auxiliary/issue-30109-1.rs
similarity index 100%
rename from src/test/auxiliary/issue-30109-1.rs
rename to src/test/rustdoc/auxiliary/issue-30109-1.rs
diff --git a/src/test/auxiliary/reexp_stripped.rs b/src/test/rustdoc/auxiliary/reexp_stripped.rs
similarity index 100%
rename from src/test/auxiliary/reexp_stripped.rs
rename to src/test/rustdoc/auxiliary/reexp_stripped.rs
diff --git a/src/test/auxiliary/rustdoc-default-impl.rs b/src/test/rustdoc/auxiliary/rustdoc-default-impl.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-default-impl.rs
rename to src/test/rustdoc/auxiliary/rustdoc-default-impl.rs
diff --git a/src/test/auxiliary/rustdoc-extern-default-method.rs b/src/test/rustdoc/auxiliary/rustdoc-extern-default-method.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-extern-default-method.rs
rename to src/test/rustdoc/auxiliary/rustdoc-extern-default-method.rs
diff --git a/src/test/auxiliary/rustdoc-extern-method.rs b/src/test/rustdoc/auxiliary/rustdoc-extern-method.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-extern-method.rs
rename to src/test/rustdoc/auxiliary/rustdoc-extern-method.rs
diff --git a/src/test/auxiliary/rustdoc-ffi.rs b/src/test/rustdoc/auxiliary/rustdoc-ffi.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-ffi.rs
rename to src/test/rustdoc/auxiliary/rustdoc-ffi.rs
diff --git a/src/test/auxiliary/rustdoc-impl-parts-crosscrate.rs b/src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-impl-parts-crosscrate.rs
rename to src/test/rustdoc/auxiliary/rustdoc-impl-parts-crosscrate.rs
diff --git a/src/test/auxiliary/variant-struct.rs b/src/test/rustdoc/auxiliary/variant-struct.rs
similarity index 100%
rename from src/test/auxiliary/variant-struct.rs
rename to src/test/rustdoc/auxiliary/variant-struct.rs
diff --git a/src/test/auxiliary/issue-33113.rs b/src/test/rustdoc/inline_cross/auxiliary/issue-33113.rs
similarity index 100%
rename from src/test/auxiliary/issue-33113.rs
rename to src/test/rustdoc/inline_cross/auxiliary/issue-33113.rs
diff --git a/src/test/auxiliary/rustdoc-hidden-sig.rs b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-hidden-sig.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-hidden-sig.rs
rename to src/test/rustdoc/inline_cross/auxiliary/rustdoc-hidden-sig.rs
diff --git a/src/test/auxiliary/rustdoc-hidden.rs b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-hidden.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-hidden.rs
rename to src/test/rustdoc/inline_cross/auxiliary/rustdoc-hidden.rs
diff --git a/src/test/auxiliary/rustdoc-nonreachable-impls.rs b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-nonreachable-impls.rs
rename to src/test/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs
diff --git a/src/test/auxiliary/rustdoc-trait-object-impl.rs b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs
similarity index 100%
rename from src/test/auxiliary/rustdoc-trait-object-impl.rs
rename to src/test/rustdoc/inline_cross/auxiliary/rustdoc-trait-object-impl.rs
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index e7019de8f43..ae8beb83530 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -108,9 +108,6 @@ pub struct Config {
     // The directory where programs should be built
     pub build_base: PathBuf,
 
-    // Directory for auxiliary libraries
-    pub aux_base: PathBuf,
-
     // The name of the stage being built (stage1, etc)
     pub stage_id: String,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index c8df8739f52..b5cebe2e3ea 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -18,6 +18,111 @@ use common::Config;
 use common;
 use util;
 
+/// Properties which must be known very early, before actually running
+/// the test.
+pub struct EarlyProps {
+    pub ignore: bool,
+    pub should_fail: bool,
+}
+
+impl EarlyProps {
+    pub fn from_file(config: &Config, testfile: &Path) -> Self {
+        let mut props = EarlyProps {
+            ignore: false,
+            should_fail: false,
+        };
+
+        iter_header(testfile, None, &mut |ln| {
+            props.ignore =
+                props.ignore ||
+                parse_name_directive(ln, "ignore-test") ||
+                parse_name_directive(ln, &ignore_target(config)) ||
+                parse_name_directive(ln, &ignore_architecture(config)) ||
+                parse_name_directive(ln, &ignore_stage(config)) ||
+                parse_name_directive(ln, &ignore_env(config)) ||
+                (config.mode == common::Pretty &&
+                 parse_name_directive(ln, "ignore-pretty")) ||
+                (config.target != config.host &&
+                 parse_name_directive(ln, "ignore-cross-compile")) ||
+                ignore_gdb(config, ln) ||
+                ignore_lldb(config, ln);
+
+            props.should_fail =
+                props.should_fail ||
+                parse_name_directive(ln, "should-fail");
+        });
+
+        return props;
+
+        fn ignore_target(config: &Config) -> String {
+            format!("ignore-{}", util::get_os(&config.target))
+        }
+        fn ignore_architecture(config: &Config) -> String {
+            format!("ignore-{}", util::get_arch(&config.target))
+        }
+        fn ignore_stage(config: &Config) -> String {
+            format!("ignore-{}",
+                    config.stage_id.split('-').next().unwrap())
+        }
+        fn ignore_env(config: &Config) -> String {
+            format!("ignore-{}", util::get_env(&config.target).unwrap_or("<unknown>"))
+        }
+        fn ignore_gdb(config: &Config, line: &str) -> bool {
+            if config.mode != common::DebugInfoGdb {
+                return false;
+            }
+
+            if parse_name_directive(line, "ignore-gdb") {
+                return true;
+            }
+
+            if let Some(ref actual_version) = config.gdb_version {
+                if line.contains("min-gdb-version") {
+                    let min_version = line.trim()
+                                          .split(' ')
+                                          .last()
+                                          .expect("Malformed GDB version directive");
+                    // Ignore if actual version is smaller the minimum required
+                    // version
+                    gdb_version_to_int(actual_version) <
+                        gdb_version_to_int(min_version)
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
+        }
+
+        fn ignore_lldb(config: &Config, line: &str) -> bool {
+            if config.mode != common::DebugInfoLldb {
+                return false;
+            }
+
+            if parse_name_directive(line, "ignore-lldb") {
+                return true;
+            }
+
+            if let Some(ref actual_version) = config.lldb_version {
+                if line.contains("min-lldb-version") {
+                    let min_version = line.trim()
+                                          .split(' ')
+                                          .last()
+                                          .expect("Malformed lldb version directive");
+                    // Ignore if actual version is smaller the minimum required
+                    // version
+                    lldb_version_to_int(actual_version) <
+                        lldb_version_to_int(min_version)
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
+        }
+    }
+}
+
 #[derive(Clone, Debug)]
 pub struct TestProps {
     // Lines that should be expected, in order, on standard out
@@ -29,7 +134,9 @@ pub struct TestProps {
     // If present, the name of a file that this test should match when
     // pretty-printed
     pub pp_exact: Option<PathBuf>,
-    // Modules from aux directory that should be compiled
+    // Other crates that should be compiled (typically from the same
+    // directory as the test, but for backwards compatibility reasons
+    // we also check the auxiliary directory)
     pub aux_builds: Vec<String> ,
     // Environment settings to use for compiling
     pub rustc_env: Vec<(String,String)> ,
@@ -57,233 +164,134 @@ pub struct TestProps {
     pub revisions: Vec<String>,
 }
 
-// Load any test directives embedded in the file
-pub fn load_props(testfile: &Path) -> TestProps {
-    let error_patterns = Vec::new();
-    let aux_builds = Vec::new();
-    let exec_env = Vec::new();
-    let run_flags = None;
-    let pp_exact = None;
-    let check_lines = Vec::new();
-    let build_aux_docs = false;
-    let force_host = false;
-    let check_stdout = false;
-    let no_prefer_dynamic = false;
-    let pretty_expanded = false;
-    let pretty_compare_only = false;
-    let forbid_output = Vec::new();
-    let mut props = TestProps {
-        error_patterns: error_patterns,
-        compile_flags: vec![],
-        run_flags: run_flags,
-        pp_exact: pp_exact,
-        aux_builds: aux_builds,
-        revisions: vec![],
-        rustc_env: vec![],
-        exec_env: exec_env,
-        check_lines: check_lines,
-        build_aux_docs: build_aux_docs,
-        force_host: force_host,
-        check_stdout: check_stdout,
-        no_prefer_dynamic: no_prefer_dynamic,
-        pretty_expanded: pretty_expanded,
-        pretty_mode: format!("normal"),
-        pretty_compare_only: pretty_compare_only,
-        forbid_output: forbid_output,
-    };
-    load_props_into(&mut props, testfile, None);
-    props
-}
-
-/// Load properties from `testfile` into `props`. If a property is
-/// tied to a particular revision `foo` (indicated by writing
-/// `//[foo]`), then the property is ignored unless `cfg` is
-/// `Some("foo")`.
-pub fn load_props_into(props: &mut TestProps, testfile: &Path, cfg: Option<&str>)  {
-    iter_header(testfile, cfg, &mut |ln| {
-        if let Some(ep) = parse_error_pattern(ln) {
-            props.error_patterns.push(ep);
-        }
-
-        if let Some(flags) = parse_compile_flags(ln) {
-            props.compile_flags.extend(
-                flags
-                    .split_whitespace()
-                    .map(|s| s.to_owned()));
-        }
-
-        if let Some(r) = parse_revisions(ln) {
-            props.revisions.extend(r);
-        }
-
-        if props.run_flags.is_none() {
-            props.run_flags = parse_run_flags(ln);
-        }
-
-        if props.pp_exact.is_none() {
-            props.pp_exact = parse_pp_exact(ln, testfile);
-        }
-
-        if !props.build_aux_docs {
-            props.build_aux_docs = parse_build_aux_docs(ln);
-        }
-
-        if !props.force_host {
-            props.force_host = parse_force_host(ln);
-        }
-
-        if !props.check_stdout {
-            props.check_stdout = parse_check_stdout(ln);
-        }
-
-        if !props.no_prefer_dynamic {
-            props.no_prefer_dynamic = parse_no_prefer_dynamic(ln);
-        }
-
-        if !props.pretty_expanded {
-            props.pretty_expanded = parse_pretty_expanded(ln);
-        }
-
-        if let Some(m) = parse_pretty_mode(ln) {
-            props.pretty_mode = m;
-        }
-
-        if !props.pretty_compare_only {
-            props.pretty_compare_only = parse_pretty_compare_only(ln);
-        }
-
-        if let  Some(ab) = parse_aux_build(ln) {
-            props.aux_builds.push(ab);
-        }
-
-        if let Some(ee) = parse_env(ln, "exec-env") {
-            props.exec_env.push(ee);
-        }
-
-        if let Some(ee) = parse_env(ln, "rustc-env") {
-            props.rustc_env.push(ee);
-        }
-
-        if let Some(cl) =  parse_check_line(ln) {
-            props.check_lines.push(cl);
-        }
-
-        if let Some(of) = parse_forbid_output(ln) {
-            props.forbid_output.push(of);
-        }
-    });
-
-    for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
-        match env::var(key) {
-            Ok(val) =>
-                if props.exec_env.iter().find(|&&(ref x, _)| *x == key).is_none() {
-                    props.exec_env.push((key.to_owned(), val))
-                },
-            Err(..) => {}
+impl TestProps {
+    pub fn new() -> Self {
+        let error_patterns = Vec::new();
+        let aux_builds = Vec::new();
+        let exec_env = Vec::new();
+        let run_flags = None;
+        let pp_exact = None;
+        let check_lines = Vec::new();
+        let build_aux_docs = false;
+        let force_host = false;
+        let check_stdout = false;
+        let no_prefer_dynamic = false;
+        let pretty_expanded = false;
+        let pretty_compare_only = false;
+        let forbid_output = Vec::new();
+        TestProps {
+            error_patterns: error_patterns,
+            compile_flags: vec![],
+            run_flags: run_flags,
+            pp_exact: pp_exact,
+            aux_builds: aux_builds,
+            revisions: vec![],
+            rustc_env: vec![],
+            exec_env: exec_env,
+            check_lines: check_lines,
+            build_aux_docs: build_aux_docs,
+            force_host: force_host,
+            check_stdout: check_stdout,
+            no_prefer_dynamic: no_prefer_dynamic,
+            pretty_expanded: pretty_expanded,
+            pretty_mode: format!("normal"),
+            pretty_compare_only: pretty_compare_only,
+            forbid_output: forbid_output,
         }
     }
-}
 
-pub struct EarlyProps {
-    pub ignore: bool,
-    pub should_fail: bool,
-}
-
-// scan the file to detect whether the test should be ignored and
-// whether it should panic; these are two things the test runner needs
-// to know early, before actually running the test
-pub fn early_props(config: &Config, testfile: &Path) -> EarlyProps {
-    let mut props = EarlyProps {
-        ignore: false,
-        should_fail: false,
-    };
-
-    iter_header(testfile, None, &mut |ln| {
-        props.ignore =
-            props.ignore ||
-            parse_name_directive(ln, "ignore-test") ||
-            parse_name_directive(ln, &ignore_target(config)) ||
-            parse_name_directive(ln, &ignore_architecture(config)) ||
-            parse_name_directive(ln, &ignore_stage(config)) ||
-            parse_name_directive(ln, &ignore_env(config)) ||
-            (config.mode == common::Pretty &&
-             parse_name_directive(ln, "ignore-pretty")) ||
-            (config.target != config.host &&
-             parse_name_directive(ln, "ignore-cross-compile")) ||
-            ignore_gdb(config, ln) ||
-            ignore_lldb(config, ln);
-
-        props.should_fail =
-            props.should_fail ||
-            parse_name_directive(ln, "should-fail");
-    });
-
-    return props;
-
-    fn ignore_target(config: &Config) -> String {
-        format!("ignore-{}", util::get_os(&config.target))
+    pub fn from_file(testfile: &Path) -> Self {
+        let mut props = TestProps::new();
+        props.load_from(testfile, None);
+        props
     }
-    fn ignore_architecture(config: &Config) -> String {
-        format!("ignore-{}", util::get_arch(&config.target))
-    }
-    fn ignore_stage(config: &Config) -> String {
-        format!("ignore-{}",
-                config.stage_id.split('-').next().unwrap())
-    }
-    fn ignore_env(config: &Config) -> String {
-        format!("ignore-{}", util::get_env(&config.target).unwrap_or("<unknown>"))
-    }
-    fn ignore_gdb(config: &Config, line: &str) -> bool {
-        if config.mode != common::DebugInfoGdb {
-            return false;
-        }
 
-        if parse_name_directive(line, "ignore-gdb") {
-            return true;
-        }
-
-        if let Some(ref actual_version) = config.gdb_version {
-            if line.contains("min-gdb-version") {
-                let min_version = line.trim()
-                                      .split(' ')
-                                      .last()
-                                      .expect("Malformed GDB version directive");
-                // Ignore if actual version is smaller the minimum required
-                // version
-                gdb_version_to_int(actual_version) <
-                    gdb_version_to_int(min_version)
-            } else {
-                false
+    /// Load properties from `testfile` into `props`. If a property is
+    /// tied to a particular revision `foo` (indicated by writing
+    /// `//[foo]`), then the property is ignored unless `cfg` is
+    /// `Some("foo")`.
+    pub fn load_from(&mut self, testfile: &Path, cfg: Option<&str>)  {
+        iter_header(testfile, cfg, &mut |ln| {
+            if let Some(ep) = parse_error_pattern(ln) {
+                self.error_patterns.push(ep);
             }
-        } else {
-            false
-        }
-    }
 
-    fn ignore_lldb(config: &Config, line: &str) -> bool {
-        if config.mode != common::DebugInfoLldb {
-            return false;
-        }
-
-        if parse_name_directive(line, "ignore-lldb") {
-            return true;
-        }
-
-        if let Some(ref actual_version) = config.lldb_version {
-            if line.contains("min-lldb-version") {
-                let min_version = line.trim()
-                                      .split(' ')
-                                      .last()
-                                      .expect("Malformed lldb version directive");
-                // Ignore if actual version is smaller the minimum required
-                // version
-                lldb_version_to_int(actual_version) <
-                    lldb_version_to_int(min_version)
-            } else {
-                false
+            if let Some(flags) = parse_compile_flags(ln) {
+                self.compile_flags.extend(
+                    flags
+                        .split_whitespace()
+                        .map(|s| s.to_owned()));
+            }
+
+            if let Some(r) = parse_revisions(ln) {
+                self.revisions.extend(r);
+            }
+
+            if self.run_flags.is_none() {
+                self.run_flags = parse_run_flags(ln);
+            }
+
+            if self.pp_exact.is_none() {
+                self.pp_exact = parse_pp_exact(ln, testfile);
+            }
+
+            if !self.build_aux_docs {
+                self.build_aux_docs = parse_build_aux_docs(ln);
+            }
+
+            if !self.force_host {
+                self.force_host = parse_force_host(ln);
+            }
+
+            if !self.check_stdout {
+                self.check_stdout = parse_check_stdout(ln);
+            }
+
+            if !self.no_prefer_dynamic {
+                self.no_prefer_dynamic = parse_no_prefer_dynamic(ln);
+            }
+
+            if !self.pretty_expanded {
+                self.pretty_expanded = parse_pretty_expanded(ln);
+            }
+
+            if let Some(m) = parse_pretty_mode(ln) {
+                self.pretty_mode = m;
+            }
+
+            if !self.pretty_compare_only {
+                self.pretty_compare_only = parse_pretty_compare_only(ln);
+            }
+
+            if let  Some(ab) = parse_aux_build(ln) {
+                self.aux_builds.push(ab);
+            }
+
+            if let Some(ee) = parse_env(ln, "exec-env") {
+                self.exec_env.push(ee);
+            }
+
+            if let Some(ee) = parse_env(ln, "rustc-env") {
+                self.rustc_env.push(ee);
+            }
+
+            if let Some(cl) =  parse_check_line(ln) {
+                self.check_lines.push(cl);
+            }
+
+            if let Some(of) = parse_forbid_output(ln) {
+                self.forbid_output.push(of);
+            }
+        });
+
+        for key in vec!["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {
+            match env::var(key) {
+                Ok(val) =>
+                    if self.exec_env.iter().find(|&&(ref x, _)| *x == key).is_none() {
+                        self.exec_env.push((key.to_owned(), val))
+                    },
+                Err(..) => {}
             }
-        } else {
-            false
         }
     }
 }
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 26382967c6b..245c3992bee 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -30,6 +30,7 @@ extern crate log;
 extern crate env_logger;
 
 use std::env;
+use std::ffi::OsString;
 use std::fs;
 use std::io;
 use std::path::{Path, PathBuf};
@@ -39,6 +40,8 @@ use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Mode};
 use test::TestPaths;
 use util::logv;
 
+use self::header::EarlyProps;
+
 pub mod procsrv;
 pub mod util;
 mod json;
@@ -79,7 +82,6 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR"),
           reqopt("", "src-base", "directory to scan for test files", "PATH"),
           reqopt("", "build-base", "directory to deposit test outputs", "PATH"),
-          reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
           reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
           reqopt("", "mode", "which sort of compile tests to run",
                  "(compile-fail|parse-fail|run-fail|run-pass|\
@@ -155,7 +157,6 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         llvm_filecheck: matches.opt_str("llvm-filecheck").map(|s| PathBuf::from(&s)),
         src_base: opt_path(matches, "src-base"),
         build_base: opt_path(matches, "build-base"),
-        aux_base: opt_path(matches, "aux-base"),
         stage_id: matches.opt_str("stage-id").unwrap(),
         mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
         run_ignored: matches.opt_present("ignored"),
@@ -333,21 +334,24 @@ fn collect_tests_from_dir(config: &Config,
         }
     }
 
+    // If we find a test foo/bar.rs, we have to build the
+    // output directory `$build/foo` so we can write
+    // `$build/foo/bar` into it. We do this *now* in this
+    // sequential loop because otherwise, if we do it in the
+    // tests themselves, they race for the privilege of
+    // creating the directories and sometimes fail randomly.
+    let build_dir = config.build_base.join(&relative_dir_path);
+    fs::create_dir_all(&build_dir).unwrap();
+
+    // Add each `.rs` file as a test, and recurse further on any
+    // subdirectories we find, except for `aux` directories.
     let dirs = fs::read_dir(dir)?;
     for file in dirs {
         let file = file?;
         let file_path = file.path();
-        debug!("inspecting file {:?}", file_path.display());
-        if is_test(config, &file_path) {
-            // If we find a test foo/bar.rs, we have to build the
-            // output directory `$build/foo` so we can write
-            // `$build/foo/bar` into it. We do this *now* in this
-            // sequential loop because otherwise, if we do it in the
-            // tests themselves, they race for the privilege of
-            // creating the directories and sometimes fail randomly.
-            let build_dir = config.build_base.join(&relative_dir_path);
-            fs::create_dir_all(&build_dir).unwrap();
-
+        let file_name = file.file_name();
+        if is_test(&file_name) {
+            debug!("found test file: {:?}", file_path.display());
             let paths = TestPaths {
                 file: file_path,
                 base: base.to_path_buf(),
@@ -356,45 +360,43 @@ fn collect_tests_from_dir(config: &Config,
             tests.push(make_test(config, &paths))
         } else if file_path.is_dir() {
             let relative_file_path = relative_dir_path.join(file.file_name());
-            collect_tests_from_dir(config,
-                                   base,
-                                   &file_path,
-                                   &relative_file_path,
-                                   tests)?;
+            if &file_name == "auxiliary" {
+                // `aux` directories contain other crates used for
+                // cross-crate tests. Don't search them for tests, but
+                // do create a directory in the build dir for them,
+                // since we will dump intermediate output in there
+                // sometimes.
+                let build_dir = config.build_base.join(&relative_file_path);
+                fs::create_dir_all(&build_dir).unwrap();
+            } else {
+                debug!("found directory: {:?}", file_path.display());
+                collect_tests_from_dir(config,
+                                       base,
+                                       &file_path,
+                                       &relative_file_path,
+                                       tests)?;
+            }
+        } else {
+            debug!("found other file/directory: {:?}", file_path.display());
         }
     }
     Ok(())
 }
 
-pub fn is_test(config: &Config, testfile: &Path) -> bool {
-    // Pretty-printer does not work with .rc files yet
-    let valid_extensions =
-        match config.mode {
-          Pretty => vec!(".rs".to_owned()),
-          _ => vec!(".rc".to_owned(), ".rs".to_owned())
-        };
-    let invalid_prefixes = vec!(".".to_owned(), "#".to_owned(), "~".to_owned());
-    let name = testfile.file_name().unwrap().to_str().unwrap();
+pub fn is_test(file_name: &OsString) -> bool {
+    let file_name = file_name.to_str().unwrap();
 
-    let mut valid = false;
-
-    for ext in &valid_extensions {
-        if name.ends_with(ext) {
-            valid = true;
-        }
+    if !file_name.ends_with(".rs") {
+        return false;
     }
 
-    for pre in &invalid_prefixes {
-        if name.starts_with(pre) {
-            valid = false;
-        }
-    }
-
-    return valid;
+    // `.`, `#`, and `~` are common temp-file prefixes.
+    let invalid_prefixes = &[".", "#", "~"];
+    !invalid_prefixes.iter().any(|p| file_name.starts_with(p))
 }
 
 pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn {
-    let early_props = header::early_props(config, &testpaths.file);
+    let early_props = EarlyProps::from_file(config, &testpaths.file);
 
     // The `should-fail` annotation doesn't apply to pretty tests,
     // since we run the pretty printer across all tests by default.
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 19f706dc1d7..74e4b81f555 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -47,308 +47,304 @@ pub fn run(config: Config, testpaths: &TestPaths) {
         print!("\n\n");
     }
     debug!("running {:?}", testpaths.file.display());
-    let props = header::load_props(&testpaths.file);
-    debug!("loaded props");
-    match config.mode {
-        CompileFail => run_cfail_test(&config, &props, &testpaths),
-        ParseFail => run_cfail_test(&config, &props, &testpaths),
-        RunFail => run_rfail_test(&config, &props, &testpaths),
-        RunPass => run_rpass_test(&config, &props, &testpaths),
-        RunPassValgrind => run_valgrind_test(&config, &props, &testpaths),
-        Pretty => run_pretty_test(&config, &props, &testpaths),
-        DebugInfoGdb => run_debuginfo_gdb_test(&config, &props, &testpaths),
-        DebugInfoLldb => run_debuginfo_lldb_test(&config, &props, &testpaths),
-        Codegen => run_codegen_test(&config, &props, &testpaths),
-        Rustdoc => run_rustdoc_test(&config, &props, &testpaths),
-        CodegenUnits => run_codegen_units_test(&config, &props, &testpaths),
-        Incremental => run_incremental_test(&config, &props, &testpaths),
-        RunMake => run_rmake_test(&config, &props, &testpaths),
-    }
-}
+    let base_props = TestProps::from_file(&testpaths.file);
 
-fn get_output(props: &TestProps, proc_res: &ProcRes) -> String {
-    if props.check_stdout {
-        format!("{}{}", proc_res.stdout, proc_res.stderr)
+    let base_cx = TestCx { config: &config,
+                           props: &base_props,
+                           testpaths: testpaths,
+                           revision: None };
+    base_cx.init_all();
+
+    if base_props.revisions.is_empty() {
+        base_cx.run_revision()
     } else {
-        proc_res.stderr.clone()
-    }
-}
-
-
-fn for_each_revision<OP>(config: &Config, props: &TestProps, testpaths: &TestPaths,
-                         mut op: OP)
-    where OP: FnMut(&Config, &TestProps, &TestPaths, Option<&str>)
-{
-    if props.revisions.is_empty() {
-        op(config, props, testpaths, None)
-    } else {
-        for revision in &props.revisions {
-            let mut revision_props = props.clone();
-            header::load_props_into(&mut revision_props,
-                                    &testpaths.file,
-                                    Some(&revision));
+        for revision in &base_props.revisions {
+            let mut revision_props = base_props.clone();
+            revision_props.load_from(&testpaths.file, Some(&revision));
             revision_props.compile_flags.extend(vec![
                 format!("--cfg"),
                 format!("{}", revision),
             ]);
-            op(config, &revision_props, testpaths, Some(revision));
+            let rev_cx = TestCx {
+                config: &config,
+                props: &revision_props,
+                testpaths: testpaths,
+                revision: Some(revision)
+            };
+            rev_cx.run_revision();
         }
     }
+
+    base_cx.complete_all();
 }
 
-fn run_cfail_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    for_each_revision(config, props, testpaths, run_cfail_test_revision);
+struct TestCx<'test> {
+    config: &'test Config,
+    props: &'test TestProps,
+    testpaths: &'test TestPaths,
+    revision: Option<&'test str>
 }
 
-fn run_cfail_test_revision(config: &Config,
-                           props: &TestProps,
-                           testpaths: &TestPaths,
-                           revision: Option<&str>) {
-    let proc_res = compile_test(config, props, testpaths);
+struct DebuggerCommands {
+    commands: Vec<String>,
+    check_lines: Vec<String>,
+    breakpoint_lines: Vec<usize>,
+}
 
-    if proc_res.status.success() {
-        fatal_proc_rec(
-            revision,
-            &format!("{} test compiled successfully!", config.mode)[..],
-            &proc_res);
-    }
-
-    check_correct_failure_status(revision, &proc_res);
-
-    if proc_res.status.success() {
-        fatal(revision, "process did not return an error status");
-    }
-
-    let output_to_check = get_output(props, &proc_res);
-    let expected_errors = errors::load_errors(&testpaths.file, revision);
-    if !expected_errors.is_empty() {
-        if !props.error_patterns.is_empty() {
-            fatal(revision, "both error pattern and expected errors specified");
+impl<'test> TestCx<'test> {
+    /// invoked once before any revisions have been processed
+    fn init_all(&self) {
+        assert!(self.revision.is_none(), "init_all invoked for a revision");
+        match self.config.mode {
+            Incremental => self.init_incremental_test(),
+            _ => { }
         }
-        check_expected_errors(revision, expected_errors, testpaths, &proc_res);
-    } else {
-        check_error_patterns(revision, props, testpaths, &output_to_check, &proc_res);
-    }
-    check_no_compiler_crash(revision, &proc_res);
-    check_forbid_output(revision, props, &output_to_check, &proc_res);
-}
-
-fn run_rfail_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    for_each_revision(config, props, testpaths, run_rfail_test_revision);
-}
-
-fn run_rfail_test_revision(config: &Config,
-                           props: &TestProps,
-                           testpaths: &TestPaths,
-                           revision: Option<&str>) {
-    let proc_res = compile_test(config, props, testpaths);
-
-    if !proc_res.status.success() {
-        fatal_proc_rec(revision, "compilation failed!", &proc_res);
     }
 
-    let proc_res = exec_compiled_test(config, props, testpaths);
-
-    // The value our Makefile configures valgrind to return on failure
-    const VALGRIND_ERR: i32 = 100;
-    if proc_res.status.code() == Some(VALGRIND_ERR) {
-        fatal_proc_rec(revision, "run-fail test isn't valgrind-clean!", &proc_res);
+    /// Code executed for each revision in turn (or, if there are no
+    /// revisions, exactly once, with revision == None).
+    fn run_revision(&self) {
+        match self.config.mode {
+            CompileFail => self.run_cfail_test(),
+            ParseFail => self.run_cfail_test(),
+            RunFail => self.run_rfail_test(),
+            RunPass => self.run_rpass_test(),
+            RunPassValgrind => self.run_valgrind_test(),
+            Pretty => self.run_pretty_test(),
+            DebugInfoGdb => self.run_debuginfo_gdb_test(),
+            DebugInfoLldb => self.run_debuginfo_lldb_test(),
+            Codegen => self.run_codegen_test(),
+            Rustdoc => self.run_rustdoc_test(),
+            CodegenUnits => self.run_codegen_units_test(),
+            Incremental => self.run_incremental_test(),
+            RunMake => self.run_rmake_test(),
+        }
     }
 
-    let output_to_check = get_output(props, &proc_res);
-    check_correct_failure_status(revision, &proc_res);
-    check_error_patterns(revision, props, testpaths, &output_to_check, &proc_res);
-}
-
-fn check_correct_failure_status(revision: Option<&str>, proc_res: &ProcRes) {
-    // The value the rust runtime returns on failure
-    const RUST_ERR: i32 = 101;
-    if proc_res.status.code() != Some(RUST_ERR) {
-        fatal_proc_rec(
-            revision,
-            &format!("failure produced the wrong error: {}",
-                     proc_res.status),
-            proc_res);
-    }
-}
-
-fn run_rpass_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    for_each_revision(config, props, testpaths, run_rpass_test_revision);
-}
-
-fn run_rpass_test_revision(config: &Config,
-                           props: &TestProps,
-                           testpaths: &TestPaths,
-                           revision: Option<&str>) {
-    let proc_res = compile_test(config, props, testpaths);
-
-    if !proc_res.status.success() {
-        fatal_proc_rec(revision, "compilation failed!", &proc_res);
+    /// Invoked after all revisions have executed.
+    fn complete_all(&self) {
+        assert!(self.revision.is_none(), "init_all invoked for a revision");
     }
 
-    let proc_res = exec_compiled_test(config, props, testpaths);
+    fn run_cfail_test(&self) {
+        let proc_res = self.compile_test();
 
-    if !proc_res.status.success() {
-        fatal_proc_rec(revision, "test run failed!", &proc_res);
-    }
-}
+        if proc_res.status.success() {
+            self.fatal_proc_rec(
+                &format!("{} test compiled successfully!", self.config.mode)[..],
+                &proc_res);
+        }
 
-fn run_valgrind_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    assert!(props.revisions.is_empty(), "revisions not relevant here");
+        self.check_correct_failure_status(&proc_res);
 
-    if config.valgrind_path.is_none() {
-        assert!(!config.force_valgrind);
-        return run_rpass_test(config, props, testpaths);
+        if proc_res.status.success() {
+            self.fatal("process did not return an error status");
+        }
+
+        let output_to_check = self.get_output(&proc_res);
+        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
+        if !expected_errors.is_empty() {
+            if !self.props.error_patterns.is_empty() {
+                self.fatal("both error pattern and expected errors specified");
+            }
+            self.check_expected_errors(expected_errors, &proc_res);
+        } else {
+            self.check_error_patterns(&output_to_check, &proc_res);
+        }
+        self.check_no_compiler_crash(&proc_res);
+        self.check_forbid_output(&output_to_check, &proc_res);
     }
 
-    let mut proc_res = compile_test(config, props, testpaths);
-
-    if !proc_res.status.success() {
-        fatal_proc_rec(None, "compilation failed!", &proc_res);
-    }
-
-    let mut new_config = config.clone();
-    new_config.runtool = new_config.valgrind_path.clone();
-    proc_res = exec_compiled_test(&new_config, props, testpaths);
-
-    if !proc_res.status.success() {
-        fatal_proc_rec(None, "test run failed!", &proc_res);
-    }
-}
-
-fn run_pretty_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    for_each_revision(config, props, testpaths, run_pretty_test_revision);
-}
-
-fn run_pretty_test_revision(config: &Config,
-                            props: &TestProps,
-                            testpaths: &TestPaths,
-                            revision: Option<&str>) {
-    if props.pp_exact.is_some() {
-        logv(config, "testing for exact pretty-printing".to_owned());
-    } else {
-        logv(config, "testing for converging pretty-printing".to_owned());
-    }
-
-    let rounds =
-        match props.pp_exact { Some(_) => 1, None => 2 };
-
-    let mut src = String::new();
-    File::open(&testpaths.file).unwrap().read_to_string(&mut src).unwrap();
-    let mut srcs = vec!(src);
-
-    let mut round = 0;
-    while round < rounds {
-        logv(config, format!("pretty-printing round {} revision {:?}",
-                             round, revision));
-        let proc_res = print_source(config,
-                                    props,
-                                    testpaths,
-                                    srcs[round].to_owned(),
-                                    &props.pretty_mode);
+    fn run_rfail_test(&self) {
+        let proc_res = self.compile_test();
 
         if !proc_res.status.success() {
-            fatal_proc_rec(revision,
-                           &format!("pretty-printing failed in round {} revision {:?}",
-                                    round, revision),
-                           &proc_res);
+            self.fatal_proc_rec("compilation failed!", &proc_res);
         }
 
-        let ProcRes{ stdout, .. } = proc_res;
-        srcs.push(stdout);
-        round += 1;
-    }
+        let proc_res = self.exec_compiled_test();
 
-    let mut expected = match props.pp_exact {
-        Some(ref file) => {
-            let filepath = testpaths.file.parent().unwrap().join(file);
-            let mut s = String::new();
-            File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
-            s
+        // The value our Makefile configures valgrind to return on failure
+        const VALGRIND_ERR: i32 = 100;
+        if proc_res.status.code() == Some(VALGRIND_ERR) {
+            self.fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
         }
-        None => { srcs[srcs.len() - 2].clone() }
-    };
-    let mut actual = srcs[srcs.len() - 1].clone();
 
-    if props.pp_exact.is_some() {
-        // Now we have to care about line endings
-        let cr = "\r".to_owned();
-        actual = actual.replace(&cr, "").to_owned();
-        expected = expected.replace(&cr, "").to_owned();
+        let output_to_check = self.get_output(&proc_res);
+        self.check_correct_failure_status(&proc_res);
+        self.check_error_patterns(&output_to_check, &proc_res);
     }
 
-    compare_source(revision, &expected, &actual);
-
-    // If we're only making sure that the output matches then just stop here
-    if props.pretty_compare_only { return; }
-
-    // Finally, let's make sure it actually appears to remain valid code
-    let proc_res = typecheck_source(config, props, testpaths, actual);
-    if !proc_res.status.success() {
-        fatal_proc_rec(revision, "pretty-printed source does not typecheck", &proc_res);
+    fn get_output(&self, proc_res: &ProcRes) -> String {
+        if self.props.check_stdout {
+            format!("{}{}", proc_res.stdout, proc_res.stderr)
+        } else {
+            proc_res.stderr.clone()
+        }
     }
 
-    if !props.pretty_expanded { return }
-
-    // additionally, run `--pretty expanded` and try to build it.
-    let proc_res = print_source(config, props, testpaths, srcs[round].clone(), "expanded");
-    if !proc_res.status.success() {
-        fatal_proc_rec(revision, "pretty-printing (expanded) failed", &proc_res);
+    fn check_correct_failure_status(&self, proc_res: &ProcRes) {
+        // The value the rust runtime returns on failure
+        const RUST_ERR: i32 = 101;
+        if proc_res.status.code() != Some(RUST_ERR) {
+            self.fatal_proc_rec(
+                &format!("failure produced the wrong error: {}",
+                         proc_res.status),
+                proc_res);
+        }
     }
 
-    let ProcRes{ stdout: expanded_src, .. } = proc_res;
-    let proc_res = typecheck_source(config, props, testpaths, expanded_src);
-    if !proc_res.status.success() {
-        fatal_proc_rec(
-            revision,
-            "pretty-printed source (expanded) does not typecheck",
-            &proc_res);
+    fn run_rpass_test(&self) {
+        let proc_res = self.compile_test();
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        let proc_res = self.exec_compiled_test();
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("test run failed!", &proc_res);
+        }
     }
 
-    return;
+    fn run_valgrind_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
 
-    fn print_source(config: &Config,
-                    props: &TestProps,
-                    testpaths: &TestPaths,
+        if self.config.valgrind_path.is_none() {
+            assert!(!self.config.force_valgrind);
+            return self.run_rpass_test();
+        }
+
+        let mut proc_res = self.compile_test();
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        let mut new_config = self.config.clone();
+        new_config.runtool = new_config.valgrind_path.clone();
+        let new_cx = TestCx { config: &new_config, ..*self };
+        proc_res = new_cx.exec_compiled_test();
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("test run failed!", &proc_res);
+        }
+    }
+
+    fn run_pretty_test(&self) {
+        if self.props.pp_exact.is_some() {
+            logv(self.config, "testing for exact pretty-printing".to_owned());
+        } else {
+            logv(self.config, "testing for converging pretty-printing".to_owned());
+        }
+
+        let rounds = match self.props.pp_exact { Some(_) => 1, None => 2 };
+
+        let mut src = String::new();
+        File::open(&self.testpaths.file).unwrap().read_to_string(&mut src).unwrap();
+        let mut srcs = vec!(src);
+
+        let mut round = 0;
+        while round < rounds {
+            logv(self.config, format!("pretty-printing round {} revision {:?}",
+                                      round, self.revision));
+            let proc_res = self.print_source(srcs[round].to_owned(), &self.props.pretty_mode);
+
+            if !proc_res.status.success() {
+                self.fatal_proc_rec(&format!("pretty-printing failed in round {} revision {:?}",
+                                             round, self.revision),
+                                    &proc_res);
+            }
+
+            let ProcRes{ stdout, .. } = proc_res;
+            srcs.push(stdout);
+            round += 1;
+        }
+
+        let mut expected = match self.props.pp_exact {
+            Some(ref file) => {
+                let filepath = self.testpaths.file.parent().unwrap().join(file);
+                let mut s = String::new();
+                File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
+                s
+            }
+            None => { srcs[srcs.len() - 2].clone() }
+        };
+        let mut actual = srcs[srcs.len() - 1].clone();
+
+        if self.props.pp_exact.is_some() {
+            // Now we have to care about line endings
+            let cr = "\r".to_owned();
+            actual = actual.replace(&cr, "").to_owned();
+            expected = expected.replace(&cr, "").to_owned();
+        }
+
+        self.compare_source(&expected, &actual);
+
+        // If we're only making sure that the output matches then just stop here
+        if self.props.pretty_compare_only { return; }
+
+        // Finally, let's make sure it actually appears to remain valid code
+        let proc_res = self.typecheck_source(actual);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
+        }
+
+        if !self.props.pretty_expanded { return }
+
+        // additionally, run `--pretty expanded` and try to build it.
+        let proc_res = self.print_source(srcs[round].clone(), "expanded");
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
+        }
+
+        let ProcRes{ stdout: expanded_src, .. } = proc_res;
+        let proc_res = self.typecheck_source(expanded_src);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec(
+                "pretty-printed source (expanded) does not typecheck",
+                &proc_res);
+        }
+    }
+
+    fn print_source(&self,
                     src: String,
-                    pretty_type: &str) -> ProcRes {
-        let aux_dir = aux_output_dir_name(config, testpaths);
-        compose_and_run(config,
-                        testpaths,
-                        make_pp_args(config,
-                                     props,
-                                     testpaths,
-                                     pretty_type.to_owned()),
-                        props.exec_env.clone(),
-                        config.compile_lib_path.to_str().unwrap(),
-                        Some(aux_dir.to_str().unwrap()),
-                        Some(src))
+                    pretty_type: &str)
+                    -> ProcRes {
+        let aux_dir = self.aux_output_dir_name();
+        self.compose_and_run(self.make_pp_args(pretty_type.to_owned()),
+                             self.props.exec_env.clone(),
+                             self.config.compile_lib_path.to_str().unwrap(),
+                             Some(aux_dir.to_str().unwrap()),
+                             Some(src))
     }
 
-    fn make_pp_args(config: &Config,
-                    props: &TestProps,
-                    testpaths: &TestPaths,
-                    pretty_type: String) -> ProcArgs {
-        let aux_dir = aux_output_dir_name(config, testpaths);
+    fn make_pp_args(&self,
+                    pretty_type: String)
+                    -> ProcArgs {
+        let aux_dir = self.aux_output_dir_name();
         // FIXME (#9639): This needs to handle non-utf8 paths
         let mut args = vec!("-".to_owned(),
                             "-Zunstable-options".to_owned(),
                             "--unpretty".to_owned(),
                             pretty_type,
-                            format!("--target={}", config.target),
+                            format!("--target={}", self.config.target),
                             "-L".to_owned(),
                             aux_dir.to_str().unwrap().to_owned());
-        args.extend(split_maybe_args(&config.target_rustcflags));
-        args.extend(props.compile_flags.iter().cloned());
+        args.extend(self.split_maybe_args(&self.config.target_rustcflags));
+        args.extend(self.props.compile_flags.iter().cloned());
         return ProcArgs {
-            prog: config.rustc_path.to_str().unwrap().to_owned(),
+            prog: self.config.rustc_path.to_str().unwrap().to_owned(),
             args: args,
         };
     }
 
-    fn compare_source(revision: Option<&str>, expected: &str, actual: &str) {
+    fn compare_source(&self,
+                      expected: &str,
+                      actual: &str) {
         if expected != actual {
-            error(revision, "pretty-printed source does not match expected source");
+            self.error("pretty-printed source does not match expected source");
             println!("\n\
 expected:\n\
 ------------------------------------------\n\
@@ -364,749 +360,1741 @@ actual:\n\
         }
     }
 
-    fn typecheck_source(config: &Config, props: &TestProps,
-                        testpaths: &TestPaths, src: String) -> ProcRes {
-        let args = make_typecheck_args(config, props, testpaths);
-        compose_and_run_compiler(config, props, testpaths, args, Some(src))
+    fn typecheck_source(&self, src: String) -> ProcRes {
+        let args = self.make_typecheck_args();
+        self.compose_and_run_compiler(args, Some(src))
     }
 
-    fn make_typecheck_args(config: &Config, props: &TestProps, testpaths: &TestPaths) -> ProcArgs {
-        let aux_dir = aux_output_dir_name(config, testpaths);
-        let target = if props.force_host {
-            &*config.host
+    fn make_typecheck_args(&self) -> ProcArgs {
+        let aux_dir = self.aux_output_dir_name();
+        let target = if self.props.force_host {
+            &*self.config.host
         } else {
-            &*config.target
+            &*self.config.target
         };
         // FIXME (#9639): This needs to handle non-utf8 paths
         let mut args = vec!("-".to_owned(),
                             "-Zno-trans".to_owned(),
                             format!("--target={}", target),
                             "-L".to_owned(),
-                            config.build_base.to_str().unwrap().to_owned(),
+                            self.config.build_base.to_str().unwrap().to_owned(),
                             "-L".to_owned(),
                             aux_dir.to_str().unwrap().to_owned());
-        args.extend(split_maybe_args(&config.target_rustcflags));
-        args.extend(props.compile_flags.iter().cloned());
+        args.extend(self.split_maybe_args(&self.config.target_rustcflags));
+        args.extend(self.props.compile_flags.iter().cloned());
         // FIXME (#9639): This needs to handle non-utf8 paths
         return ProcArgs {
-            prog: config.rustc_path.to_str().unwrap().to_owned(),
+            prog: self.config.rustc_path.to_str().unwrap().to_owned(),
             args: args,
         };
     }
-}
 
-fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    assert!(props.revisions.is_empty(), "revisions not relevant here");
+    fn run_debuginfo_gdb_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
 
-    let mut config = Config {
-        target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags),
-        host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags),
-        .. config.clone()
-    };
+        let config = Config {
+            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
+            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            .. self.config.clone()
+        };
 
-    let config = &mut config;
-    let DebuggerCommands {
-        commands,
-        check_lines,
-        breakpoint_lines
-    } = parse_debugger_commands(testpaths, "gdb");
-    let mut cmds = commands.join("\n");
+        let test_cx = TestCx {
+            config: &config,
+            ..*self
+        };
 
-    // compile test file (it should have 'compile-flags:-g' in the header)
-    let compiler_run_result = compile_test(config, props, testpaths);
-    if !compiler_run_result.status.success() {
-        fatal_proc_rec(None, "compilation failed!", &compiler_run_result);
+        test_cx.run_debuginfo_gdb_test_no_opt();
     }
 
-    let exe_file = make_exe_name(config, testpaths);
+    fn run_debuginfo_gdb_test_no_opt(&self) {
+        let DebuggerCommands {
+            commands,
+            check_lines,
+            breakpoint_lines
+        } = self.parse_debugger_commands("gdb");
+        let mut cmds = commands.join("\n");
 
-    let debugger_run_result;
-    match &*config.target {
-        "arm-linux-androideabi" | "aarch64-linux-android" => {
-
-            cmds = cmds.replace("run", "continue");
-
-            // write debugger script
-            let mut script_str = String::with_capacity(2048);
-            script_str.push_str(&format!("set charset {}\n", charset()));
-            script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
-            script_str.push_str("target remote :5039\n");
-            script_str.push_str(&format!("set solib-search-path \
-                                         ./{}/stage2/lib/rustlib/{}/lib/\n",
-                                         config.host, config.target));
-            for line in &breakpoint_lines {
-                script_str.push_str(&format!("break {:?}:{}\n",
-                                             testpaths.file
-                                                      .file_name()
-                                                      .unwrap()
-                                                      .to_string_lossy(),
-                                             *line)[..]);
-            }
-            script_str.push_str(&cmds);
-            script_str.push_str("\nquit\n");
-
-            debug!("script_str = {}", script_str);
-            dump_output_file(config,
-                             testpaths,
-                             &script_str,
-                             "debugger.script");
-
-
-            procsrv::run("",
-                         &config.adb_path,
-                         None,
-                         &[
-                            "push".to_owned(),
-                            exe_file.to_str().unwrap().to_owned(),
-                            config.adb_test_dir.clone()
-                         ],
-                         vec!(("".to_owned(), "".to_owned())),
-                         Some("".to_owned()))
-                .expect(&format!("failed to exec `{:?}`", config.adb_path));
-
-            procsrv::run("",
-                         &config.adb_path,
-                         None,
-                         &[
-                            "forward".to_owned(),
-                            "tcp:5039".to_owned(),
-                            "tcp:5039".to_owned()
-                         ],
-                         vec!(("".to_owned(), "".to_owned())),
-                         Some("".to_owned()))
-                .expect(&format!("failed to exec `{:?}`", config.adb_path));
-
-            let adb_arg = format!("export LD_LIBRARY_PATH={}; \
-                                   gdbserver{} :5039 {}/{}",
-                                  config.adb_test_dir.clone(),
-                                  if config.target.contains("aarch64")
-                                  {"64"} else {""},
-                                  config.adb_test_dir.clone(),
-                                  exe_file.file_name().unwrap().to_str()
-                                          .unwrap());
-
-            let mut process = procsrv::run_background("",
-                                                      &config.adb_path
-                                                            ,
-                                                      None,
-                                                      &[
-                                                        "shell".to_owned(),
-                                                        adb_arg.clone()
-                                                      ],
-                                                      vec!(("".to_owned(),
-                                                            "".to_owned())),
-                                                      Some("".to_owned()))
-                .expect(&format!("failed to exec `{:?}`", config.adb_path));
-            loop {
-                //waiting 1 second for gdbserver start
-                ::std::thread::sleep(::std::time::Duration::new(1,0));
-                if TcpStream::connect("127.0.0.1:5039").is_ok() {
-                    break
-                }
-            }
-
-            let tool_path = match config.android_cross_path.to_str() {
-                Some(x) => x.to_owned(),
-                None => fatal(None, "cannot find android cross path")
-            };
-
-            let debugger_script = make_out_name(config, testpaths, "debugger.script");
-            // FIXME (#9639): This needs to handle non-utf8 paths
-            let debugger_opts =
-                vec!("-quiet".to_owned(),
-                     "-batch".to_owned(),
-                     "-nx".to_owned(),
-                     format!("-command={}", debugger_script.to_str().unwrap()));
-
-            let mut gdb_path = tool_path;
-            gdb_path.push_str(&format!("/bin/{}-gdb", config.target));
-            let procsrv::Result {
-                out,
-                err,
-                status
-            } = procsrv::run("",
-                             &gdb_path,
-                             None,
-                             &debugger_opts,
-                             vec!(("".to_owned(), "".to_owned())),
-                             None)
-                .expect(&format!("failed to exec `{:?}`", gdb_path));
-            let cmdline = {
-                let cmdline = make_cmdline("",
-                                           &format!("{}-gdb", config.target),
-                                           &debugger_opts);
-                logv(config, format!("executing {}", cmdline));
-                cmdline
-            };
-
-            debugger_run_result = ProcRes {
-                status: Status::Normal(status),
-                stdout: out,
-                stderr: err,
-                cmdline: cmdline
-            };
-            if process.kill().is_err() {
-                println!("Adb process is already finished.");
-            }
+        // compile test file (it should have 'compile-flags:-g' in the header)
+        let compiler_run_result = self.compile_test();
+        if !compiler_run_result.status.success() {
+            self.fatal_proc_rec("compilation failed!", &compiler_run_result);
         }
 
-        _=> {
-            let rust_src_root = find_rust_src_root(config)
-                .expect("Could not find Rust source root");
-            let rust_pp_module_rel_path = Path::new("./src/etc");
-            let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
-                                                       .to_str()
-                                                       .unwrap()
-                                                       .to_owned();
-            // write debugger script
-            let mut script_str = String::with_capacity(2048);
-            script_str.push_str(&format!("set charset {}\n", charset()));
-            script_str.push_str("show version\n");
+        let exe_file = self.make_exe_name();
 
-            match config.gdb_version {
-                Some(ref version) => {
-                    println!("NOTE: compiletest thinks it is using GDB version {}",
-                             version);
+        let debugger_run_result;
+        match &*self.config.target {
+            "arm-linux-androideabi" | "aarch64-linux-android" => {
 
-                    if header::gdb_version_to_int(version) >
-                        header::gdb_version_to_int("7.4") {
-                        // Add the directory containing the pretty printers to
-                        // GDB's script auto loading safe path
-                        script_str.push_str(
-                            &format!("add-auto-load-safe-path {}\n",
-                                     rust_pp_module_abs_path.replace(r"\", r"\\"))
-                                );
+                cmds = cmds.replace("run", "continue");
+
+                // write debugger script
+                let mut script_str = String::with_capacity(2048);
+                script_str.push_str(&format!("set charset {}\n", Self::charset()));
+                script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
+                script_str.push_str("target remote :5039\n");
+                script_str.push_str(&format!("set solib-search-path \
+                                              ./{}/stage2/lib/rustlib/{}/lib/\n",
+                                             self.config.host, self.config.target));
+                for line in &breakpoint_lines {
+                    script_str.push_str(&format!("break {:?}:{}\n",
+                                                 self.testpaths.file.file_name()
+                                                 .unwrap()
+                                                 .to_string_lossy(),
+                                                 *line)[..]);
+                }
+                script_str.push_str(&cmds);
+                script_str.push_str("\nquit\n");
+
+                debug!("script_str = {}", script_str);
+                self.dump_output_file(&script_str, "debugger.script");
+
+
+                procsrv::run("",
+                             &self.config.adb_path,
+                             None,
+                             &[
+                                 "push".to_owned(),
+                                 exe_file.to_str().unwrap().to_owned(),
+                                 self.config.adb_test_dir.clone()
+                             ],
+                             vec!(("".to_owned(), "".to_owned())),
+                             Some("".to_owned()))
+                    .expect(&format!("failed to exec `{:?}`", self.config.adb_path));
+
+                procsrv::run("",
+                             &self.config.adb_path,
+                             None,
+                             &[
+                                 "forward".to_owned(),
+                                 "tcp:5039".to_owned(),
+                                 "tcp:5039".to_owned()
+                             ],
+                             vec!(("".to_owned(), "".to_owned())),
+                             Some("".to_owned()))
+                    .expect(&format!("failed to exec `{:?}`", self.config.adb_path));
+
+                let adb_arg = format!("export LD_LIBRARY_PATH={}; \
+                                       gdbserver{} :5039 {}/{}",
+                                      self.config.adb_test_dir.clone(),
+                                      if self.config.target.contains("aarch64")
+                                      {"64"} else {""},
+                                      self.config.adb_test_dir.clone(),
+                                      exe_file.file_name().unwrap().to_str()
+                                      .unwrap());
+
+                let mut process = procsrv::run_background("",
+                                                          &self.config.adb_path
+                                                          ,
+                                                          None,
+                                                          &[
+                                                              "shell".to_owned(),
+                                                              adb_arg.clone()
+                                                          ],
+                                                          vec!(("".to_owned(),
+                                                                "".to_owned())),
+                                                          Some("".to_owned()))
+                    .expect(&format!("failed to exec `{:?}`", self.config.adb_path));
+                loop {
+                    //waiting 1 second for gdbserver start
+                    ::std::thread::sleep(::std::time::Duration::new(1,0));
+                    if TcpStream::connect("127.0.0.1:5039").is_ok() {
+                        break
                     }
                 }
-                _ => {
-                    println!("NOTE: compiletest does not know which version of \
-                              GDB it is using");
+
+                let tool_path = match self.config.android_cross_path.to_str() {
+                    Some(x) => x.to_owned(),
+                    None => self.fatal("cannot find android cross path")
+                };
+
+                let debugger_script = self.make_out_name("debugger.script");
+                // FIXME (#9639): This needs to handle non-utf8 paths
+                let debugger_opts =
+                    vec!("-quiet".to_owned(),
+                         "-batch".to_owned(),
+                         "-nx".to_owned(),
+                         format!("-command={}", debugger_script.to_str().unwrap()));
+
+                let mut gdb_path = tool_path;
+                gdb_path.push_str(&format!("/bin/{}-gdb", self.config.target));
+                let procsrv::Result {
+                    out,
+                    err,
+                    status
+                } = procsrv::run("",
+                                 &gdb_path,
+                                 None,
+                                 &debugger_opts,
+                                 vec!(("".to_owned(), "".to_owned())),
+                                 None)
+                    .expect(&format!("failed to exec `{:?}`", gdb_path));
+                let cmdline = {
+                    let cmdline = self.make_cmdline("",
+                                                    &format!("{}-gdb", self.config.target),
+                                                    &debugger_opts);
+                    logv(self.config, format!("executing {}", cmdline));
+                    cmdline
+                };
+
+                debugger_run_result = ProcRes {
+                    status: Status::Normal(status),
+                    stdout: out,
+                    stderr: err,
+                    cmdline: cmdline
+                };
+                if process.kill().is_err() {
+                    println!("Adb process is already finished.");
                 }
             }
 
-            // The following line actually doesn't have to do anything with
-            // pretty printing, it just tells GDB to print values on one line:
-            script_str.push_str("set print pretty off\n");
+            _=> {
+                let rust_src_root = self.find_rust_src_root()
+                                        .expect("Could not find Rust source root");
+                let rust_pp_module_rel_path = Path::new("./src/etc");
+                let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
+                                                           .to_str()
+                                                           .unwrap()
+                                                           .to_owned();
+                // write debugger script
+                let mut script_str = String::with_capacity(2048);
+                script_str.push_str(&format!("set charset {}\n", Self::charset()));
+                script_str.push_str("show version\n");
 
-            // Add the pretty printer directory to GDB's source-file search path
-            script_str.push_str(&format!("directory {}\n",
-                                         rust_pp_module_abs_path));
+                match self.config.gdb_version {
+                    Some(ref version) => {
+                        println!("NOTE: compiletest thinks it is using GDB version {}",
+                                 version);
 
-            // Load the target executable
-            script_str.push_str(&format!("file {}\n",
-                                         exe_file.to_str().unwrap()
-                                                 .replace(r"\", r"\\")));
+                        if header::gdb_version_to_int(version) >
+                            header::gdb_version_to_int("7.4") {
+                                // Add the directory containing the pretty printers to
+                                // GDB's script auto loading safe path
+                                script_str.push_str(
+                                    &format!("add-auto-load-safe-path {}\n",
+                                             rust_pp_module_abs_path.replace(r"\", r"\\"))
+                                );
+                            }
+                    }
+                    _ => {
+                        println!("NOTE: compiletest does not know which version of \
+                                  GDB it is using");
+                    }
+                }
 
-            // Add line breakpoints
-            for line in &breakpoint_lines {
-                script_str.push_str(&format!("break '{}':{}\n",
-                                             testpaths.file.file_name().unwrap()
-                                                     .to_string_lossy(),
-                                             *line));
+                // The following line actually doesn't have to do anything with
+                // pretty printing, it just tells GDB to print values on one line:
+                script_str.push_str("set print pretty off\n");
+
+                // Add the pretty printer directory to GDB's source-file search path
+                script_str.push_str(&format!("directory {}\n",
+                                             rust_pp_module_abs_path));
+
+                // Load the target executable
+                script_str.push_str(&format!("file {}\n",
+                                             exe_file.to_str().unwrap()
+                                             .replace(r"\", r"\\")));
+
+                // Add line breakpoints
+                for line in &breakpoint_lines {
+                    script_str.push_str(&format!("break '{}':{}\n",
+                                                 self.testpaths.file.file_name().unwrap()
+                                                 .to_string_lossy(),
+                                                 *line));
+                }
+
+                script_str.push_str(&cmds);
+                script_str.push_str("\nquit\n");
+
+                debug!("script_str = {}", script_str);
+                self.dump_output_file(&script_str, "debugger.script");
+
+                // run debugger script with gdb
+                fn debugger() -> &'static str {
+                    if cfg!(windows) {"gdb.exe"} else {"gdb"}
+                }
+
+                let debugger_script = self.make_out_name("debugger.script");
+
+                // FIXME (#9639): This needs to handle non-utf8 paths
+                let debugger_opts =
+                    vec!("-quiet".to_owned(),
+                         "-batch".to_owned(),
+                         "-nx".to_owned(),
+                         format!("-command={}", debugger_script.to_str().unwrap()));
+
+                let proc_args = ProcArgs {
+                    prog: debugger().to_owned(),
+                    args: debugger_opts,
+                };
+
+                let environment = vec![("PYTHONPATH".to_owned(), rust_pp_module_abs_path)];
+
+                debugger_run_result =
+                    self.compose_and_run(proc_args,
+                                         environment,
+                                         self.config.run_lib_path.to_str().unwrap(),
+                                         None,
+                                         None);
             }
+        }
 
-            script_str.push_str(&cmds);
-            script_str.push_str("\nquit\n");
+        if !debugger_run_result.status.success() {
+            self.fatal("gdb failed to execute");
+        }
 
-            debug!("script_str = {}", script_str);
-            dump_output_file(config,
-                             testpaths,
-                             &script_str,
-                             "debugger.script");
+        self.check_debugger_output(&debugger_run_result, &check_lines);
+    }
 
-            // run debugger script with gdb
-            fn debugger() -> &'static str {
-                if cfg!(windows) {"gdb.exe"} else {"gdb"}
+    fn find_rust_src_root(&self) -> Option<PathBuf> {
+        let mut path = self.config.src_base.clone();
+        let path_postfix = Path::new("src/etc/lldb_batchmode.py");
+
+        while path.pop() {
+            if path.join(&path_postfix).is_file() {
+                return Some(path);
             }
-
-            let debugger_script = make_out_name(config, testpaths, "debugger.script");
-
-            // FIXME (#9639): This needs to handle non-utf8 paths
-            let debugger_opts =
-                vec!("-quiet".to_owned(),
-                     "-batch".to_owned(),
-                     "-nx".to_owned(),
-                     format!("-command={}", debugger_script.to_str().unwrap()));
-
-            let proc_args = ProcArgs {
-                prog: debugger().to_owned(),
-                args: debugger_opts,
-            };
-
-            let environment = vec![("PYTHONPATH".to_owned(), rust_pp_module_abs_path)];
-
-            debugger_run_result = compose_and_run(config,
-                                                  testpaths,
-                                                  proc_args,
-                                                  environment,
-                                                  config.run_lib_path.to_str().unwrap(),
-                                                  None,
-                                                  None);
         }
+
+        return None;
     }
 
-    if !debugger_run_result.status.success() {
-        fatal(None, "gdb failed to execute");
-    }
+    fn run_debuginfo_lldb_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
 
-    check_debugger_output(&debugger_run_result, &check_lines);
-}
-
-fn find_rust_src_root(config: &Config) -> Option<PathBuf> {
-    let mut path = config.src_base.clone();
-    let path_postfix = Path::new("src/etc/lldb_batchmode.py");
-
-    while path.pop() {
-        if path.join(&path_postfix).is_file() {
-            return Some(path);
+        if self.config.lldb_python_dir.is_none() {
+            self.fatal("Can't run LLDB test because LLDB's python path is not set.");
         }
+
+        let config = Config {
+            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
+            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            .. self.config.clone()
+        };
+
+
+        let test_cx = TestCx {
+            config: &config,
+            ..*self
+        };
+
+        test_cx.run_debuginfo_lldb_test_no_opt();
     }
 
-    return None;
-}
-
-fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    assert!(props.revisions.is_empty(), "revisions not relevant here");
-
-    if config.lldb_python_dir.is_none() {
-        fatal(None, "Can't run LLDB test because LLDB's python path is not set.");
-    }
-
-    let mut config = Config {
-        target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags),
-        host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags),
-        .. config.clone()
-    };
-
-    let config = &mut config;
-
-    // compile test file (it should have 'compile-flags:-g' in the header)
-    let compile_result = compile_test(config, props, testpaths);
-    if !compile_result.status.success() {
-        fatal_proc_rec(None, "compilation failed!", &compile_result);
-    }
-
-    let exe_file = make_exe_name(config, testpaths);
-
-    match config.lldb_version {
-        Some(ref version) => {
-            println!("NOTE: compiletest thinks it is using LLDB version {}",
-                     version);
+    fn run_debuginfo_lldb_test_no_opt(&self) {
+        // compile test file (it should have 'compile-flags:-g' in the header)
+        let compile_result = self.compile_test();
+        if !compile_result.status.success() {
+            self.fatal_proc_rec("compilation failed!", &compile_result);
         }
-        _ => {
-            println!("NOTE: compiletest does not know which version of \
-                      LLDB it is using");
+
+        let exe_file = self.make_exe_name();
+
+        match self.config.lldb_version {
+            Some(ref version) => {
+                println!("NOTE: compiletest thinks it is using LLDB version {}",
+                         version);
+            }
+            _ => {
+                println!("NOTE: compiletest does not know which version of \
+                          LLDB it is using");
+            }
         }
+
+        // Parse debugger commands etc from test files
+        let DebuggerCommands {
+            commands,
+            check_lines,
+            breakpoint_lines,
+            ..
+        } = self.parse_debugger_commands("lldb");
+
+        // Write debugger script:
+        // We don't want to hang when calling `quit` while the process is still running
+        let mut script_str = String::from("settings set auto-confirm true\n");
+
+        // Make LLDB emit its version, so we have it documented in the test output
+        script_str.push_str("version\n");
+
+        // Switch LLDB into "Rust mode"
+        let rust_src_root = self.find_rust_src_root().expect("Could not find Rust source root");
+        let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
+        let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
+                                                   .to_str()
+                                                   .unwrap()
+                                                   .to_owned();
+
+        script_str.push_str(&format!("command script import {}\n",
+                                     &rust_pp_module_abs_path[..])[..]);
+        script_str.push_str("type summary add --no-value ");
+        script_str.push_str("--python-function lldb_rust_formatters.print_val ");
+        script_str.push_str("-x \".*\" --category Rust\n");
+        script_str.push_str("type category enable Rust\n");
+
+        // Set breakpoints on every line that contains the string "#break"
+        let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
+        for line in &breakpoint_lines {
+            script_str.push_str(&format!("breakpoint set --file '{}' --line {}\n",
+                                         source_file_name,
+                                         line));
+        }
+
+        // Append the other commands
+        for line in &commands {
+            script_str.push_str(line);
+            script_str.push_str("\n");
+        }
+
+        // Finally, quit the debugger
+        script_str.push_str("\nquit\n");
+
+        // Write the script into a file
+        debug!("script_str = {}", script_str);
+        self.dump_output_file(&script_str, "debugger.script");
+        let debugger_script = self.make_out_name("debugger.script");
+
+        // Let LLDB execute the script via lldb_batchmode.py
+        let debugger_run_result = self.run_lldb(&exe_file,
+                                                &debugger_script,
+                                                &rust_src_root);
+
+        if !debugger_run_result.status.success() {
+            self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
+        }
+
+        self.check_debugger_output(&debugger_run_result, &check_lines);
     }
 
-    // Parse debugger commands etc from test files
-    let DebuggerCommands {
-        commands,
-        check_lines,
-        breakpoint_lines,
-        ..
-    } = parse_debugger_commands(testpaths, "lldb");
-
-    // Write debugger script:
-    // We don't want to hang when calling `quit` while the process is still running
-    let mut script_str = String::from("settings set auto-confirm true\n");
-
-    // Make LLDB emit its version, so we have it documented in the test output
-    script_str.push_str("version\n");
-
-    // Switch LLDB into "Rust mode"
-    let rust_src_root = find_rust_src_root(config)
-        .expect("Could not find Rust source root");
-    let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
-    let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
-                                               .to_str()
-                                               .unwrap()
-                                               .to_owned();
-
-    script_str.push_str(&format!("command script import {}\n",
-                                 &rust_pp_module_abs_path[..])[..]);
-    script_str.push_str("type summary add --no-value ");
-    script_str.push_str("--python-function lldb_rust_formatters.print_val ");
-    script_str.push_str("-x \".*\" --category Rust\n");
-    script_str.push_str("type category enable Rust\n");
-
-    // Set breakpoints on every line that contains the string "#break"
-    let source_file_name = testpaths.file.file_name().unwrap().to_string_lossy();
-    for line in &breakpoint_lines {
-        script_str.push_str(&format!("breakpoint set --file '{}' --line {}\n",
-                                     source_file_name,
-                                     line));
-    }
-
-    // Append the other commands
-    for line in &commands {
-        script_str.push_str(line);
-        script_str.push_str("\n");
-    }
-
-    // Finally, quit the debugger
-    script_str.push_str("\nquit\n");
-
-    // Write the script into a file
-    debug!("script_str = {}", script_str);
-    dump_output_file(config,
-                     testpaths,
-                     &script_str,
-                     "debugger.script");
-    let debugger_script = make_out_name(config, testpaths, "debugger.script");
-
-    // Let LLDB execute the script via lldb_batchmode.py
-    let debugger_run_result = run_lldb(config,
-                                       testpaths,
-                                       &exe_file,
-                                       &debugger_script,
-                                       &rust_src_root);
-
-    if !debugger_run_result.status.success() {
-        fatal_proc_rec(None, "Error while running LLDB", &debugger_run_result);
-    }
-
-    check_debugger_output(&debugger_run_result, &check_lines);
-
-    fn run_lldb(config: &Config,
-                testpaths: &TestPaths,
+    fn run_lldb(&self,
                 test_executable: &Path,
                 debugger_script: &Path,
                 rust_src_root: &Path)
                 -> ProcRes {
         // Prepare the lldb_batchmode which executes the debugger script
         let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
-        cmd2procres(config,
-                    testpaths,
-                    Command::new(&config.lldb_python)
-                            .arg(&lldb_script_path)
-                            .arg(test_executable)
-                            .arg(debugger_script)
-                            .env("PYTHONPATH",
-                                 config.lldb_python_dir.as_ref().unwrap()))
+        self.cmd2procres(Command::new(&self.config.lldb_python)
+                         .arg(&lldb_script_path)
+                         .arg(test_executable)
+                         .arg(debugger_script)
+                         .env("PYTHONPATH",
+                              self.config.lldb_python_dir.as_ref().unwrap()))
     }
-}
 
-fn cmd2procres(config: &Config, testpaths: &TestPaths, cmd: &mut Command)
-              -> ProcRes {
-    let (status, out, err) = match cmd.output() {
-        Ok(Output { status, stdout, stderr }) => {
-            (status,
-             String::from_utf8(stdout).unwrap(),
-             String::from_utf8(stderr).unwrap())
-        },
-        Err(e) => {
-            fatal(None, &format!("Failed to setup Python process for \
-                            LLDB script: {}", e))
-        }
-    };
-
-    dump_output(config, testpaths, &out, &err);
-    ProcRes {
-        status: Status::Normal(status),
-        stdout: out,
-        stderr: err,
-        cmdline: format!("{:?}", cmd)
-    }
-}
-
-struct DebuggerCommands {
-    commands: Vec<String>,
-    check_lines: Vec<String>,
-    breakpoint_lines: Vec<usize>,
-}
-
-fn parse_debugger_commands(testpaths: &TestPaths, debugger_prefix: &str)
-                           -> DebuggerCommands {
-    let command_directive = format!("{}-command", debugger_prefix);
-    let check_directive = format!("{}-check", debugger_prefix);
-
-    let mut breakpoint_lines = vec!();
-    let mut commands = vec!();
-    let mut check_lines = vec!();
-    let mut counter = 1;
-    let reader = BufReader::new(File::open(&testpaths.file).unwrap());
-    for line in reader.lines() {
-        match line {
-            Ok(line) => {
-                if line.contains("#break") {
-                    breakpoint_lines.push(counter);
-                }
-
-                header::parse_name_value_directive(
-                        &line,
-                        &command_directive).map(|cmd| {
-                    commands.push(cmd)
-                });
-
-                header::parse_name_value_directive(
-                        &line,
-                        &check_directive).map(|cmd| {
-                    check_lines.push(cmd)
-                });
-            }
+    fn cmd2procres(&self, cmd: &mut Command) -> ProcRes {
+        let (status, out, err) = match cmd.output() {
+            Ok(Output { status, stdout, stderr }) => {
+                (status,
+                 String::from_utf8(stdout).unwrap(),
+                 String::from_utf8(stderr).unwrap())
+            },
             Err(e) => {
-                fatal(None, &format!("Error while parsing debugger commands: {}", e))
+                self.fatal(&format!("Failed to setup Python process for \
+                                      LLDB script: {}", e))
             }
-        }
-        counter += 1;
-    }
-
-    DebuggerCommands {
-        commands: commands,
-        check_lines: check_lines,
-        breakpoint_lines: breakpoint_lines,
-    }
-}
-
-fn cleanup_debug_info_options(options: &Option<String>) -> Option<String> {
-    if options.is_none() {
-        return None;
-    }
-
-    // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
-    let options_to_remove = [
-        "-O".to_owned(),
-        "-g".to_owned(),
-        "--debuginfo".to_owned()
-    ];
-    let new_options =
-        split_maybe_args(options).into_iter()
-                                 .filter(|x| !options_to_remove.contains(x))
-                                 .collect::<Vec<String>>();
-
-    Some(new_options.join(" "))
-}
-
-fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) {
-    let num_check_lines = check_lines.len();
-
-    let mut check_line_index = 0;
-    for line in debugger_run_result.stdout.lines() {
-        if check_line_index >= num_check_lines {
-            break;
-        }
-
-        if check_single_line(line, &(check_lines[check_line_index])[..]) {
-            check_line_index += 1;
-        }
-    }
-    if check_line_index != num_check_lines && num_check_lines > 0 {
-        fatal_proc_rec(None, &format!("line not found in debugger output: {}",
-                                check_lines[check_line_index]),
-                      debugger_run_result);
-    }
-
-    fn check_single_line(line: &str, check_line: &str) -> bool {
-        // Allow check lines to leave parts unspecified (e.g., uninitialized
-        // bits in the  wrong case of an enum) with the notation "[...]".
-        let line = line.trim();
-        let check_line = check_line.trim();
-        let can_start_anywhere = check_line.starts_with("[...]");
-        let can_end_anywhere = check_line.ends_with("[...]");
-
-        let check_fragments: Vec<&str> = check_line.split("[...]")
-                                                   .filter(|frag| !frag.is_empty())
-                                                   .collect();
-        if check_fragments.is_empty() {
-            return true;
-        }
-
-        let (mut rest, first_fragment) = if can_start_anywhere {
-            match line.find(check_fragments[0]) {
-                Some(pos) => (&line[pos + check_fragments[0].len() ..], 1),
-                None => return false
-            }
-        } else {
-            (line, 0)
         };
 
-        for fragment_index in first_fragment .. check_fragments.len() {
-            let current_fragment = check_fragments[fragment_index];
-            match rest.find(current_fragment) {
-                Some(pos) => {
-                    rest = &rest[pos + current_fragment.len() .. ];
+        self.dump_output(&out, &err);
+        ProcRes {
+            status: Status::Normal(status),
+            stdout: out,
+            stderr: err,
+            cmdline: format!("{:?}", cmd)
+        }
+    }
+
+    fn parse_debugger_commands(&self, debugger_prefix: &str) -> DebuggerCommands {
+        let command_directive = format!("{}-command", debugger_prefix);
+        let check_directive = format!("{}-check", debugger_prefix);
+
+        let mut breakpoint_lines = vec!();
+        let mut commands = vec!();
+        let mut check_lines = vec!();
+        let mut counter = 1;
+        let reader = BufReader::new(File::open(&self.testpaths.file).unwrap());
+        for line in reader.lines() {
+            match line {
+                Ok(line) => {
+                    if line.contains("#break") {
+                        breakpoint_lines.push(counter);
+                    }
+
+                    header::parse_name_value_directive(
+                        &line,
+                        &command_directive).map(|cmd| {
+                            commands.push(cmd)
+                        });
+
+                    header::parse_name_value_directive(
+                        &line,
+                        &check_directive).map(|cmd| {
+                            check_lines.push(cmd)
+                        });
+                }
+                Err(e) => {
+                    self.fatal(&format!("Error while parsing debugger commands: {}", e))
                 }
-                None => return false
             }
+            counter += 1;
         }
 
-        if !can_end_anywhere && !rest.is_empty() {
-            return false;
+        DebuggerCommands {
+            commands: commands,
+            check_lines: check_lines,
+            breakpoint_lines: breakpoint_lines,
+        }
+    }
+
+    fn cleanup_debug_info_options(&self, options: &Option<String>) -> Option<String> {
+        if options.is_none() {
+            return None;
         }
 
-        return true;
-    }
-}
+        // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
+        let options_to_remove = [
+            "-O".to_owned(),
+            "-g".to_owned(),
+            "--debuginfo".to_owned()
+        ];
+        let new_options =
+            self.split_maybe_args(options).into_iter()
+                                          .filter(|x| !options_to_remove.contains(x))
+                                          .collect::<Vec<String>>();
 
-fn check_error_patterns(revision: Option<&str>,
-                        props: &TestProps,
-                        testpaths: &TestPaths,
-                        output_to_check: &str,
-                        proc_res: &ProcRes) {
-    if props.error_patterns.is_empty() {
-        fatal(revision,
-              &format!("no error pattern specified in {:?}",
-                       testpaths.file.display()));
+        Some(new_options.join(" "))
     }
-    let mut next_err_idx = 0;
-    let mut next_err_pat = props.error_patterns[next_err_idx].trim();
-    let mut done = false;
-    for line in output_to_check.lines() {
-        if line.contains(next_err_pat) {
-            debug!("found error pattern {}", next_err_pat);
-            next_err_idx += 1;
-            if next_err_idx == props.error_patterns.len() {
-                debug!("found all error patterns");
-                done = true;
+
+    fn check_debugger_output(&self, debugger_run_result: &ProcRes, check_lines: &[String]) {
+        let num_check_lines = check_lines.len();
+
+        let mut check_line_index = 0;
+        for line in debugger_run_result.stdout.lines() {
+            if check_line_index >= num_check_lines {
                 break;
             }
-            next_err_pat = props.error_patterns[next_err_idx].trim();
+
+            if check_single_line(line, &(check_lines[check_line_index])[..]) {
+                check_line_index += 1;
+            }
         }
-    }
-    if done { return; }
-
-    let missing_patterns = &props.error_patterns[next_err_idx..];
-    if missing_patterns.len() == 1 {
-        fatal_proc_rec(
-            revision,
-            &format!("error pattern '{}' not found!", missing_patterns[0]),
-            proc_res);
-    } else {
-        for pattern in missing_patterns {
-            error(revision, &format!("error pattern '{}' not found!", *pattern));
+        if check_line_index != num_check_lines && num_check_lines > 0 {
+            self.fatal_proc_rec(&format!("line not found in debugger output: {}",
+                                         check_lines[check_line_index]),
+                                debugger_run_result);
         }
-        fatal_proc_rec(revision, "multiple error patterns not found", proc_res);
-    }
-}
 
-fn check_no_compiler_crash(revision: Option<&str>, proc_res: &ProcRes) {
-    for line in proc_res.stderr.lines() {
-        if line.starts_with("error: internal compiler error:") {
-            fatal_proc_rec(revision,
-                           "compiler encountered internal error",
-                           proc_res);
-        }
-    }
-}
+        fn check_single_line(line: &str, check_line: &str) -> bool {
+            // Allow check lines to leave parts unspecified (e.g., uninitialized
+            // bits in the  wrong case of an enum) with the notation "[...]".
+            let line = line.trim();
+            let check_line = check_line.trim();
+            let can_start_anywhere = check_line.starts_with("[...]");
+            let can_end_anywhere = check_line.ends_with("[...]");
 
-fn check_forbid_output(revision: Option<&str>,
-                       props: &TestProps,
-                       output_to_check: &str,
-                       proc_res: &ProcRes) {
-    for pat in &props.forbid_output {
-        if output_to_check.contains(pat) {
-            fatal_proc_rec(revision,
-                           "forbidden pattern found in compiler output",
-                           proc_res);
-        }
-    }
-}
-
-fn check_expected_errors(revision: Option<&str>,
-                         expected_errors: Vec<errors::Error>,
-                         testpaths: &TestPaths,
-                         proc_res: &ProcRes) {
-    if proc_res.status.success() {
-        fatal_proc_rec(revision, "process did not return an error status", proc_res);
-    }
-
-    let file_name =
-        format!("{}", testpaths.file.display())
-        .replace(r"\", "/"); // on windows, translate all '\' path separators to '/'
-
-    // If the testcase being checked contains at least one expected "help"
-    // message, then we'll ensure that all "help" messages are expected.
-    // Otherwise, all "help" messages reported by the compiler will be ignored.
-    // This logic also applies to "note" messages.
-    let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help));
-    let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note));
-
-    // Parse the JSON output from the compiler and extract out the messages.
-    let actual_errors = json::parse_output(&file_name, &proc_res.stderr);
-    let mut unexpected = 0;
-    let mut not_found = 0;
-    let mut found = vec![false; expected_errors.len()];
-    for actual_error in &actual_errors {
-        let opt_index =
-            expected_errors
-            .iter()
-            .enumerate()
-            .position(|(index, expected_error)| {
-                !found[index] &&
-                    actual_error.line_num == expected_error.line_num &&
-                    (expected_error.kind.is_none() ||
-                     actual_error.kind == expected_error.kind) &&
-                    actual_error.msg.contains(&expected_error.msg)
-            });
-
-        match opt_index {
-            Some(index) => {
-                // found a match, everybody is happy
-                assert!(!found[index]);
-                found[index] = true;
+            let check_fragments: Vec<&str> = check_line.split("[...]")
+                                                       .filter(|frag| !frag.is_empty())
+                                                       .collect();
+            if check_fragments.is_empty() {
+                return true;
             }
 
-            None => {
-                if is_unexpected_compiler_message(actual_error,
-                                                  expect_help,
-                                                  expect_note) {
-                    error(revision,
-                          &format!("{}:{}: unexpected {:?}: '{}'",
-                                   file_name,
-                                   actual_error.line_num,
-                                   actual_error.kind.as_ref()
-                                                    .map_or(String::from("message"),
-                                                            |k| k.to_string()),
-                                   actual_error.msg));
-                    unexpected += 1;
+            let (mut rest, first_fragment) = if can_start_anywhere {
+                match line.find(check_fragments[0]) {
+                    Some(pos) => (&line[pos + check_fragments[0].len() ..], 1),
+                    None => return false
+                }
+            } else {
+                (line, 0)
+            };
+
+            for fragment_index in first_fragment .. check_fragments.len() {
+                let current_fragment = check_fragments[fragment_index];
+                match rest.find(current_fragment) {
+                    Some(pos) => {
+                        rest = &rest[pos + current_fragment.len() .. ];
+                    }
+                    None => return false
+                }
+            }
+
+            if !can_end_anywhere && !rest.is_empty() {
+                return false;
+            }
+
+            return true;
+        }
+    }
+
+    fn check_error_patterns(&self,
+                            output_to_check: &str,
+                            proc_res: &ProcRes) {
+        if self.props.error_patterns.is_empty() {
+            self.fatal(&format!("no error pattern specified in {:?}",
+                                self.testpaths.file.display()));
+        }
+        let mut next_err_idx = 0;
+        let mut next_err_pat = self.props.error_patterns[next_err_idx].trim();
+        let mut done = false;
+        for line in output_to_check.lines() {
+            if line.contains(next_err_pat) {
+                debug!("found error pattern {}", next_err_pat);
+                next_err_idx += 1;
+                if next_err_idx == self.props.error_patterns.len() {
+                    debug!("found all error patterns");
+                    done = true;
+                    break;
+                }
+                next_err_pat = self.props.error_patterns[next_err_idx].trim();
+            }
+        }
+        if done { return; }
+
+        let missing_patterns = &self.props.error_patterns[next_err_idx..];
+        if missing_patterns.len() == 1 {
+            self.fatal_proc_rec(
+                &format!("error pattern '{}' not found!", missing_patterns[0]),
+                proc_res);
+        } else {
+            for pattern in missing_patterns {
+                self.error(&format!("error pattern '{}' not found!", *pattern));
+            }
+            self.fatal_proc_rec("multiple error patterns not found", proc_res);
+        }
+    }
+
+    fn check_no_compiler_crash(&self, proc_res: &ProcRes) {
+        for line in proc_res.stderr.lines() {
+            if line.starts_with("error: internal compiler error:") {
+                self.fatal_proc_rec("compiler encountered internal error", proc_res);
+            }
+        }
+    }
+
+    fn check_forbid_output(&self,
+                           output_to_check: &str,
+                           proc_res: &ProcRes) {
+        for pat in &self.props.forbid_output {
+            if output_to_check.contains(pat) {
+                self.fatal_proc_rec("forbidden pattern found in compiler output", proc_res);
+            }
+        }
+    }
+
+    fn check_expected_errors(&self,
+                             expected_errors: Vec<errors::Error>,
+                             proc_res: &ProcRes) {
+        if proc_res.status.success() {
+            self.fatal_proc_rec("process did not return an error status", proc_res);
+        }
+
+        let file_name =
+            format!("{}", self.testpaths.file.display())
+            .replace(r"\", "/"); // on windows, translate all '\' path separators to '/'
+
+        // If the testcase being checked contains at least one expected "help"
+        // message, then we'll ensure that all "help" messages are expected.
+        // Otherwise, all "help" messages reported by the compiler will be ignored.
+        // This logic also applies to "note" messages.
+        let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help));
+        let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note));
+
+        // Parse the JSON output from the compiler and extract out the messages.
+        let actual_errors = json::parse_output(&file_name, &proc_res.stderr);
+        let mut unexpected = 0;
+        let mut not_found = 0;
+        let mut found = vec![false; expected_errors.len()];
+        for actual_error in &actual_errors {
+            let opt_index =
+                expected_errors
+                .iter()
+                .enumerate()
+                .position(|(index, expected_error)| {
+                    !found[index] &&
+                        actual_error.line_num == expected_error.line_num &&
+                        (expected_error.kind.is_none() ||
+                         actual_error.kind == expected_error.kind) &&
+                        actual_error.msg.contains(&expected_error.msg)
+                });
+
+            match opt_index {
+                Some(index) => {
+                    // found a match, everybody is happy
+                    assert!(!found[index]);
+                    found[index] = true;
+                }
+
+                None => {
+                    if self.is_unexpected_compiler_message(actual_error, expect_help, expect_note) {
+                        self.error(
+                            &format!("{}:{}: unexpected {:?}: '{}'",
+                                     file_name,
+                                     actual_error.line_num,
+                                     actual_error.kind.as_ref()
+                                     .map_or(String::from("message"),
+                                             |k| k.to_string()),
+                                     actual_error.msg));
+                        unexpected += 1;
+                    }
+                }
+            }
+        }
+
+        // anything not yet found is a problem
+        for (index, expected_error) in expected_errors.iter().enumerate() {
+            if !found[index] {
+                self.error(
+                    &format!("{}:{}: expected {} not found: {}",
+                             file_name,
+                             expected_error.line_num,
+                             expected_error.kind.as_ref()
+                             .map_or("message".into(),
+                                     |k| k.to_string()),
+                             expected_error.msg));
+                not_found += 1;
+            }
+        }
+
+        if unexpected > 0 || not_found > 0 {
+            self.error(
+                &format!("{} unexpected errors found, {} expected errors not found",
+                         unexpected, not_found));
+            print!("status: {}\ncommand: {}\n",
+                   proc_res.status, proc_res.cmdline);
+            println!("actual errors (from JSON output): {:#?}\n", actual_errors);
+            println!("expected errors (from test file): {:#?}\n", expected_errors);
+            panic!();
+        }
+    }
+
+    /// Returns true if we should report an error about `actual_error`,
+    /// which did not match any of the expected error. We always require
+    /// errors/warnings to be explicitly listed, but only require
+    /// helps/notes if there are explicit helps/notes given.
+    fn is_unexpected_compiler_message(&self,
+                                      actual_error: &Error,
+                                      expect_help: bool,
+                                      expect_note: bool)
+                                      -> bool {
+        match actual_error.kind {
+            Some(ErrorKind::Help) => expect_help,
+            Some(ErrorKind::Note) => expect_note,
+            Some(ErrorKind::Error) => true,
+            Some(ErrorKind::Warning) => true,
+            Some(ErrorKind::Suggestion) => false,
+            None => false
+        }
+    }
+
+    fn compile_test(&self) -> ProcRes {
+        let aux_dir = self.aux_output_dir_name();
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        let link_args = vec!("-L".to_owned(),
+                             aux_dir.to_str().unwrap().to_owned());
+        let args = self.make_compile_args(link_args,
+                                          &self.testpaths.file,
+                                          TargetLocation::ThisFile(self.make_exe_name()));
+        self.compose_and_run_compiler(args, None)
+    }
+
+    fn document(&self, out_dir: &Path) -> ProcRes {
+        if self.props.build_aux_docs {
+            for rel_ab in &self.props.aux_builds {
+                let aux_testpaths = self.compute_aux_test_paths(rel_ab);
+                let aux_props = TestProps::from_file(&aux_testpaths.file);
+                let aux_cx = TestCx {
+                    config: self.config,
+                    props: &aux_props,
+                    testpaths: &aux_testpaths,
+                    revision: self.revision
+                };
+                let auxres = aux_cx.document(out_dir);
+                if !auxres.status.success() {
+                    return auxres;
+                }
+            }
+        }
+
+        let aux_dir = self.aux_output_dir_name();
+        let mut args = vec!["-L".to_owned(),
+                            aux_dir.to_str().unwrap().to_owned(),
+                            "-o".to_owned(),
+                            out_dir.to_str().unwrap().to_owned(),
+                            self.testpaths.file.to_str().unwrap().to_owned()];
+        args.extend(self.props.compile_flags.iter().cloned());
+        let args = ProcArgs {
+            prog: self.config.rustdoc_path.to_str().unwrap().to_owned(),
+            args: args,
+        };
+        self.compose_and_run_compiler(args, None)
+    }
+
+    fn exec_compiled_test(&self) -> ProcRes {
+        let env = self.props.exec_env.clone();
+
+        match &*self.config.target {
+
+            "arm-linux-androideabi" | "aarch64-linux-android" => {
+                self._arm_exec_compiled_test(env)
+            }
+
+            _=> {
+                let aux_dir = self.aux_output_dir_name();
+                self.compose_and_run(self.make_run_args(),
+                                     env,
+                                     self.config.run_lib_path.to_str().unwrap(),
+                                     Some(aux_dir.to_str().unwrap()),
+                                     None)
+            }
+        }
+    }
+
+    /// For each `aux-build: foo/bar` annotation, we check to find the
+    /// file in a `aux` directory relative to the test itself.
+    fn compute_aux_test_paths(&self, rel_ab: &str) -> TestPaths {
+        let test_ab = self.testpaths.file
+                                    .parent()
+                                    .expect("test file path has no parent")
+                                    .join("auxiliary")
+                                    .join(rel_ab);
+        if !test_ab.exists() {
+            self.fatal(&format!("aux-build `{}` source not found", test_ab.display()))
+        }
+
+        TestPaths {
+            file: test_ab,
+            base: self.testpaths.base.clone(),
+            relative_dir: self.testpaths.relative_dir
+                                        .join("auxiliary")
+                                        .join(rel_ab)
+                                        .parent()
+                                        .expect("aux-build path has no parent")
+                                        .to_path_buf()
+        }
+    }
+
+    fn compose_and_run_compiler(&self, args: ProcArgs, input: Option<String>) -> ProcRes {
+        if !self.props.aux_builds.is_empty() {
+            self.create_dir_racy(&self.aux_output_dir_name());
+        }
+
+        let aux_dir = self.aux_output_dir_name();
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        let extra_link_args = vec!["-L".to_owned(),
+                                   aux_dir.to_str().unwrap().to_owned()];
+
+        for rel_ab in &self.props.aux_builds {
+            let aux_testpaths = self.compute_aux_test_paths(rel_ab);
+            let aux_props = TestProps::from_file(&aux_testpaths.file);
+            let mut crate_type = if aux_props.no_prefer_dynamic {
+                Vec::new()
+            } else {
+                // We primarily compile all auxiliary libraries as dynamic libraries
+                // to avoid code size bloat and large binaries as much as possible
+                // for the test suite (otherwise including libstd statically in all
+                // executables takes up quite a bit of space).
+                //
+                // For targets like MUSL or Emscripten, however, there is no support for
+                // dynamic libraries so we just go back to building a normal library. Note,
+                // however, that for MUSL if the library is built with `force_host` then
+                // it's ok to be a dylib as the host should always support dylibs.
+                if (self.config.target.contains("musl") && !aux_props.force_host) ||
+                    self.config.target.contains("emscripten")
+                {
+                    vec!("--crate-type=lib".to_owned())
+                } else {
+                    vec!("--crate-type=dylib".to_owned())
+                }
+            };
+            crate_type.extend(extra_link_args.clone());
+            let aux_output = {
+                let f = self.make_lib_name(&self.testpaths.file);
+                let parent = f.parent().unwrap();
+                TargetLocation::ThisDirectory(parent.to_path_buf())
+            };
+            let aux_cx = TestCx {
+                config: self.config,
+                props: &aux_props,
+                testpaths: &aux_testpaths,
+                revision: self.revision
+            };
+            let aux_args = aux_cx.make_compile_args(crate_type, &aux_testpaths.file, aux_output);
+            let auxres = aux_cx.compose_and_run(aux_args,
+                                                Vec::new(),
+                                                aux_cx.config.compile_lib_path.to_str().unwrap(),
+                                                Some(aux_dir.to_str().unwrap()),
+                                                None);
+            if !auxres.status.success() {
+                self.fatal_proc_rec(
+                    &format!("auxiliary build of {:?} failed to compile: ",
+                             aux_testpaths.file.display()),
+                    &auxres);
+            }
+
+            match &*self.config.target {
+                "arm-linux-androideabi"  | "aarch64-linux-android" => {
+                    self._arm_push_aux_shared_library();
+                }
+                _ => {}
+            }
+        }
+
+        self.compose_and_run(args,
+                             self.props.rustc_env.clone(),
+                             self.config.compile_lib_path.to_str().unwrap(),
+                             Some(aux_dir.to_str().unwrap()),
+                             input)
+    }
+
+    // Like std::fs::create_dir_all, except handles concurrent calls among multiple
+    // threads or processes.
+    fn create_dir_racy(&self, path: &Path) {
+        match fs::create_dir(path) {
+            Ok(()) => return,
+            Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return,
+            Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
+            Err(e) => panic!("failed to create dir {:?}: {}", path, e),
+        }
+        self.create_dir_racy(path.parent().unwrap());
+        match fs::create_dir(path) {
+            Ok(()) => {}
+            Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => {}
+            Err(e) => panic!("failed to create dir {:?}: {}", path, e),
+        }
+    }
+
+    fn compose_and_run(&self,
+                       ProcArgs{ args, prog }: ProcArgs,
+                       procenv: Vec<(String, String)> ,
+                       lib_path: &str,
+                       aux_path: Option<&str>,
+                       input: Option<String>) -> ProcRes {
+        return self.program_output(lib_path, prog, aux_path, args, procenv, input);
+    }
+
+    fn make_compile_args(&self,
+                         extras: Vec<String> ,
+                         input_file: &Path,
+                         output_file: TargetLocation)
+                         -> ProcArgs
+    {
+        let target = if self.props.force_host {
+            &*self.config.host
+        } else {
+            &*self.config.target
+        };
+
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        let mut args = vec!(input_file.to_str().unwrap().to_owned(),
+                            "-L".to_owned(),
+                            self.config.build_base.to_str().unwrap().to_owned(),
+                            format!("--target={}", target));
+
+        match self.config.mode {
+            CompileFail |
+            ParseFail |
+            Incremental => {
+                // If we are extracting and matching errors in the new
+                // fashion, then you want JSON mode. Old-skool error
+                // patterns still match the raw compiler output.
+                if self.props.error_patterns.is_empty() {
+                    args.extend(["--error-format",
+                                 "json",
+                                 "-Z",
+                                 "unstable-options"]
+                                .iter()
+                                .map(|s| s.to_string()));
+                }
+            }
+
+            RunFail |
+            RunPass |
+            RunPassValgrind |
+            Pretty |
+            DebugInfoGdb |
+            DebugInfoLldb |
+            Codegen |
+            Rustdoc |
+            RunMake |
+            CodegenUnits => {
+                // do not use JSON output
+            }
+        }
+
+        args.extend_from_slice(&extras);
+        if !self.props.no_prefer_dynamic {
+            args.push("-C".to_owned());
+            args.push("prefer-dynamic".to_owned());
+        }
+        let path = match output_file {
+            TargetLocation::ThisFile(path) => {
+                args.push("-o".to_owned());
+                path
+            }
+            TargetLocation::ThisDirectory(path) => {
+                args.push("--out-dir".to_owned());
+                path
+            }
+        };
+        args.push(path.to_str().unwrap().to_owned());
+        if self.props.force_host {
+            args.extend(self.split_maybe_args(&self.config.host_rustcflags));
+        } else {
+            args.extend(self.split_maybe_args(&self.config.target_rustcflags));
+        }
+        args.extend(self.props.compile_flags.iter().cloned());
+        return ProcArgs {
+            prog: self.config.rustc_path.to_str().unwrap().to_owned(),
+            args: args,
+        };
+    }
+
+    fn make_lib_name(&self, auxfile: &Path) -> PathBuf {
+        // what we return here is not particularly important, as it
+        // happens; rustc ignores everything except for the directory.
+        let auxname = self.output_testname(auxfile);
+        self.aux_output_dir_name().join(&auxname)
+    }
+
+    fn make_exe_name(&self) -> PathBuf {
+        let mut f = self.output_base_name();
+        // FIXME: This is using the host architecture exe suffix, not target!
+        if self.config.target == "asmjs-unknown-emscripten" {
+            let mut fname = f.file_name().unwrap().to_os_string();
+            fname.push(".js");
+            f.set_file_name(&fname);
+        } else if !env::consts::EXE_SUFFIX.is_empty() {
+            let mut fname = f.file_name().unwrap().to_os_string();
+            fname.push(env::consts::EXE_SUFFIX);
+            f.set_file_name(&fname);
+        }
+        f
+    }
+
+    fn make_run_args(&self) -> ProcArgs {
+        // If we've got another tool to run under (valgrind),
+        // then split apart its command
+        let mut args = self.split_maybe_args(&self.config.runtool);
+
+        // If this is emscripten, then run tests under nodejs
+        if self.config.target == "asmjs-unknown-emscripten" {
+            args.push("nodejs".to_owned());
+        }
+
+        let exe_file = self.make_exe_name();
+
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        args.push(exe_file.to_str().unwrap().to_owned());
+
+        // Add the arguments in the run_flags directive
+        args.extend(self.split_maybe_args(&self.props.run_flags));
+
+        let prog = args.remove(0);
+        return ProcArgs {
+            prog: prog,
+            args: args,
+        };
+    }
+
+    fn split_maybe_args(&self, argstr: &Option<String>) -> Vec<String> {
+        match *argstr {
+            Some(ref s) => {
+                s
+                    .split(' ')
+                    .filter_map(|s| {
+                        if s.chars().all(|c| c.is_whitespace()) {
+                            None
+                        } else {
+                            Some(s.to_owned())
+                        }
+                    }).collect()
+            }
+            None => Vec::new()
+        }
+    }
+
+    fn program_output(&self,
+                      lib_path: &str,
+                      prog: String,
+                      aux_path: Option<&str>,
+                      args: Vec<String>,
+                      env: Vec<(String, String)>,
+                      input: Option<String>)
+                      -> ProcRes {
+        let cmdline =
+        {
+            let cmdline = self.make_cmdline(lib_path,
+                                            &prog,
+                                            &args);
+            logv(self.config, format!("executing {}", cmdline));
+            cmdline
+        };
+        let procsrv::Result {
+            out,
+            err,
+            status
+        } = procsrv::run(lib_path,
+                         &prog,
+                         aux_path,
+                         &args,
+                         env,
+                         input).expect(&format!("failed to exec `{}`", prog));
+        self.dump_output(&out, &err);
+        return ProcRes {
+            status: Status::Normal(status),
+            stdout: out,
+            stderr: err,
+            cmdline: cmdline,
+        };
+    }
+
+    fn make_cmdline(&self, libpath: &str, prog: &str, args: &[String]) -> String {
+        use util;
+
+        // Linux and mac don't require adjusting the library search path
+        if cfg!(unix) {
+            format!("{} {}", prog, args.join(" "))
+        } else {
+            // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
+            // for diagnostic purposes
+            fn lib_path_cmd_prefix(path: &str) -> String {
+                format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
+            }
+
+            format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.join(" "))
+        }
+    }
+
+    fn dump_output(&self, out: &str, err: &str) {
+        self.dump_output_file(out, "out");
+        self.dump_output_file(err, "err");
+        self.maybe_dump_to_stdout(out, err);
+    }
+
+    fn dump_output_file(&self,
+                        out: &str,
+                        extension: &str) {
+        let outfile = self.make_out_name(extension);
+        File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
+    }
+
+    fn make_out_name(&self, extension: &str) -> PathBuf {
+        self.output_base_name().with_extension(extension)
+    }
+
+    fn aux_output_dir_name(&self) -> PathBuf {
+        let f = self.output_base_name();
+        let mut fname = f.file_name().unwrap().to_os_string();
+        fname.push(&format!(".{}.libaux", self.config.mode));
+        f.with_file_name(&fname)
+    }
+
+    fn output_testname(&self, filepath: &Path) -> PathBuf {
+        PathBuf::from(filepath.file_stem().unwrap())
+    }
+
+    /// Given a test path like `compile-fail/foo/bar.rs` Returns a name like
+    ///
+    ///     <output>/foo/bar-stage1
+    fn output_base_name(&self) -> PathBuf {
+        let dir = self.config.build_base.join(&self.testpaths.relative_dir);
+
+        // Note: The directory `dir` is created during `collect_tests_from_dir`
+        dir
+            .join(&self.output_testname(&self.testpaths.file))
+            .with_extension(&self.config.stage_id)
+    }
+
+    fn maybe_dump_to_stdout(&self, out: &str, err: &str) {
+        if self.config.verbose {
+            println!("------{}------------------------------", "stdout");
+            println!("{}", out);
+            println!("------{}------------------------------", "stderr");
+            println!("{}", err);
+            println!("------------------------------------------");
+        }
+    }
+
+    fn error(&self, err: &str) {
+        match self.revision {
+            Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
+            None => println!("\nerror: {}", err)
+        }
+    }
+
+    fn fatal(&self, err: &str) -> ! {
+        self.error(err); panic!();
+    }
+
+    fn fatal_proc_rec(&self, err: &str, proc_res: &ProcRes) -> ! {
+        self.error(err);
+        print!("\
+            status: {}\n\
+            command: {}\n\
+            stdout:\n\
+            ------------------------------------------\n\
+            {}\n\
+            ------------------------------------------\n\
+            stderr:\n\
+            ------------------------------------------\n\
+            {}\n\
+            ------------------------------------------\n\
+            \n",
+               proc_res.status, proc_res.cmdline, proc_res.stdout,
+               proc_res.stderr);
+        panic!();
+    }
+
+    fn _arm_exec_compiled_test(&self, env: Vec<(String, String)>) -> ProcRes {
+        let args = self.make_run_args();
+        let cmdline = self.make_cmdline("", &args.prog, &args.args);
+
+        // get bare program string
+        let mut tvec: Vec<String> = args.prog
+                                        .split('/')
+                                        .map(str::to_owned)
+                                        .collect();
+        let prog_short = tvec.pop().unwrap();
+
+        // copy to target
+        let copy_result = procsrv::run("",
+                                       &self.config.adb_path,
+                                       None,
+                                       &[
+                                           "push".to_owned(),
+                                           args.prog.clone(),
+                                           self.config.adb_test_dir.clone()
+                                       ],
+                                       vec!(("".to_owned(), "".to_owned())),
+                                       Some("".to_owned()))
+            .expect(&format!("failed to exec `{}`", self.config.adb_path));
+
+        if self.config.verbose {
+            println!("push ({}) {} {} {}",
+                     self.config.target,
+                     args.prog,
+                     copy_result.out,
+                     copy_result.err);
+        }
+
+        logv(self.config, format!("executing ({}) {}", self.config.target, cmdline));
+
+        let mut runargs = Vec::new();
+
+        // run test via adb_run_wrapper
+        runargs.push("shell".to_owned());
+        for (key, val) in env {
+            runargs.push(format!("{}={}", key, val));
+        }
+        runargs.push(format!("{}/../adb_run_wrapper.sh", self.config.adb_test_dir));
+        runargs.push(format!("{}", self.config.adb_test_dir));
+        runargs.push(format!("{}", prog_short));
+
+        for tv in &args.args {
+            runargs.push(tv.to_owned());
+        }
+        procsrv::run("",
+                     &self.config.adb_path,
+                     None,
+                     &runargs,
+                     vec!(("".to_owned(), "".to_owned())), Some("".to_owned()))
+            .expect(&format!("failed to exec `{}`", self.config.adb_path));
+
+        // get exitcode of result
+        runargs = Vec::new();
+        runargs.push("shell".to_owned());
+        runargs.push("cat".to_owned());
+        runargs.push(format!("{}/{}.exitcode", self.config.adb_test_dir, prog_short));
+
+        let procsrv::Result{ out: exitcode_out, err: _, status: _ } =
+            procsrv::run("",
+                         &self.config.adb_path,
+                         None,
+                         &runargs,
+                         vec!(("".to_owned(), "".to_owned())),
+                         Some("".to_owned()))
+            .expect(&format!("failed to exec `{}`", self.config.adb_path));
+
+        let mut exitcode: i32 = 0;
+        for c in exitcode_out.chars() {
+            if !c.is_numeric() { break; }
+            exitcode = exitcode * 10 + match c {
+                '0' ... '9' => c as i32 - ('0' as i32),
+                _ => 101,
+            }
+        }
+
+        // get stdout of result
+        runargs = Vec::new();
+        runargs.push("shell".to_owned());
+        runargs.push("cat".to_owned());
+        runargs.push(format!("{}/{}.stdout", self.config.adb_test_dir, prog_short));
+
+        let procsrv::Result{ out: stdout_out, err: _, status: _ } =
+            procsrv::run("",
+                         &self.config.adb_path,
+                         None,
+                         &runargs,
+                         vec!(("".to_owned(), "".to_owned())),
+                         Some("".to_owned()))
+            .expect(&format!("failed to exec `{}`", self.config.adb_path));
+
+        // get stderr of result
+        runargs = Vec::new();
+        runargs.push("shell".to_owned());
+        runargs.push("cat".to_owned());
+        runargs.push(format!("{}/{}.stderr", self.config.adb_test_dir, prog_short));
+
+        let procsrv::Result{ out: stderr_out, err: _, status: _ } =
+            procsrv::run("",
+                         &self.config.adb_path,
+                         None,
+                         &runargs,
+                         vec!(("".to_owned(), "".to_owned())),
+                         Some("".to_owned()))
+            .expect(&format!("failed to exec `{}`", self.config.adb_path));
+
+        self.dump_output(&stdout_out, &stderr_out);
+
+        ProcRes {
+            status: Status::Parsed(exitcode),
+            stdout: stdout_out,
+            stderr: stderr_out,
+            cmdline: cmdline
+        }
+    }
+
+    fn _arm_push_aux_shared_library(&self) {
+        let tdir = self.aux_output_dir_name();
+
+        let dirs = fs::read_dir(&tdir).unwrap();
+        for file in dirs {
+            let file = file.unwrap().path();
+            if file.extension().and_then(|s| s.to_str()) == Some("so") {
+                // FIXME (#9639): This needs to handle non-utf8 paths
+                let copy_result = procsrv::run("",
+                                               &self.config.adb_path,
+                                               None,
+                                               &[
+                                                   "push".to_owned(),
+                                                   file.to_str()
+                                                       .unwrap()
+                                                       .to_owned(),
+                                                   self.config.adb_test_dir.to_owned(),
+                                               ],
+                                               vec!(("".to_owned(),
+                                                     "".to_owned())),
+                                               Some("".to_owned()))
+                    .expect(&format!("failed to exec `{}`", self.config.adb_path));
+
+                if self.config.verbose {
+                    println!("push ({}) {:?} {} {}",
+                             self.config.target, file.display(),
+                             copy_result.out, copy_result.err);
                 }
             }
         }
     }
 
-    // anything not yet found is a problem
-    for (index, expected_error) in expected_errors.iter().enumerate() {
-        if !found[index] {
-            error(revision,
-                  &format!("{}:{}: expected {} not found: {}",
-                           file_name,
-                           expected_error.line_num,
-                           expected_error.kind.as_ref()
-                                              .map_or("message".into(),
-                                                      |k| k.to_string()),
-                           expected_error.msg));
-            not_found += 1;
+    // codegen tests (using FileCheck)
+
+    fn compile_test_and_save_ir(&self) -> ProcRes {
+        let aux_dir = self.aux_output_dir_name();
+        // FIXME (#9639): This needs to handle non-utf8 paths
+        let mut link_args = vec!("-L".to_owned(),
+                                 aux_dir.to_str().unwrap().to_owned());
+        let llvm_args = vec!("--emit=llvm-ir".to_owned(),);
+        link_args.extend(llvm_args);
+        let args = self.make_compile_args(link_args,
+                                          &self.testpaths.file,
+                                          TargetLocation::ThisDirectory(
+                                              self.output_base_name().parent()
+                                                                     .unwrap()
+                                                                     .to_path_buf()));
+        self.compose_and_run_compiler(args, None)
+    }
+
+    fn check_ir_with_filecheck(&self) -> ProcRes {
+        let irfile = self.output_base_name().with_extension("ll");
+        let prog = self.config.llvm_filecheck.as_ref().unwrap();
+        let proc_args = ProcArgs {
+            // FIXME (#9639): This needs to handle non-utf8 paths
+            prog: prog.to_str().unwrap().to_owned(),
+            args: vec!(format!("-input-file={}", irfile.to_str().unwrap()),
+                       self.testpaths.file.to_str().unwrap().to_owned())
+        };
+        self.compose_and_run(proc_args, Vec::new(), "", None, None)
+    }
+
+    fn run_codegen_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        if self.config.llvm_filecheck.is_none() {
+            self.fatal("missing --llvm-filecheck");
+        }
+
+        let mut proc_res = self.compile_test_and_save_ir();
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        proc_res = self.check_ir_with_filecheck();
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
         }
     }
 
-    if unexpected > 0 || not_found > 0 {
-        error(revision,
-              &format!("{} unexpected errors found, {} expected errors not found",
-                       unexpected, not_found));
-        print!("status: {}\ncommand: {}\n",
-               proc_res.status, proc_res.cmdline);
-        println!("actual errors (from JSON output): {:#?}\n", actual_errors);
-        println!("expected errors (from test file): {:#?}\n", expected_errors);
-        panic!();
+    fn charset() -> &'static str {
+        // FreeBSD 10.1 defaults to GDB 6.1.1 which doesn't support "auto" charset
+        if cfg!(target_os = "bitrig") {
+            "auto"
+        } else if cfg!(target_os = "freebsd") {
+            "ISO-8859-1"
+        } else {
+            "UTF-8"
+        }
     }
-}
 
-/// Returns true if we should report an error about `actual_error`,
-/// which did not match any of the expected error. We always require
-/// errors/warnings to be explicitly listed, but only require
-/// helps/notes if there are explicit helps/notes given.
-fn is_unexpected_compiler_message(actual_error: &Error,
-                                  expect_help: bool,
-                                  expect_note: bool)
-                                  -> bool {
-    match actual_error.kind {
-        Some(ErrorKind::Help) => expect_help,
-        Some(ErrorKind::Note) => expect_note,
-        Some(ErrorKind::Error) => true,
-        Some(ErrorKind::Warning) => true,
-        Some(ErrorKind::Suggestion) => false,
-        None => false
+    fn run_rustdoc_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        let out_dir = self.output_base_name();
+        let _ = fs::remove_dir_all(&out_dir);
+        self.create_dir_racy(&out_dir);
+
+        let proc_res = self.document(&out_dir);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("rustdoc failed!", &proc_res);
+        }
+        let root = self.find_rust_src_root().unwrap();
+
+        let res = self.cmd2procres(Command::new(&self.config.docck_python)
+                                   .arg(root.join("src/etc/htmldocck.py"))
+                                   .arg(out_dir)
+                                   .arg(&self.testpaths.file));
+        if !res.status.success() {
+            self.fatal_proc_rec("htmldocck failed!", &res);
+        }
+    }
+
+    fn run_codegen_units_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        let proc_res = self.compile_test();
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        self.check_no_compiler_crash(&proc_res);
+
+        const PREFIX: &'static str = "TRANS_ITEM ";
+        const CGU_MARKER: &'static str = "@@";
+
+        let actual: Vec<TransItem> = proc_res
+            .stdout
+            .lines()
+            .filter(|line| line.starts_with(PREFIX))
+            .map(str_to_trans_item)
+            .collect();
+
+        let expected: Vec<TransItem> = errors::load_errors(&self.testpaths.file, None)
+            .iter()
+            .map(|e| str_to_trans_item(&e.msg[..]))
+            .collect();
+
+        let mut missing = Vec::new();
+        let mut wrong_cgus = Vec::new();
+
+        for expected_item in &expected {
+            let actual_item_with_same_name = actual.iter()
+                                                   .find(|ti| ti.name == expected_item.name);
+
+            if let Some(actual_item) = actual_item_with_same_name {
+                if !expected_item.codegen_units.is_empty() {
+                    // Also check for codegen units
+                    if expected_item.codegen_units != actual_item.codegen_units {
+                        wrong_cgus.push((expected_item.clone(), actual_item.clone()));
+                    }
+                }
+            } else {
+                missing.push(expected_item.string.clone());
+            }
+        }
+
+        let unexpected: Vec<_> =
+            actual.iter()
+                  .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name))
+                  .map(|acgu| acgu.string.clone())
+                  .collect();
+
+        if !missing.is_empty() {
+            missing.sort();
+
+            println!("\nThese items should have been contained but were not:\n");
+
+            for item in &missing {
+                println!("{}", item);
+            }
+
+            println!("\n");
+        }
+
+        if !unexpected.is_empty() {
+            let sorted = {
+                let mut sorted = unexpected.clone();
+                sorted.sort();
+                sorted
+            };
+
+            println!("\nThese items were contained but should not have been:\n");
+
+            for item in sorted {
+                println!("{}", item);
+            }
+
+            println!("\n");
+        }
+
+        if !wrong_cgus.is_empty() {
+            wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
+            println!("\nThe following items were assigned to wrong codegen units:\n");
+
+            for &(ref expected_item, ref actual_item) in &wrong_cgus {
+                println!("{}", expected_item.name);
+                println!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
+                println!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
+                println!("");
+            }
+        }
+
+        if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty())
+        {
+            panic!();
+        }
+
+        #[derive(Clone, Eq, PartialEq)]
+        struct TransItem {
+            name: String,
+            codegen_units: HashSet<String>,
+            string: String,
+        }
+
+        // [TRANS_ITEM] name [@@ (cgu)+]
+        fn str_to_trans_item(s: &str) -> TransItem {
+            let s = if s.starts_with(PREFIX) {
+                (&s[PREFIX.len()..]).trim()
+            } else {
+                s.trim()
+            };
+
+            let full_string = format!("{}{}", PREFIX, s.trim().to_owned());
+
+            let parts: Vec<&str> = s.split(CGU_MARKER)
+                                    .map(str::trim)
+                                    .filter(|s| !s.is_empty())
+                                    .collect();
+
+            let name = parts[0].trim();
+
+            let cgus = if parts.len() > 1 {
+                let cgus_str = parts[1];
+
+                cgus_str.split(" ")
+                        .map(str::trim)
+                        .filter(|s| !s.is_empty())
+                        .map(str::to_owned)
+                        .collect()
+            }
+            else {
+                HashSet::new()
+            };
+
+            TransItem {
+                name: name.to_owned(),
+                codegen_units: cgus,
+                string: full_string,
+            }
+        }
+
+        fn codegen_units_to_str(cgus: &HashSet<String>) -> String
+        {
+            let mut cgus: Vec<_> = cgus.iter().collect();
+            cgus.sort();
+
+            let mut string = String::new();
+            for cgu in cgus {
+                string.push_str(&cgu[..]);
+                string.push_str(" ");
+            }
+
+            string
+        }
+    }
+
+    fn init_incremental_test(&self) {
+        // (See `run_incremental_test` for an overview of how incremental tests work.)
+
+        // Before any of the revisions have executed, create the
+        // incremental workproduct directory.  Delete any old
+        // incremental work products that may be there from prior
+        // runs.
+        let incremental_dir = self.incremental_dir();
+        if incremental_dir.exists() {
+            fs::remove_dir_all(&incremental_dir).unwrap();
+        }
+        fs::create_dir_all(&incremental_dir).unwrap();
+
+        if self.config.verbose {
+            print!("init_incremental_test: incremental_dir={}", incremental_dir.display());
+        }
+    }
+
+    fn run_incremental_test(&self) {
+        // Basic plan for a test incremental/foo/bar.rs:
+        // - load list of revisions rpass1, cfail2, rpass3
+        //   - each should begin with `rpass`, `cfail`, or `cfail`
+        //   - if `rpass`, expect compile and execution to succeed
+        //   - if `cfail`, expect compilation to fail
+        //   - if `rfail`, expect execution to fail
+        // - create a directory build/foo/bar.incremental
+        // - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C rpass1
+        //   - because name of revision starts with "rpass", expect success
+        // - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C cfail2
+        //   - because name of revision starts with "cfail", expect an error
+        //   - load expected errors as usual, but filter for those that end in `[rfail2]`
+        // - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C rpass3
+        //   - because name of revision starts with "rpass", expect success
+        // - execute build/foo/bar.exe and save output
+        //
+        // FIXME -- use non-incremental mode as an oracle? That doesn't apply
+        // to #[rustc_dirty] and clean tests I guess
+
+        let revision = self.revision.expect("incremental tests require a list of revisions");
+
+        // Incremental workproduct directory should have already been created.
+        let incremental_dir = self.incremental_dir();
+        assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
+
+        // Add an extra flag pointing at the incremental directory.
+        let mut revision_props = self.props.clone();
+        revision_props.compile_flags.extend(vec![
+            format!("-Z"),
+            format!("incremental={}", incremental_dir.display()),
+        ]);
+
+        let revision_cx = TestCx {
+            config: self.config,
+            props: &revision_props,
+            testpaths: self.testpaths,
+            revision: self.revision,
+        };
+
+        if self.config.verbose {
+            print!("revision={:?} revision_props={:#?}", revision, revision_props);
+        }
+
+        if revision.starts_with("rpass") {
+            revision_cx.run_rpass_test();
+        } else if revision.starts_with("rfail") {
+            revision_cx.run_rfail_test();
+        } else if revision.starts_with("cfail") {
+            revision_cx.run_cfail_test();
+        } else {
+            revision_cx.fatal(
+                "revision name must begin with rpass, rfail, or cfail");
+        }
+    }
+
+    /// Directory where incremental work products are stored.
+    fn incremental_dir(&self) -> PathBuf {
+        self.output_base_name().with_extension("incremental")
+    }
+
+    fn run_rmake_test(&self) {
+        // FIXME(#11094): we should fix these tests
+        if self.config.host != self.config.target {
+            return
+        }
+
+        let cwd = env::current_dir().unwrap();
+        let src_root = self.config.src_base.parent().unwrap()
+                                           .parent().unwrap()
+                                           .parent().unwrap();
+        let src_root = cwd.join(&src_root);
+
+        let tmpdir = cwd.join(self.output_base_name());
+        if tmpdir.exists() {
+            self.aggressive_rm_rf(&tmpdir).unwrap();
+        }
+        self.create_dir_racy(&tmpdir);
+
+        let mut cmd = Command::new("make");
+        cmd.current_dir(&self.testpaths.file)
+           .env("TARGET", &self.config.target)
+           .env("PYTHON", &self.config.docck_python)
+           .env("S", src_root)
+           .env("RUST_BUILD_STAGE", &self.config.stage_id)
+           .env("RUSTC", cwd.join(&self.config.rustc_path))
+           .env("RUSTDOC", cwd.join(&self.config.rustdoc_path))
+           .env("TMPDIR", &tmpdir)
+           .env("LD_LIB_PATH_ENVVAR", procsrv::dylib_env_var())
+           .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
+           .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
+           .env("LLVM_COMPONENTS", &self.config.llvm_components)
+           .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags);
+
+        if self.config.target.contains("msvc") {
+            // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe`
+            // and that `lib.exe` lives next to it.
+            let lib = Path::new(&self.config.cc).parent().unwrap().join("lib.exe");
+
+            // MSYS doesn't like passing flags of the form `/foo` as it thinks it's
+            // a path and instead passes `C:\msys64\foo`, so convert all
+            // `/`-arguments to MSVC here to `-` arguments.
+            let cflags = self.config.cflags.split(' ').map(|s| s.replace("/", "-"))
+                                                 .collect::<Vec<_>>().join(" ");
+
+            cmd.env("IS_MSVC", "1")
+               .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
+               .env("CC", format!("'{}' {}", self.config.cc, cflags))
+               .env("CXX", &self.config.cxx);
+        } else {
+            cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
+               .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags));
+        }
+
+        let output = cmd.output().expect("failed to spawn `make`");
+        if !output.status.success() {
+            let res = ProcRes {
+                status: Status::Normal(output.status),
+                stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
+                stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
+                cmdline: format!("{:?}", cmd),
+            };
+            self.fatal_proc_rec("make failed", &res);
+        }
+    }
+
+    fn aggressive_rm_rf(&self, path: &Path) -> io::Result<()> {
+        for e in try!(path.read_dir()) {
+            let entry = try!(e);
+            let path = entry.path();
+            if try!(entry.file_type()).is_dir() {
+                try!(self.aggressive_rm_rf(&path));
+            } else {
+                // Remove readonly files as well on windows (by default we can't)
+                try!(fs::remove_file(&path).or_else(|e| {
+                    if cfg!(windows) && e.kind() == io::ErrorKind::PermissionDenied {
+                        let mut meta = try!(entry.metadata()).permissions();
+                        meta.set_readonly(false);
+                        try!(fs::set_permissions(&path, meta));
+                        fs::remove_file(&path)
+                    } else {
+                        Err(e)
+                    }
+                }))
+            }
+        }
+        fs::remove_dir(path)
     }
 }
 
@@ -1152,1020 +2140,8 @@ impl fmt::Display for Status {
     }
 }
 
-fn compile_test(config: &Config, props: &TestProps,
-                testpaths: &TestPaths) -> ProcRes {
-    let aux_dir = aux_output_dir_name(config, testpaths);
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let link_args = vec!("-L".to_owned(),
-                         aux_dir.to_str().unwrap().to_owned());
-    let args = make_compile_args(config,
-                                 props,
-                                 link_args,
-                                 |a, b| TargetLocation::ThisFile(make_exe_name(a, b)), testpaths);
-    compose_and_run_compiler(config, props, testpaths, args, None)
-}
-
-fn document(config: &Config,
-            props: &TestProps,
-            testpaths: &TestPaths,
-            out_dir: &Path)
-            -> ProcRes {
-    if props.build_aux_docs {
-        for rel_ab in &props.aux_builds {
-            let aux_testpaths = compute_aux_test_paths(config, testpaths, rel_ab);
-            let aux_props = header::load_props(&aux_testpaths.file);
-            let auxres = document(config, &aux_props, &aux_testpaths, out_dir);
-            if !auxres.status.success() {
-                return auxres;
-            }
-        }
-    }
-
-    let aux_dir = aux_output_dir_name(config, testpaths);
-    let mut args = vec!["-L".to_owned(),
-                        aux_dir.to_str().unwrap().to_owned(),
-                        "-o".to_owned(),
-                        out_dir.to_str().unwrap().to_owned(),
-                        testpaths.file.to_str().unwrap().to_owned()];
-    args.extend(props.compile_flags.iter().cloned());
-    let args = ProcArgs {
-        prog: config.rustdoc_path.to_str().unwrap().to_owned(),
-        args: args,
-    };
-    compose_and_run_compiler(config, props, testpaths, args, None)
-}
-
-fn exec_compiled_test(config: &Config, props: &TestProps,
-                      testpaths: &TestPaths) -> ProcRes {
-
-    let env = props.exec_env.clone();
-
-    match &*config.target {
-
-        "arm-linux-androideabi" | "aarch64-linux-android" => {
-            _arm_exec_compiled_test(config, props, testpaths, env)
-        }
-
-        _=> {
-            let aux_dir = aux_output_dir_name(config, testpaths);
-            compose_and_run(config,
-                            testpaths,
-                            make_run_args(config, props, testpaths),
-                            env,
-                            config.run_lib_path.to_str().unwrap(),
-                            Some(aux_dir.to_str().unwrap()),
-                            None)
-        }
-    }
-}
-
-fn compute_aux_test_paths(config: &Config,
-                          testpaths: &TestPaths,
-                          rel_ab: &str)
-                          -> TestPaths
-{
-    let abs_ab = config.aux_base.join(rel_ab);
-    TestPaths {
-        file: abs_ab,
-        base: testpaths.base.clone(),
-        relative_dir: Path::new(rel_ab).parent()
-                                       .map(|p| p.to_path_buf())
-                                       .unwrap_or_else(|| PathBuf::new())
-    }
-}
-
-fn compose_and_run_compiler(config: &Config, props: &TestProps,
-                            testpaths: &TestPaths, args: ProcArgs,
-                            input: Option<String>) -> ProcRes {
-    if !props.aux_builds.is_empty() {
-        create_dir_racy(&aux_output_dir_name(config, testpaths));
-    }
-
-    let aux_dir = aux_output_dir_name(config, testpaths);
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let extra_link_args = vec!["-L".to_owned(),
-                               aux_dir.to_str().unwrap().to_owned()];
-
-    for rel_ab in &props.aux_builds {
-        let aux_testpaths = compute_aux_test_paths(config, testpaths, rel_ab);
-        let aux_props = header::load_props(&aux_testpaths.file);
-        let mut crate_type = if aux_props.no_prefer_dynamic {
-            Vec::new()
-        } else {
-            // We primarily compile all auxiliary libraries as dynamic libraries
-            // to avoid code size bloat and large binaries as much as possible
-            // for the test suite (otherwise including libstd statically in all
-            // executables takes up quite a bit of space).
-            //
-            // For targets like MUSL or Emscripten, however, there is no support for
-            // dynamic libraries so we just go back to building a normal library. Note,
-            // however, that for MUSL if the library is built with `force_host` then
-            // it's ok to be a dylib as the host should always support dylibs.
-            if (config.target.contains("musl") && !aux_props.force_host) ||
-                config.target.contains("emscripten")
-            {
-                vec!("--crate-type=lib".to_owned())
-            } else {
-                vec!("--crate-type=dylib".to_owned())
-            }
-        };
-        crate_type.extend(extra_link_args.clone());
-        let aux_args =
-            make_compile_args(config,
-                              &aux_props,
-                              crate_type,
-                              |a,b| {
-                                  let f = make_lib_name(a, &b.file, testpaths);
-                                  let parent = f.parent().unwrap();
-                                  TargetLocation::ThisDirectory(parent.to_path_buf())
-                              },
-                              &aux_testpaths);
-        let auxres = compose_and_run(config,
-                                     &aux_testpaths,
-                                     aux_args,
-                                     Vec::new(),
-                                     config.compile_lib_path.to_str().unwrap(),
-                                     Some(aux_dir.to_str().unwrap()),
-                                     None);
-        if !auxres.status.success() {
-            fatal_proc_rec(
-                None,
-                &format!("auxiliary build of {:?} failed to compile: ",
-                        aux_testpaths.file.display()),
-                &auxres);
-        }
-
-        match &*config.target {
-            "arm-linux-androideabi"  | "aarch64-linux-android" => {
-                _arm_push_aux_shared_library(config, testpaths);
-            }
-            _ => {}
-        }
-    }
-
-    compose_and_run(config,
-                    testpaths,
-                    args,
-                    props.rustc_env.clone(),
-                    config.compile_lib_path.to_str().unwrap(),
-                    Some(aux_dir.to_str().unwrap()),
-                    input)
-}
-
-fn compose_and_run(config: &Config,
-                   testpaths: &TestPaths,
-                   ProcArgs{ args, prog }: ProcArgs,
-                   procenv: Vec<(String, String)> ,
-                   lib_path: &str,
-                   aux_path: Option<&str>,
-                   input: Option<String>) -> ProcRes {
-    return program_output(config, testpaths, lib_path,
-                          prog, aux_path, args, procenv, input);
-}
-
 enum TargetLocation {
     ThisFile(PathBuf),
     ThisDirectory(PathBuf),
 }
 
-fn make_compile_args<F>(config: &Config,
-                        props: &TestProps,
-                        extras: Vec<String> ,
-                        xform: F,
-                        testpaths: &TestPaths)
-                        -> ProcArgs where
-    F: FnOnce(&Config, &TestPaths) -> TargetLocation,
-{
-    let xform_file = xform(config, testpaths);
-    let target = if props.force_host {
-        &*config.host
-    } else {
-        &*config.target
-    };
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let mut args = vec!(testpaths.file.to_str().unwrap().to_owned(),
-                        "-L".to_owned(),
-                        config.build_base.to_str().unwrap().to_owned(),
-                        format!("--target={}", target));
-
-    match config.mode {
-        CompileFail |
-        ParseFail |
-        Incremental => {
-            // If we are extracting and matching errors in the new
-            // fashion, then you want JSON mode. Old-skool error
-            // patterns still match the raw compiler output.
-            if props.error_patterns.is_empty() {
-                args.extend(["--error-format",
-                             "json",
-                             "-Z",
-                             "unstable-options"]
-                            .iter()
-                            .map(|s| s.to_string()));
-            }
-        }
-
-        RunFail |
-        RunPass |
-        RunPassValgrind |
-        Pretty |
-        DebugInfoGdb |
-        DebugInfoLldb |
-        Codegen |
-        Rustdoc |
-        RunMake |
-        CodegenUnits => {
-            // do not use JSON output
-        }
-    }
-
-    args.extend_from_slice(&extras);
-    if !props.no_prefer_dynamic {
-        args.push("-C".to_owned());
-        args.push("prefer-dynamic".to_owned());
-    }
-    let path = match xform_file {
-        TargetLocation::ThisFile(path) => {
-            args.push("-o".to_owned());
-            path
-        }
-        TargetLocation::ThisDirectory(path) => {
-            args.push("--out-dir".to_owned());
-            path
-        }
-    };
-    args.push(path.to_str().unwrap().to_owned());
-    if props.force_host {
-        args.extend(split_maybe_args(&config.host_rustcflags));
-    } else {
-        args.extend(split_maybe_args(&config.target_rustcflags));
-    }
-    args.extend(props.compile_flags.iter().cloned());
-    return ProcArgs {
-        prog: config.rustc_path.to_str().unwrap().to_owned(),
-        args: args,
-    };
-}
-
-fn make_lib_name(config: &Config, auxfile: &Path, testpaths: &TestPaths) -> PathBuf {
-    // what we return here is not particularly important, as it
-    // happens; rustc ignores everything except for the directory.
-    let auxname = output_testname(auxfile);
-    aux_output_dir_name(config, testpaths).join(&auxname)
-}
-
-fn make_exe_name(config: &Config, testpaths: &TestPaths) -> PathBuf {
-    let mut f = output_base_name(config, testpaths);
-    // FIXME: This is using the host architecture exe suffix, not target!
-    if config.target == "asmjs-unknown-emscripten" {
-        let mut fname = f.file_name().unwrap().to_os_string();
-        fname.push(".js");
-        f.set_file_name(&fname);
-    } else if !env::consts::EXE_SUFFIX.is_empty() {
-        let mut fname = f.file_name().unwrap().to_os_string();
-        fname.push(env::consts::EXE_SUFFIX);
-        f.set_file_name(&fname);
-    }
-    f
-}
-
-fn make_run_args(config: &Config, props: &TestProps, testpaths: &TestPaths)
-                 -> ProcArgs {
-    // If we've got another tool to run under (valgrind),
-    // then split apart its command
-    let mut args = split_maybe_args(&config.runtool);
-
-    // If this is emscripten, then run tests under nodejs
-    if config.target == "asmjs-unknown-emscripten" {
-        args.push("nodejs".to_owned());
-    }
-
-    let exe_file = make_exe_name(config, testpaths);
-
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    args.push(exe_file.to_str().unwrap().to_owned());
-
-    // Add the arguments in the run_flags directive
-    args.extend(split_maybe_args(&props.run_flags));
-
-    let prog = args.remove(0);
-    return ProcArgs {
-        prog: prog,
-        args: args,
-    };
-}
-
-fn split_maybe_args(argstr: &Option<String>) -> Vec<String> {
-    match *argstr {
-        Some(ref s) => {
-            s
-             .split(' ')
-             .filter_map(|s| {
-                 if s.chars().all(|c| c.is_whitespace()) {
-                     None
-                 } else {
-                     Some(s.to_owned())
-                 }
-             }).collect()
-        }
-        None => Vec::new()
-    }
-}
-
-fn program_output(config: &Config, testpaths: &TestPaths, lib_path: &str, prog: String,
-                  aux_path: Option<&str>, args: Vec<String>,
-                  env: Vec<(String, String)>,
-                  input: Option<String>) -> ProcRes {
-    let cmdline =
-        {
-            let cmdline = make_cmdline(lib_path,
-                                       &prog,
-                                       &args);
-            logv(config, format!("executing {}", cmdline));
-            cmdline
-        };
-    let procsrv::Result {
-        out,
-        err,
-        status
-    } = procsrv::run(lib_path,
-                     &prog,
-                     aux_path,
-                     &args,
-                     env,
-                     input).expect(&format!("failed to exec `{}`", prog));
-    dump_output(config, testpaths, &out, &err);
-    return ProcRes {
-        status: Status::Normal(status),
-        stdout: out,
-        stderr: err,
-        cmdline: cmdline,
-    };
-}
-
-fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
-    use util;
-
-    // Linux and mac don't require adjusting the library search path
-    if cfg!(unix) {
-        format!("{} {}", prog, args.join(" "))
-    } else {
-        // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
-        // for diagnostic purposes
-        fn lib_path_cmd_prefix(path: &str) -> String {
-            format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
-        }
-
-        format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.join(" "))
-    }
-}
-
-fn dump_output(config: &Config, testpaths: &TestPaths, out: &str, err: &str) {
-    create_dir_racy(output_base_name(config, testpaths).parent().unwrap());
-    dump_output_file(config, testpaths, out, "out");
-    dump_output_file(config, testpaths, err, "err");
-    maybe_dump_to_stdout(config, out, err);
-}
-
-fn dump_output_file(config: &Config,
-                    testpaths: &TestPaths,
-                    out: &str,
-                    extension: &str) {
-    let outfile = make_out_name(config, testpaths, extension);
-    File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
-}
-
-fn make_out_name(config: &Config, testpaths: &TestPaths, extension: &str) -> PathBuf {
-    output_base_name(config, testpaths).with_extension(extension)
-}
-
-fn aux_output_dir_name(config: &Config, testpaths: &TestPaths) -> PathBuf {
-    let f = output_base_name(config, testpaths);
-    let mut fname = f.file_name().unwrap().to_os_string();
-    fname.push(&format!(".{}.libaux", config.mode));
-    f.with_file_name(&fname)
-}
-
-fn output_testname(filepath: &Path) -> PathBuf {
-    PathBuf::from(filepath.file_stem().unwrap())
-}
-
-fn output_base_name(config: &Config, testpaths: &TestPaths) -> PathBuf {
-    let dir = config.build_base.join(&testpaths.relative_dir);
-
-    // Note: The directory `dir` is created during `collect_tests_from_dir`
-    dir
-        .join(&output_testname(&testpaths.file))
-        .with_extension(&config.stage_id)
-}
-
-fn maybe_dump_to_stdout(config: &Config, out: &str, err: &str) {
-    if config.verbose {
-        println!("------{}------------------------------", "stdout");
-        println!("{}", out);
-        println!("------{}------------------------------", "stderr");
-        println!("{}", err);
-        println!("------------------------------------------");
-    }
-}
-
-fn error(revision: Option<&str>, err: &str) {
-    match revision {
-        Some(rev) => println!("\nerror in revision `{}`: {}", rev, err),
-        None => println!("\nerror: {}", err)
-    }
-}
-
-fn fatal(revision: Option<&str>, err: &str) -> ! {
-    error(revision, err); panic!();
-}
-
-fn fatal_proc_rec(revision: Option<&str>, err: &str, proc_res: &ProcRes) -> ! {
-    error(revision, err);
-    print!("\
-status: {}\n\
-command: {}\n\
-stdout:\n\
-------------------------------------------\n\
-{}\n\
-------------------------------------------\n\
-stderr:\n\
-------------------------------------------\n\
-{}\n\
-------------------------------------------\n\
-\n",
-             proc_res.status, proc_res.cmdline, proc_res.stdout,
-             proc_res.stderr);
-    panic!();
-}
-
-fn _arm_exec_compiled_test(config: &Config,
-                           props: &TestProps,
-                           testpaths: &TestPaths,
-                           env: Vec<(String, String)>)
-                           -> ProcRes {
-    let args = make_run_args(config, props, testpaths);
-    let cmdline = make_cmdline("",
-                               &args.prog,
-                               &args.args);
-
-    // get bare program string
-    let mut tvec: Vec<String> = args.prog
-                                    .split('/')
-                                    .map(str::to_owned)
-                                    .collect();
-    let prog_short = tvec.pop().unwrap();
-
-    // copy to target
-    let copy_result = procsrv::run("",
-                                   &config.adb_path,
-                                   None,
-                                   &[
-                                    "push".to_owned(),
-                                    args.prog.clone(),
-                                    config.adb_test_dir.clone()
-                                   ],
-                                   vec!(("".to_owned(), "".to_owned())),
-                                   Some("".to_owned()))
-        .expect(&format!("failed to exec `{}`", config.adb_path));
-
-    if config.verbose {
-        println!("push ({}) {} {} {}",
-                 config.target,
-                 args.prog,
-                 copy_result.out,
-                 copy_result.err);
-    }
-
-    logv(config, format!("executing ({}) {}", config.target, cmdline));
-
-    let mut runargs = Vec::new();
-
-    // run test via adb_run_wrapper
-    runargs.push("shell".to_owned());
-    for (key, val) in env {
-        runargs.push(format!("{}={}", key, val));
-    }
-    runargs.push(format!("{}/../adb_run_wrapper.sh", config.adb_test_dir));
-    runargs.push(format!("{}", config.adb_test_dir));
-    runargs.push(format!("{}", prog_short));
-
-    for tv in &args.args {
-        runargs.push(tv.to_owned());
-    }
-    procsrv::run("",
-                 &config.adb_path,
-                 None,
-                 &runargs,
-                 vec!(("".to_owned(), "".to_owned())), Some("".to_owned()))
-        .expect(&format!("failed to exec `{}`", config.adb_path));
-
-    // get exitcode of result
-    runargs = Vec::new();
-    runargs.push("shell".to_owned());
-    runargs.push("cat".to_owned());
-    runargs.push(format!("{}/{}.exitcode", config.adb_test_dir, prog_short));
-
-    let procsrv::Result{ out: exitcode_out, err: _, status: _ } =
-        procsrv::run("",
-                     &config.adb_path,
-                     None,
-                     &runargs,
-                     vec!(("".to_owned(), "".to_owned())),
-                     Some("".to_owned()))
-        .expect(&format!("failed to exec `{}`", config.adb_path));
-
-    let mut exitcode: i32 = 0;
-    for c in exitcode_out.chars() {
-        if !c.is_numeric() { break; }
-        exitcode = exitcode * 10 + match c {
-            '0' ... '9' => c as i32 - ('0' as i32),
-            _ => 101,
-        }
-    }
-
-    // get stdout of result
-    runargs = Vec::new();
-    runargs.push("shell".to_owned());
-    runargs.push("cat".to_owned());
-    runargs.push(format!("{}/{}.stdout", config.adb_test_dir, prog_short));
-
-    let procsrv::Result{ out: stdout_out, err: _, status: _ } =
-        procsrv::run("",
-                     &config.adb_path,
-                     None,
-                     &runargs,
-                     vec!(("".to_owned(), "".to_owned())),
-                     Some("".to_owned()))
-        .expect(&format!("failed to exec `{}`", config.adb_path));
-
-    // get stderr of result
-    runargs = Vec::new();
-    runargs.push("shell".to_owned());
-    runargs.push("cat".to_owned());
-    runargs.push(format!("{}/{}.stderr", config.adb_test_dir, prog_short));
-
-    let procsrv::Result{ out: stderr_out, err: _, status: _ } =
-        procsrv::run("",
-                     &config.adb_path,
-                     None,
-                     &runargs,
-                     vec!(("".to_owned(), "".to_owned())),
-                     Some("".to_owned()))
-        .expect(&format!("failed to exec `{}`", config.adb_path));
-
-    dump_output(config,
-                testpaths,
-                &stdout_out,
-                &stderr_out);
-
-    ProcRes {
-        status: Status::Parsed(exitcode),
-        stdout: stdout_out,
-        stderr: stderr_out,
-        cmdline: cmdline
-    }
-}
-
-fn _arm_push_aux_shared_library(config: &Config, testpaths: &TestPaths) {
-    let tdir = aux_output_dir_name(config, testpaths);
-
-    let dirs = fs::read_dir(&tdir).unwrap();
-    for file in dirs {
-        let file = file.unwrap().path();
-        if file.extension().and_then(|s| s.to_str()) == Some("so") {
-            // FIXME (#9639): This needs to handle non-utf8 paths
-            let copy_result = procsrv::run("",
-                                           &config.adb_path,
-                                           None,
-                                           &[
-                                            "push".to_owned(),
-                                            file.to_str()
-                                                .unwrap()
-                                                .to_owned(),
-                                            config.adb_test_dir.to_owned(),
-                                           ],
-                                           vec!(("".to_owned(),
-                                                 "".to_owned())),
-                                           Some("".to_owned()))
-                .expect(&format!("failed to exec `{}`", config.adb_path));
-
-            if config.verbose {
-                println!("push ({}) {:?} {} {}",
-                    config.target, file.display(),
-                    copy_result.out, copy_result.err);
-            }
-        }
-    }
-}
-
-// codegen tests (using FileCheck)
-
-fn compile_test_and_save_ir(config: &Config, props: &TestProps,
-                                 testpaths: &TestPaths) -> ProcRes {
-    let aux_dir = aux_output_dir_name(config, testpaths);
-    // FIXME (#9639): This needs to handle non-utf8 paths
-    let mut link_args = vec!("-L".to_owned(),
-                             aux_dir.to_str().unwrap().to_owned());
-    let llvm_args = vec!("--emit=llvm-ir".to_owned(),);
-    link_args.extend(llvm_args);
-    let args = make_compile_args(config,
-                                 props,
-                                 link_args,
-                                 |a, b| TargetLocation::ThisDirectory(
-                                     output_base_name(a, b).parent()
-                                        .unwrap().to_path_buf()),
-                                 testpaths);
-    compose_and_run_compiler(config, props, testpaths, args, None)
-}
-
-fn check_ir_with_filecheck(config: &Config, testpaths: &TestPaths) -> ProcRes {
-    let irfile = output_base_name(config, testpaths).with_extension("ll");
-    let prog = config.llvm_filecheck.as_ref().unwrap();
-    let proc_args = ProcArgs {
-        // FIXME (#9639): This needs to handle non-utf8 paths
-        prog: prog.to_str().unwrap().to_owned(),
-        args: vec!(format!("-input-file={}", irfile.to_str().unwrap()),
-                   testpaths.file.to_str().unwrap().to_owned())
-    };
-    compose_and_run(config, testpaths, proc_args, Vec::new(), "", None, None)
-}
-
-fn run_codegen_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    assert!(props.revisions.is_empty(), "revisions not relevant here");
-
-    if config.llvm_filecheck.is_none() {
-        fatal(None, "missing --llvm-filecheck");
-    }
-
-    let mut proc_res = compile_test_and_save_ir(config, props, testpaths);
-    if !proc_res.status.success() {
-        fatal_proc_rec(None, "compilation failed!", &proc_res);
-    }
-
-    proc_res = check_ir_with_filecheck(config, testpaths);
-    if !proc_res.status.success() {
-        fatal_proc_rec(None,
-                       "verification with 'FileCheck' failed",
-                       &proc_res);
-    }
-}
-
-fn charset() -> &'static str {
-    // FreeBSD 10.1 defaults to GDB 6.1.1 which doesn't support "auto" charset
-    if cfg!(target_os = "bitrig") {
-        "auto"
-    } else if cfg!(target_os = "freebsd") {
-        "ISO-8859-1"
-    } else {
-        "UTF-8"
-    }
-}
-
-fn run_rustdoc_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    assert!(props.revisions.is_empty(), "revisions not relevant here");
-
-    let out_dir = output_base_name(config, testpaths);
-    let _ = fs::remove_dir_all(&out_dir);
-    create_dir_racy(&out_dir);
-
-    let proc_res = document(config, props, testpaths, &out_dir);
-    if !proc_res.status.success() {
-        fatal_proc_rec(None, "rustdoc failed!", &proc_res);
-    }
-    let root = find_rust_src_root(config).unwrap();
-
-    let res = cmd2procres(config,
-                          testpaths,
-                          Command::new(&config.docck_python)
-                                  .arg(root.join("src/etc/htmldocck.py"))
-                                  .arg(out_dir)
-                                  .arg(&testpaths.file));
-    if !res.status.success() {
-        fatal_proc_rec(None, "htmldocck failed!", &res);
-    }
-}
-
-fn run_codegen_units_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-
-    assert!(props.revisions.is_empty(), "revisions not relevant here");
-
-    let proc_res = compile_test(config, props, testpaths);
-
-    if !proc_res.status.success() {
-        fatal_proc_rec(None, "compilation failed!", &proc_res);
-    }
-
-    check_no_compiler_crash(None, &proc_res);
-
-    const PREFIX: &'static str = "TRANS_ITEM ";
-    const CGU_MARKER: &'static str = "@@";
-
-    let actual: Vec<TransItem> = proc_res
-        .stdout
-        .lines()
-        .filter(|line| line.starts_with(PREFIX))
-        .map(str_to_trans_item)
-        .collect();
-
-    let expected: Vec<TransItem> = errors::load_errors(&testpaths.file, None)
-        .iter()
-        .map(|e| str_to_trans_item(&e.msg[..]))
-        .collect();
-
-    let mut missing = Vec::new();
-    let mut wrong_cgus = Vec::new();
-
-    for expected_item in &expected {
-        let actual_item_with_same_name = actual.iter()
-                                               .find(|ti| ti.name == expected_item.name);
-
-        if let Some(actual_item) = actual_item_with_same_name {
-            if !expected_item.codegen_units.is_empty() {
-                // Also check for codegen units
-                if expected_item.codegen_units != actual_item.codegen_units {
-                    wrong_cgus.push((expected_item.clone(), actual_item.clone()));
-                }
-            }
-        } else {
-            missing.push(expected_item.string.clone());
-        }
-    }
-
-    let unexpected: Vec<_> =
-        actual.iter()
-              .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name))
-              .map(|acgu| acgu.string.clone())
-              .collect();
-
-    if !missing.is_empty() {
-        missing.sort();
-
-        println!("\nThese items should have been contained but were not:\n");
-
-        for item in &missing {
-            println!("{}", item);
-        }
-
-        println!("\n");
-    }
-
-    if !unexpected.is_empty() {
-        let sorted = {
-            let mut sorted = unexpected.clone();
-            sorted.sort();
-            sorted
-        };
-
-        println!("\nThese items were contained but should not have been:\n");
-
-        for item in sorted {
-            println!("{}", item);
-        }
-
-        println!("\n");
-    }
-
-    if !wrong_cgus.is_empty() {
-        wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
-        println!("\nThe following items were assigned to wrong codegen units:\n");
-
-        for &(ref expected_item, ref actual_item) in &wrong_cgus {
-            println!("{}", expected_item.name);
-            println!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
-            println!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
-            println!("");
-        }
-    }
-
-    if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty())
-    {
-        panic!();
-    }
-
-    #[derive(Clone, Eq, PartialEq)]
-    struct TransItem {
-        name: String,
-        codegen_units: HashSet<String>,
-        string: String,
-    }
-
-    // [TRANS_ITEM] name [@@ (cgu)+]
-    fn str_to_trans_item(s: &str) -> TransItem {
-        let s = if s.starts_with(PREFIX) {
-            (&s[PREFIX.len()..]).trim()
-        } else {
-            s.trim()
-        };
-
-        let full_string = format!("{}{}", PREFIX, s.trim().to_owned());
-
-        let parts: Vec<&str> = s.split(CGU_MARKER)
-                                .map(str::trim)
-                                .filter(|s| !s.is_empty())
-                                .collect();
-
-        let name = parts[0].trim();
-
-        let cgus = if parts.len() > 1 {
-            let cgus_str = parts[1];
-
-            cgus_str.split(" ")
-                    .map(str::trim)
-                    .filter(|s| !s.is_empty())
-                    .map(str::to_owned)
-                    .collect()
-        }
-        else {
-            HashSet::new()
-        };
-
-        TransItem {
-            name: name.to_owned(),
-            codegen_units: cgus,
-            string: full_string,
-        }
-    }
-
-    fn codegen_units_to_str(cgus: &HashSet<String>) -> String
-    {
-        let mut cgus: Vec<_> = cgus.iter().collect();
-        cgus.sort();
-
-        let mut string = String::new();
-        for cgu in cgus {
-            string.push_str(&cgu[..]);
-            string.push_str(" ");
-        }
-
-        string
-    }
-}
-
-fn run_incremental_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
-    // Basic plan for a test incremental/foo/bar.rs:
-    // - load list of revisions pass1, fail2, pass3
-    //   - each should begin with `rpass`, `rfail`, or `cfail`
-    //   - if `rpass`, expect compile and execution to succeed
-    //   - if `cfail`, expect compilation to fail
-    //   - if `rfail`, expect execution to fail
-    // - create a directory build/foo/bar.incremental
-    // - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C pass1
-    //   - because name of revision starts with "pass", expect success
-    // - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C fail2
-    //   - because name of revision starts with "fail", expect an error
-    //   - load expected errors as usual, but filter for those that end in `[fail2]`
-    // - compile foo/bar.rs with -Z incremental=.../foo/bar.incremental and -C pass3
-    //   - because name of revision starts with "pass", expect success
-    // - execute build/foo/bar.exe and save output
-    //
-    // FIXME -- use non-incremental mode as an oracle? That doesn't apply
-    // to #[rustc_dirty] and clean tests I guess
-
-    assert!(!props.revisions.is_empty(), "incremental tests require a list of revisions");
-
-    let output_base_name = output_base_name(config, testpaths);
-
-    // Create the incremental workproduct directory.
-    let incremental_dir = output_base_name.with_extension("incremental");
-    if incremental_dir.exists() {
-        fs::remove_dir_all(&incremental_dir).unwrap();
-    }
-    create_dir_racy(&incremental_dir);
-
-    if config.verbose {
-        print!("incremental_dir={}", incremental_dir.display());
-    }
-
-    for revision in &props.revisions {
-        let mut revision_props = props.clone();
-        header::load_props_into(&mut revision_props, &testpaths.file, Some(&revision));
-
-        revision_props.compile_flags.extend(vec![
-            format!("-Z"),
-            format!("incremental={}", incremental_dir.display()),
-            format!("--cfg"),
-            format!("{}", revision),
-        ]);
-
-        if config.verbose {
-            print!("revision={:?} revision_props={:#?}", revision, revision_props);
-        }
-
-        if revision.starts_with("rpass") {
-            run_rpass_test_revision(config, &revision_props, testpaths, Some(&revision));
-        } else if revision.starts_with("rfail") {
-            run_rfail_test_revision(config, &revision_props, testpaths, Some(&revision));
-        } else if revision.starts_with("cfail") {
-            run_cfail_test_revision(config, &revision_props, testpaths, Some(&revision));
-        } else {
-            fatal(
-                Some(revision),
-                "revision name must begin with rpass, rfail, or cfail");
-        }
-    }
-}
-
-fn run_rmake_test(config: &Config, _props: &TestProps, testpaths: &TestPaths) {
-    // FIXME(#11094): we should fix these tests
-    if config.host != config.target {
-        return
-    }
-
-    let cwd = env::current_dir().unwrap();
-    let src_root = config.src_base.parent().unwrap().parent().unwrap()
-                                  .parent().unwrap();
-    let src_root = cwd.join(&src_root);
-
-    let tmpdir = cwd.join(output_base_name(config, testpaths));
-    if tmpdir.exists() {
-        aggressive_rm_rf(&tmpdir).unwrap();
-    }
-    create_dir_racy(&tmpdir);
-
-    let mut cmd = Command::new("make");
-    cmd.current_dir(&testpaths.file)
-       .env("TARGET", &config.target)
-       .env("PYTHON", &config.docck_python)
-       .env("S", src_root)
-       .env("RUST_BUILD_STAGE", &config.stage_id)
-       .env("RUSTC", cwd.join(&config.rustc_path))
-       .env("RUSTDOC", cwd.join(&config.rustdoc_path))
-       .env("TMPDIR", &tmpdir)
-       .env("LD_LIB_PATH_ENVVAR", procsrv::dylib_env_var())
-       .env("HOST_RPATH_DIR", cwd.join(&config.compile_lib_path))
-       .env("TARGET_RPATH_DIR", cwd.join(&config.run_lib_path))
-       .env("LLVM_COMPONENTS", &config.llvm_components)
-       .env("LLVM_CXXFLAGS", &config.llvm_cxxflags);
-
-    if config.target.contains("msvc") {
-        // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe`
-        // and that `lib.exe` lives next to it.
-        let lib = Path::new(&config.cc).parent().unwrap().join("lib.exe");
-
-        // MSYS doesn't like passing flags of the form `/foo` as it thinks it's
-        // a path and instead passes `C:\msys64\foo`, so convert all
-        // `/`-arguments to MSVC here to `-` arguments.
-        let cflags = config.cflags.split(' ').map(|s| s.replace("/", "-"))
-                           .collect::<Vec<_>>().join(" ");
-
-        cmd.env("IS_MSVC", "1")
-           .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
-           .env("CC", format!("'{}' {}", config.cc, cflags))
-           .env("CXX", &config.cxx);
-    } else {
-        cmd.env("CC", format!("{} {}", config.cc, config.cflags))
-           .env("CXX", format!("{} {}", config.cxx, config.cflags));
-    }
-
-    let output = cmd.output().expect("failed to spawn `make`");
-    if !output.status.success() {
-        let res = ProcRes {
-            status: Status::Normal(output.status),
-            stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
-            stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
-            cmdline: format!("{:?}", cmd),
-        };
-        fatal_proc_rec(None, "make failed", &res);
-    }
-}
-
-fn aggressive_rm_rf(path: &Path) -> io::Result<()> {
-    for e in try!(path.read_dir()) {
-        let entry = try!(e);
-        let path = entry.path();
-        if try!(entry.file_type()).is_dir() {
-            try!(aggressive_rm_rf(&path));
-        } else {
-            // Remove readonly files as well on windows (by default we can't)
-            try!(fs::remove_file(&path).or_else(|e| {
-                if cfg!(windows) && e.kind() == io::ErrorKind::PermissionDenied {
-                    let mut meta = try!(entry.metadata()).permissions();
-                    meta.set_readonly(false);
-                    try!(fs::set_permissions(&path, meta));
-                    fs::remove_file(&path)
-                } else {
-                    Err(e)
-                }
-            }))
-        }
-    }
-    fs::remove_dir(path)
-}
-
-// Like std::fs::create_dir_all, except handles concurrent calls among multiple
-// threads or processes.
-fn create_dir_racy(path: &Path) {
-    match fs::create_dir(path) {
-        Ok(()) => return,
-        Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => return,
-        Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
-        Err(e) => panic!("failed to create dir {:?}: {}", path, e),
-    }
-    create_dir_racy(path.parent().unwrap());
-    match fs::create_dir(path) {
-        Ok(()) => {}
-        Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => {}
-        Err(e) => panic!("failed to create dir {:?}: {}", path, e),
-    }
-}