about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-10-06 04:59:16 +0000
committerbors <bors@rust-lang.org>2019-10-06 04:59:16 +0000
commit5a8fb7c24d85d0bd911ca465c4a077c7cee608ae (patch)
treeb096ac2dd13c5edbfc3edaf9ecce9edde915470d
parent7870050796e5904a0fc85ecbe6fa6dde1cfe0c91 (diff)
parent69598dc3cfd7e0ad63282268ea58ebac0b6031dc (diff)
downloadrust-5a8fb7c24d85d0bd911ca465c4a077c7cee608ae.tar.gz
rust-5a8fb7c24d85d0bd911ca465c4a077c7cee608ae.zip
Auto merge of #65152 - tmandry:rollup-btn4a01, r=tmandry
Rollup of 18 pull requests

This contains changes from all the successful runs that bors marked as timed out, plus a revert of #63649 which appears to be the immediate cause of the timeouts.

Successful merges:

 - #64708 (Stabilize `Option::as_deref` and `Option::as_deref_mut`)
 - #64728 (Stabilize UdpSocket::peer_addr)
 - #64765 (std: Reduce checks for `feature = "backtrace"`)
 - #64909 (When encountering chained operators use heuristics to recover from bad turbofish)
 - #65011 (Do not ICE when dereferencing non-Copy raw pointer)
 - #65064 (permit asyncawait-ondeck to be added by anyone)
 - #65066 ([const-prop] Fix ICE when trying to eval polymorphic promoted MIR)
 - #65100 (Replace GeneratorSubsts with SubstsRef)
 - #65105 (Split out some passes from librustc)
 - #65106 (Allow unused attributes to avoid incremental bug)
 - #65113 (Fix lonely backtick)
 - #65116 (Remove unneeded visit_statement definition)
 - #65118 (Update the documented default of -Z mutable-noalias)
 - #65123 (Account for macro invocation in `let mut $pat` diagnostic.)
 - #65124 (Replace some instances of `as *[const | mut] _` with `.cast()`)
 - #65126 (Fix typo on `now()` comments)
 - #65130 (lint: extern non-exhaustive types are improper)
 - #65151 (Revert #63649 - "Upgrade Emscripten targets to use upstream LLVM backend")

Failed merges:

r? @ghost
-rw-r--r--Cargo.lock2
-rw-r--r--config.toml.example1
-rw-r--r--src/bootstrap/builder.rs1
-rw-r--r--src/bootstrap/test.rs5
-rw-r--r--src/ci/docker/asmjs/Dockerfile29
-rw-r--r--src/ci/docker/disabled/wasm32-exp/Dockerfile35
-rwxr-xr-xsrc/ci/docker/disabled/wasm32-exp/node.sh9
-rw-r--r--src/ci/docker/disabled/wasm32/Dockerfile22
-rw-r--r--src/ci/docker/scripts/emscripten-wasm.sh37
-rw-r--r--src/ci/docker/scripts/emscripten.sh11
-rw-r--r--src/liballoc/tests/binary_heap.rs13
-rw-r--r--src/liballoc/tests/str.rs2
-rw-r--r--src/liballoc/tests/str.rs.rej10
-rw-r--r--src/liballoc/tests/vec.rs7
-rw-r--r--src/libcore/ffi.rs56
-rw-r--r--src/libcore/hint.rs16
-rw-r--r--src/libcore/option.rs8
-rw-r--r--src/libcore/slice/mod.rs1
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/librustc/error_codes.rs180
-rw-r--r--src/librustc/infer/opaque_types/mod.rs10
-rw-r--r--src/librustc/lib.rs5
-rw-r--r--src/librustc/mir/mod.rs4
-rw-r--r--src/librustc/mir/tcx.rs2
-rw-r--r--src/librustc/mir/visit.rs14
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/traits/mod.rs2
-rw-r--r--src/librustc/traits/project.rs2
-rw-r--r--src/librustc/traits/select.rs11
-rw-r--r--src/librustc/ty/context.rs4
-rw-r--r--src/librustc/ty/flags.rs2
-rw-r--r--src/librustc/ty/instance.rs4
-rw-r--r--src/librustc/ty/layout.rs19
-rw-r--r--src/librustc/ty/outlives.rs2
-rw-r--r--src/librustc/ty/print/obsolete.rs4
-rw-r--r--src/librustc/ty/print/pretty.rs4
-rw-r--r--src/librustc/ty/sty.rs17
-rw-r--r--src/librustc/ty/subst.rs10
-rw-r--r--src/librustc/ty/walk.rs6
-rw-r--r--src/librustc_codegen_llvm/allocator.rs4
-rw-r--r--src/librustc_codegen_llvm/back/lto.rs6
-rw-r--r--src/librustc_codegen_llvm/back/write.rs14
-rw-r--r--src/librustc_codegen_llvm/consts.rs6
-rw-r--r--src/librustc_codegen_llvm/context.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/gdb.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs24
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs6
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs3
-rw-r--r--src/librustc_codegen_llvm/type_of.rs2
-rw-r--r--src/librustc_codegen_ssa/back/write.rs7
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs2
-rw-r--r--src/librustc_codegen_utils/symbol_names/legacy.rs2
-rw-r--r--src/librustc_codegen_utils/symbol_names/v0.rs2
-rw-r--r--src/librustc_errors/diagnostic.rs105
-rw-r--r--src/librustc_errors/emitter.rs12
-rw-r--r--src/librustc_errors/lib.rs2
-rw-r--r--src/librustc_interface/passes.rs7
-rw-r--r--src/librustc_lint/types.rs27
-rw-r--r--src/librustc_metadata/decoder.rs2
-rw-r--r--src/librustc_mir/borrow_check/mod.rs12
-rw-r--r--src/librustc_mir/borrow_check/nll/constraint_generation.rs9
-rw-r--r--src/librustc_mir/borrow_check/nll/renumber.rs16
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs14
-rw-r--r--src/librustc_mir/borrow_check/nll/universal_regions.rs14
-rw-r--r--src/librustc_mir/build/mod.rs2
-rw-r--r--src/librustc_mir/interpret/intrinsics/type_name.rs3
-rw-r--r--src/librustc_mir/interpret/operand.rs12
-rw-r--r--src/librustc_mir/interpret/place.rs7
-rw-r--r--src/librustc_mir/shim.rs2
-rw-r--r--src/librustc_mir/transform/erase_regions.rs6
-rw-r--r--src/librustc_mir/transform/generator.rs1
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs2
-rw-r--r--src/librustc_passes/Cargo.toml2
-rw-r--r--src/librustc_passes/dead.rs (renamed from src/librustc/middle/dead.rs)24
-rw-r--r--src/librustc_passes/entry.rs (renamed from src/librustc/middle/entry.rs)16
-rw-r--r--src/librustc_passes/error_codes.rs182
-rw-r--r--src/librustc_passes/intrinsicck.rs (renamed from src/librustc/middle/intrinsicck.rs)14
-rw-r--r--src/librustc_passes/lib.rs11
-rw-r--r--src/librustc_passes/liveness.rs (renamed from src/librustc/middle/liveness.rs)26
-rw-r--r--src/librustc_resolve/lib.rs1
-rw-r--r--src/librustc_save_analysis/lib.rs1
-rw-r--r--src/librustc_target/abi/call/asmjs.rs47
-rw-r--r--src/librustc_target/abi/call/mod.rs13
-rw-r--r--src/librustc_target/abi/call/wasm32.rs52
-rw-r--r--src/librustc_target/abi/call/wasm32_bindgen_compat.rs27
-rw-r--r--src/librustc_target/spec/asmjs_unknown_emscripten.rs44
-rw-r--r--src/librustc_target/spec/mod.rs1
-rw-r--r--src/librustc_target/spec/wasm32_experimental_emscripten.rs44
-rw-r--r--src/librustc_target/spec/wasm32_unknown_emscripten.rs41
-rw-r--r--src/librustc_traits/dropck_outlives.rs2
-rw-r--r--src/librustc_traits/generic_types.rs8
-rw-r--r--src/librustc_typeck/check/closure.rs8
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/libstd/net/udp.rs4
-rw-r--r--src/libstd/panicking.rs34
-rw-r--r--src/libstd/rt.rs3
-rw-r--r--src/libstd/sys/unix/fast_thread_local.rs3
-rw-r--r--src/libstd/sys_common/backtrace.rs60
-rw-r--r--src/libstd/thread/mod.rs3
-rw-r--r--src/libstd/time.rs51
-rw-r--r--src/libsyntax/parse/diagnostics.rs163
-rw-r--r--src/libsyntax/parse/parser/expr.rs4
-rw-r--r--src/libsyntax/parse/parser/pat.rs6
-rw-r--r--src/libtest/lib.rs6
-rw-r--r--src/libtest/tests.rs11
-rw-r--r--src/test/codegen/c-variadic.rs1
-rw-r--r--src/test/codegen/drop.rs1
-rw-r--r--src/test/codegen/extern-functions.rs1
-rw-r--r--src/test/codegen/external-no-mangle-statics.rs1
-rw-r--r--src/test/codegen/link_section.rs1
-rw-r--r--src/test/codegen/no-output-asm-is-volatile.rs2
-rw-r--r--src/test/codegen/personality_lifetimes.rs1
-rw-r--r--src/test/codegen/repr-transparent-aggregates-2.rs3
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-log.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs1
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs2
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs160
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs6
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs1
-rw-r--r--src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs1
-rw-r--r--src/test/codegen/union-abi.rs1
-rw-r--r--src/test/compile-fail/weak-lang-item.rs2
-rw-r--r--src/test/incremental/change_crate_dep_kind.rs1
-rw-r--r--src/test/incremental/commandline-args.rs1
-rw-r--r--src/test/incremental/remapped_paths_cc/main.rs1
-rw-r--r--src/test/incremental/span_hash_stable/main.rs1
-rw-r--r--src/test/incremental/spans_in_type_debuginfo.rs1
-rw-r--r--src/test/incremental/spans_significant_w_debuginfo.rs1
-rw-r--r--src/test/mir-opt/box_expr.rs2
-rw-r--r--src/test/mir-opt/generator-storage-dead-unwind.rs2
-rw-r--r--src/test/mir-opt/issue-41110.rs2
-rw-r--r--src/test/mir-opt/issue-62289.rs2
-rw-r--r--src/test/mir-opt/no-spurious-drop-after-call.rs2
-rw-r--r--src/test/mir-opt/packed-struct-drop-aligned.rs2
-rw-r--r--src/test/mir-opt/remove_fake_borrows.rs2
-rw-r--r--src/test/mir-opt/retag.rs2
-rw-r--r--src/test/run-make/wasm-custom-section/Makefile2
-rw-r--r--src/test/run-make/wasm-custom-sections-opt/Makefile2
-rw-r--r--src/test/run-make/wasm-export-all-symbols/Makefile2
-rw-r--r--src/test/run-make/wasm-import-module/Makefile2
-rw-r--r--src/test/run-make/wasm-panic-small/Makefile2
-rw-r--r--src/test/run-make/wasm-symbols-not-exported/Makefile2
-rw-r--r--src/test/run-make/wasm-symbols-not-imported/Makefile2
-rw-r--r--src/test/ui/abi/statics/static-mut-foreign.rs4
-rw-r--r--src/test/ui/async-await/async-fn-size-moved-locals.rs2
-rw-r--r--src/test/ui/async-await/issue-60709.rs1
-rw-r--r--src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs2
-rw-r--r--src/test/ui/binding/match-arm-statics.rs1
-rw-r--r--src/test/ui/builtin-clone-unwind.rs2
-rw-r--r--src/test/ui/catch-unwind-bang.rs2
-rw-r--r--src/test/ui/consts/const-eval/issue-50814.rs1
-rw-r--r--src/test/ui/consts/const-eval/issue-50814.stderr12
-rw-r--r--src/test/ui/consts/const-eval/issue-64908.rs20
-rw-r--r--src/test/ui/consts/const-int-saturating-arith.rs1
-rw-r--r--src/test/ui/debuginfo-lto.rs1
-rw-r--r--src/test/ui/did_you_mean/issue-40396.rs10
-rw-r--r--src/test/ui/did_you_mean/issue-40396.stderr25
-rw-r--r--src/test/ui/drop/dynamic-drop-async.rs2
-rw-r--r--src/test/ui/drop/dynamic-drop.rs2
-rw-r--r--src/test/ui/extern/extern-const.fixed3
-rw-r--r--src/test/ui/extern/extern-const.rs3
-rw-r--r--src/test/ui/extern/extern-const.stderr2
-rw-r--r--src/test/ui/generator/issue-58888.rs1
-rw-r--r--src/test/ui/generator/panic-drops.rs2
-rw-r--r--src/test/ui/generator/panic-safe.rs2
-rw-r--r--src/test/ui/generator/resume-after-return.rs2
-rw-r--r--src/test/ui/generator/size-moved-locals.rs1
-rw-r--r--src/test/ui/intrinsics/intrinsics-integer.rs1
-rw-r--r--src/test/ui/issues/issue-14875.rs2
-rw-r--r--src/test/ui/issues/issue-23477.rs1
-rw-r--r--src/test/ui/issues/issue-24687-embed-debuginfo/main.rs1
-rw-r--r--src/test/ui/issues/issue-24945-repeat-dash-opts.rs1
-rw-r--r--src/test/ui/issues/issue-26484.rs1
-rw-r--r--src/test/ui/issues/issue-29948.rs2
-rw-r--r--src/test/ui/issues/issue-33096.rs1
-rw-r--r--src/test/ui/issues/issue-33992.rs2
-rw-r--r--src/test/ui/issues/issue-34569.rs1
-rw-r--r--src/test/ui/issues/issue-36856.rs1
-rw-r--r--src/test/ui/issues/issue-42210.rs1
-rw-r--r--src/test/ui/issues/issue-43853.rs2
-rw-r--r--src/test/ui/issues/issue-45731.rs1
-rw-r--r--src/test/ui/issues/issue-46519.rs2
-rw-r--r--src/test/ui/issues/issue-48508.rs1
-rw-r--r--src/test/ui/issues/issue-49579.rs1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr2
-rw-r--r--src/test/ui/issues/issue-52262.rs25
-rw-r--r--src/test/ui/issues/issue-52262.stderr9
-rw-r--r--src/test/ui/issues/issue-58463.rs2
-rw-r--r--src/test/ui/iterators/iter-count-overflow-debug.rs2
-rw-r--r--src/test/ui/iterators/iter-position-overflow-debug.rs2
-rw-r--r--src/test/ui/iterators/iter-step-overflow-debug.rs2
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-debug.rs2
-rw-r--r--src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs2
-rw-r--r--src/test/ui/macros/macro-comma-behavior-rpass.rs2
-rw-r--r--src/test/ui/mir/mir_calls_to_shims.rs2
-rw-r--r--src/test/ui/mir/mir_drop_order.rs2
-rw-r--r--src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs1
-rw-r--r--src/test/ui/numbers-arithmetic/i128.rs3
-rw-r--r--src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs2
-rw-r--r--src/test/ui/numbers-arithmetic/u128-as-f32.rs1
-rw-r--r--src/test/ui/numbers-arithmetic/u128.rs2
-rw-r--r--src/test/ui/panic-runtime/transitive-link-a-bunch.rs2
-rw-r--r--src/test/ui/panic-runtime/want-unwind-got-abort.rs2
-rw-r--r--src/test/ui/panic-runtime/want-unwind-got-abort2.rs2
-rw-r--r--src/test/ui/panic-uninitialized-zeroed.rs2
-rw-r--r--src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs26
-rw-r--r--src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr45
-rw-r--r--src/test/ui/parser/require-parens-for-chained-comparison.rs21
-rw-r--r--src/test/ui/parser/require-parens-for-chained-comparison.stderr30
-rw-r--r--src/test/ui/proc-macro/expand-with-a-macro.rs2
-rw-r--r--src/test/ui/reachable-unnameable-items.rs2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs31
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs24
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr47
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs46
-rw-r--r--src/test/ui/rfcs/rfc1857-drop-order.rs2
-rw-r--r--src/test/ui/sepcomp/sepcomp-lib-lto.rs1
-rw-r--r--src/test/ui/test-attrs/test-allow-fail-attr.rs2
-rw-r--r--src/test/ui/test-attrs/test-should-fail-good-message.rs2
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs1
-rw-r--r--src/tools/compiletest/src/header.rs5
-rw-r--r--triagebot.toml3
240 files changed, 1601 insertions, 966 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 80364515a7c..512dc5fd887 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3613,6 +3613,8 @@ dependencies = [
  "rustc",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_index",
+ "rustc_target",
  "syntax",
  "syntax_pos",
 ]
diff --git a/config.toml.example b/config.toml.example
index 2e3b714f922..848147c2974 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -377,7 +377,6 @@
 # but you can also optionally enable the "emscripten" backend for asm.js or
 # make this an empty array (but that probably won't get too far in the
 # bootstrap)
-# FIXME: remove the obsolete emscripten backend option.
 #codegen-backends = ["llvm"]
 
 # This is the name of the directory in which codegen backends will get installed
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 9b43bb0eff0..5d586f0c461 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -970,7 +970,6 @@ impl<'a> Builder<'a> {
                 Some("-Wl,-rpath,@loader_path/../lib")
             } else if !target.contains("windows") &&
                       !target.contains("wasm32") &&
-                      !target.contains("emscripten") &&
                       !target.contains("fuchsia") {
                 Some("-Wl,-rpath,$ORIGIN/../lib")
             } else {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index e09e25de64a..b7ce9c7b397 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1047,11 +1047,10 @@ impl Step for Compiletest {
         // Also provide `rust_test_helpers` for the host.
         builder.ensure(native::TestHelpers { target: compiler.host });
 
-        // As well as the target, except for plain wasm32, which can't build it
-        if !target.contains("wasm32") || target.contains("emscripten") {
+        // wasm32 can't build the test helpers
+        if !target.contains("wasm32") {
             builder.ensure(native::TestHelpers { target });
         }
-
         builder.ensure(RemoteCopyLibs { compiler, target });
 
         let mut cmd = builder.tool_cmd(Tool::Compiletest);
diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile
index d136fae79aa..3abaab6b34e 100644
--- a/src/ci/docker/asmjs/Dockerfile
+++ b/src/ci/docker/asmjs/Dockerfile
@@ -11,8 +11,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   cmake \
   sudo \
   gdb \
-  xz-utils \
-  bzip2
+  xz-utils
 
 COPY scripts/emscripten.sh /scripts/
 RUN bash /scripts/emscripten.sh
@@ -21,16 +20,28 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/
-ENV PATH=$PATH:/emsdk-portable/node/12.9.1_64bit/bin/
-ENV BINARYEN_ROOT=/emsdk-portable/upstream/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
 ENV EM_CONFIG=/emsdk-portable/.emscripten
 
 ENV TARGETS=asmjs-unknown-emscripten
 
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS
+ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests
 
-# This is almost identical to the wasm32-unknown-emscripten target, so
-# running with assertions again is not useful
-ENV NO_DEBUG_ASSERTIONS=1
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
+  src/test/ui \
+  src/test/run-fail \
+  src/libstd \
+  src/liballoc \
+  src/libcore
+
+# Debug assertions in rustc are largely covered by other builders, and LLVM
+# assertions cause this builder to slow down by quite a large amount and don't
+# buy us a huge amount over other builders (not sure if we've ever seen an
+# asmjs-specific backend assertion trip), so disable assertions for these
+# tests.
 ENV NO_LLVM_ASSERTIONS=1
+ENV NO_DEBUG_ASSERTIONS=1
diff --git a/src/ci/docker/disabled/wasm32-exp/Dockerfile b/src/ci/docker/disabled/wasm32-exp/Dockerfile
new file mode 100644
index 00000000000..420d47b314c
--- /dev/null
+++ b/src/ci/docker/disabled/wasm32-exp/Dockerfile
@@ -0,0 +1,35 @@
+FROM ubuntu:16.04
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  g++ \
+  make \
+  file \
+  curl \
+  ca-certificates \
+  python \
+  git \
+  cmake \
+  sudo \
+  gdb \
+  xz-utils \
+  jq \
+  bzip2
+
+# emscripten
+COPY scripts/emscripten-wasm.sh /scripts/
+COPY wasm32-exp/node.sh /usr/local/bin/node
+RUN bash /scripts/emscripten-wasm.sh
+
+# cache
+COPY scripts/sccache.sh /scripts/
+RUN sh /scripts/sccache.sh
+
+# env
+ENV PATH=/wasm-install/emscripten:/wasm-install/bin:$PATH
+ENV EM_CONFIG=/root/.emscripten
+
+ENV TARGETS=wasm32-experimental-emscripten
+
+ENV RUST_CONFIGURE_ARGS --experimental-targets=WebAssembly
+
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS
diff --git a/src/ci/docker/disabled/wasm32-exp/node.sh b/src/ci/docker/disabled/wasm32-exp/node.sh
new file mode 100755
index 00000000000..aa938971c70
--- /dev/null
+++ b/src/ci/docker/disabled/wasm32-exp/node.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+path="$(dirname $1)"
+file="$(basename $1)"
+
+shift
+
+cd "$path"
+exec /node-v8.0.0-linux-x64/bin/node "$file" "$@"
diff --git a/src/ci/docker/disabled/wasm32/Dockerfile b/src/ci/docker/disabled/wasm32/Dockerfile
index b2cf862c0a5..0d2bd39303e 100644
--- a/src/ci/docker/disabled/wasm32/Dockerfile
+++ b/src/ci/docker/disabled/wasm32/Dockerfile
@@ -11,9 +11,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   cmake \
   sudo \
   gdb \
-  xz-utils \
-  bzip2
+  xz-utils
 
+# emscripten
 COPY scripts/emscripten.sh /scripts/
 RUN bash /scripts/emscripten.sh
 
@@ -21,18 +21,12 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/upstream/emscripten/
-ENV PATH=$PATH:/emsdk-portable/node/12.9.1_64bit/bin/
-ENV BINARYEN_ROOT=/emsdk-portable/upstream/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
 ENV EM_CONFIG=/emsdk-portable/.emscripten
 
 ENV TARGETS=wasm32-unknown-emscripten
-
-# FIXME: Re-enable these tests once Cargo stops trying to execute wasms
-ENV SCRIPT python2.7 ../x.py test --target $TARGETS \
-    --exclude src/libcore \
-    --exclude src/liballoc \
-    --exclude src/libproc_macro \
-    --exclude src/libstd \
-    --exclude src/libterm \
-    --exclude src/libtest
+ENV SCRIPT python2.7 ../x.py test --target $TARGETS
diff --git a/src/ci/docker/scripts/emscripten-wasm.sh b/src/ci/docker/scripts/emscripten-wasm.sh
new file mode 100644
index 00000000000..e4a93d7a100
--- /dev/null
+++ b/src/ci/docker/scripts/emscripten-wasm.sh
@@ -0,0 +1,37 @@
+set -ex
+
+hide_output() {
+  set +x
+  on_err="
+echo ERROR: An error was encountered with the build.
+cat /tmp/build.log
+exit 1
+"
+  trap "$on_err" ERR
+  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
+  PING_LOOP_PID=$!
+  $@ &> /tmp/build.log
+  trap - ERR
+  kill $PING_LOOP_PID
+  rm -f /tmp/build.log
+  set -x
+}
+
+# Download last known good emscripten from WebAssembly waterfall
+BUILD=$(curl -fL https://storage.googleapis.com/wasm-llvm/builds/linux/lkgr.json | \
+    jq '.build | tonumber')
+curl -sL https://storage.googleapis.com/wasm-llvm/builds/linux/$BUILD/wasm-binaries.tbz2 | \
+    hide_output tar xvkj
+
+# node 8 is required to run wasm
+cd /
+curl -sL https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
+    tar -xJ
+
+# Make emscripten use wasm-ready node and LLVM tools
+echo "EMSCRIPTEN_ROOT = '/wasm-install/emscripten'" >> /root/.emscripten
+echo "NODE_JS='/usr/local/bin/node'" >> /root/.emscripten
+echo "LLVM_ROOT='/wasm-install/bin'" >> /root/.emscripten
+echo "BINARYEN_ROOT = '/wasm-install'" >> /root/.emscripten
+echo "COMPILER_ENGINE = NODE_JS" >> /root/.emscripten
+echo "JS_ENGINES = [NODE_JS]" >> /root/.emscripten
diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh
index 9c7a09e227a..47196e89396 100644
--- a/src/ci/docker/scripts/emscripten.sh
+++ b/src/ci/docker/scripts/emscripten.sh
@@ -17,15 +17,20 @@ exit 1
   set -x
 }
 
-git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
+cd /
+curl -fL https://mozilla-games.s3.amazonaws.com/emscripten/releases/emsdk-portable.tar.gz | \
+    tar -xz
+
 cd /emsdk-portable
-hide_output ./emsdk install 1.38.46-upstream
-./emsdk activate 1.38.46-upstream
+./emsdk update
+hide_output ./emsdk install sdk-1.38.15-64bit
+./emsdk activate sdk-1.38.15-64bit
 
 # Compile and cache libc
 source ./emsdk_env.sh
 echo "main(){}" > a.c
 HOME=/emsdk-portable/ emcc a.c
+HOME=/emsdk-portable/ emcc -s BINARYEN=1 a.c
 rm -f a.*
 
 # Make emsdk usable by any user
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index b8c720264d0..0685fa943c0 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -1,5 +1,10 @@
+use std::cmp;
 use std::collections::BinaryHeap;
 use std::collections::binary_heap::{Drain, PeekMut};
+use std::panic::{self, AssertUnwindSafe};
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+use rand::{thread_rng, seq::SliceRandom};
 
 #[test]
 fn test_iterator() {
@@ -276,15 +281,9 @@ fn assert_covariance() {
 // even if the order may not be correct.
 //
 // Destructors must be called exactly once per element.
-// FIXME: re-enable emscripten once it can unwind again
 #[test]
-#[cfg(not(any(miri, target_os = "emscripten")))] // Miri does not support catching panics
+#[cfg(not(miri))] // Miri does not support catching panics
 fn panic_safe() {
-    use std::cmp;
-    use std::panic::{self, AssertUnwindSafe};
-    use std::sync::atomic::{AtomicUsize, Ordering};
-    use rand::{thread_rng, seq::SliceRandom};
-
     static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
 
     #[derive(Eq, PartialEq, Ord, Clone, Debug)]
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index cb73c7c179c..4332b2e90fd 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -483,7 +483,7 @@ mod slice_index {
     }
 
     #[test]
-    #[cfg(not(target_os = "emscripten"))] // hits an OOM
+    #[cfg(not(target_arch = "asmjs"))] // hits an OOM
     #[cfg(not(miri))] // Miri is too slow
     fn simple_big() {
         fn a_million_letter_x() -> String {
diff --git a/src/liballoc/tests/str.rs.rej b/src/liballoc/tests/str.rs.rej
deleted file mode 100644
index abcba0c2e84..00000000000
--- a/src/liballoc/tests/str.rs.rej
+++ /dev/null
@@ -1,10 +0,0 @@
-diff a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs	(rejected hunks)
-@@ -483,7 +483,7 @@ mod slice_index {
-     }
- 
-     #[test]
--    #[cfg(not(target_arch = "asmjs"))] // hits an OOM
-+    #[cfg(not(target_arch = "js"))] // hits an OOM
-     #[cfg(not(miri))] // Miri is too slow
-     fn simple_big() {
-         fn a_million_letter_x() -> String {
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 80537217697..98d013dfa2b 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -944,10 +944,8 @@ fn drain_filter_complex() {
     }
 }
 
-// Miri does not support catching panics
-// FIXME: re-enable emscripten once it can unwind again
 #[test]
-#[cfg(not(any(miri, target_os = "emscripten")))]
+#[cfg(not(miri))] // Miri does not support catching panics
 fn drain_filter_consumed_panic() {
     use std::rc::Rc;
     use std::sync::Mutex;
@@ -997,9 +995,8 @@ fn drain_filter_consumed_panic() {
     }
 }
 
-// FIXME: Re-enable emscripten once it can catch panics
 #[test]
-#[cfg(not(any(miri, target_os = "emscripten")))] // Miri does not support catching panics
+#[cfg(not(miri))] // Miri does not support catching panics
 fn drain_filter_unconsumed_panic() {
     use std::rc::Rc;
     use std::sync::Mutex;
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index 0ea4187ccd4..eda0e7c518c 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -49,10 +49,8 @@ impl fmt::Debug for c_void {
 /// Basic implementation of a `va_list`.
 // The name is WIP, using `VaListImpl` for now.
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-              not(target_arch = "x86_64")),
+              not(target_arch = "x86_64"), not(target_arch = "asmjs")),
           all(target_arch = "aarch64", target_os = "ios"),
-          target_arch = "wasm32",
-          target_arch = "asmjs",
           windows))]
 #[repr(transparent)]
 #[unstable(feature = "c_variadic",
@@ -69,10 +67,8 @@ pub struct VaListImpl<'f> {
 }
 
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-              not(target_arch = "x86_64")),
+              not(target_arch = "x86_64"), not(target_arch = "asmjs")),
           all(target_arch = "aarch64", target_os = "ios"),
-          target_arch = "wasm32",
-          target_arch = "asmjs",
           windows))]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
@@ -141,6 +137,38 @@ pub struct VaListImpl<'f> {
     _marker: PhantomData<&'f mut &'f c_void>,
 }
 
+/// asm.js ABI implementation of a `va_list`.
+// asm.js uses the PNaCl ABI, which specifies that a `va_list` is
+// an array of 4 32-bit integers, according to the old PNaCl docs at
+// https://web.archive.org/web/20130518054430/https://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Derived-Types
+// and clang does the same in `CreatePNaClABIBuiltinVaListDecl` from `lib/AST/ASTContext.cpp`
+#[cfg(all(target_arch = "asmjs", not(windows)))]
+#[repr(C)]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+#[lang = "va_list"]
+pub struct VaListImpl<'f> {
+    inner: [crate::mem::MaybeUninit<i32>; 4],
+    _marker: PhantomData<&'f mut &'f c_void>,
+}
+
+#[cfg(all(target_arch = "asmjs", not(windows)))]
+#[unstable(feature = "c_variadic",
+           reason = "the `c_variadic` feature has not been properly tested on \
+                     all supported platforms",
+           issue = "44930")]
+impl<'f> fmt::Debug for VaListImpl<'f> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        unsafe {
+            write!(f, "va_list* [{:#x}, {:#x}, {:#x}, {:#x}]",
+                   self.inner[0].read(), self.inner[1].read(),
+                   self.inner[2].read(), self.inner[3].read())
+        }
+    }
+}
+
 /// A wrapper for a `va_list`
 #[repr(transparent)]
 #[derive(Debug)]
@@ -150,18 +178,14 @@ pub struct VaListImpl<'f> {
            issue = "44930")]
 pub struct VaList<'a, 'f: 'a> {
     #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-                  not(target_arch = "x86_64")),
+                  not(target_arch = "x86_64"), not(target_arch = "asmjs")),
               all(target_arch = "aarch64", target_os = "ios"),
-              target_arch = "wasm32",
-              target_arch = "asmjs",
               windows))]
     inner: VaListImpl<'f>,
 
     #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
-                  target_arch = "x86_64"),
+                  target_arch = "x86_64", target_arch = "asmjs"),
               any(not(target_arch = "aarch64"), not(target_os = "ios")),
-              not(target_arch = "wasm32"),
-              not(target_arch = "asmjs"),
               not(windows)))]
     inner: &'a mut VaListImpl<'f>,
 
@@ -169,10 +193,8 @@ pub struct VaList<'a, 'f: 'a> {
 }
 
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
-              not(target_arch = "x86_64")),
+              not(target_arch = "x86_64"), not(target_arch = "asmjs")),
           all(target_arch = "aarch64", target_os = "ios"),
-          target_arch = "wasm32",
-          target_arch = "asmjs",
           windows))]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
@@ -190,10 +212,8 @@ impl<'f> VaListImpl<'f> {
 }
 
 #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc",
-              target_arch = "x86_64"),
+              target_arch = "x86_64", target_arch = "asmjs"),
           any(not(target_arch = "aarch64"), not(target_os = "ios")),
-          not(target_arch = "wasm32"),
-          not(target_arch = "asmjs"),
           not(windows)))]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 368a2f16b28..ee4be6c9151 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -114,8 +114,24 @@ pub fn black_box<T>(dummy: T) -> T {
     // this. LLVM's intepretation of inline assembly is that it's, well, a black
     // box. This isn't the greatest implementation since it probably deoptimizes
     // more than we want, but it's so far good enough.
+    #[cfg(not(any(
+        target_arch = "asmjs",
+        all(
+            target_arch = "wasm32",
+            target_os = "emscripten"
+        )
+    )))]
     unsafe {
         asm!("" : : "r"(&dummy));
         return dummy;
     }
+
+    // Not all platforms support inline assembly so try to do something without
+    // inline assembly which in theory still hinders at least some optimizations
+    // on those targets. This is the "best effort" scenario.
+    unsafe {
+        let ret = crate::ptr::read_volatile(&dummy);
+        crate::mem::forget(dummy);
+        ret
+    }
 }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 301e432c98d..47e3a0d2167 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1102,7 +1102,6 @@ impl<T: Default> Option<T> {
     }
 }
 
-#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref> Option<T> {
     /// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
     ///
@@ -1114,20 +1113,18 @@ impl<T: Deref> Option<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(inner_deref)]
-    ///
     /// let x: Option<String> = Some("hey".to_owned());
     /// assert_eq!(x.as_deref(), Some("hey"));
     ///
     /// let x: Option<String> = None;
     /// assert_eq!(x.as_deref(), None);
     /// ```
+    #[stable(feature = "option_deref", since = "1.40.0")]
     pub fn as_deref(&self) -> Option<&T::Target> {
         self.as_ref().map(|t| t.deref())
     }
 }
 
-#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: DerefMut> Option<T> {
     /// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
     ///
@@ -1137,14 +1134,13 @@ impl<T: DerefMut> Option<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(inner_deref)]
-    ///
     /// let mut x: Option<String> = Some("hey".to_owned());
     /// assert_eq!(x.as_deref_mut().map(|x| {
     ///     x.make_ascii_uppercase();
     ///     x
     /// }), Some("HEY".to_owned().as_mut_str()));
     /// ```
+    #[stable(feature = "option_deref", since = "1.40.0")]
     pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
         self.as_mut().map(|t| t.deref_mut())
     }
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index b5462d98837..4e79ea81204 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -63,6 +63,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     // SAFETY: const sound because we transmute out the length field as a usize (which it must be)
+    #[allow(unused_attributes)]
     #[allow_internal_unstable(const_fn_union)]
     pub const fn len(&self) -> usize {
         unsafe {
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index ece61dde490..885696e5acf 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2167,6 +2167,7 @@ impl str {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline(always)]
     // SAFETY: const sound because we transmute two types with the same layout
+    #[allow(unused_attributes)]
     #[allow_internal_unstable(const_fn_union)]
     pub const fn as_bytes(&self) -> &[u8] {
         #[repr(C)]
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 968b0b9f2f2..66c51000066 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -466,66 +466,6 @@ fn main() {
 ```
 "##,
 
-// This shouldn't really ever trigger since the repeated value error comes first
-E0136: r##"
-A binary can only have one entry point, and by default that entry point is the
-function `main()`. If there are multiple such functions, please rename one.
-"##,
-
-E0137: r##"
-More than one function was declared with the `#[main]` attribute.
-
-Erroneous code example:
-
-```compile_fail,E0137
-#![feature(main)]
-
-#[main]
-fn foo() {}
-
-#[main]
-fn f() {} // error: multiple functions with a `#[main]` attribute
-```
-
-This error indicates that the compiler found multiple functions with the
-`#[main]` attribute. This is an error because there must be a unique entry
-point into a Rust program. Example:
-
-```
-#![feature(main)]
-
-#[main]
-fn f() {} // ok!
-```
-"##,
-
-E0138: r##"
-More than one function was declared with the `#[start]` attribute.
-
-Erroneous code example:
-
-```compile_fail,E0138
-#![feature(start)]
-
-#[start]
-fn foo(argc: isize, argv: *const *const u8) -> isize {}
-
-#[start]
-fn f(argc: isize, argv: *const *const u8) -> isize {}
-// error: multiple 'start' functions
-```
-
-This error indicates that the compiler found multiple functions with the
-`#[start]` attribute. This is an error because there must be a unique entry
-point into a Rust program. Example:
-
-```
-#![feature(start)]
-
-#[start]
-fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
-```
-"##,
 
 E0139: r##"
 #### Note: this error code is no longer emitted by the compiler.
@@ -1626,33 +1566,6 @@ It is not possible to use stability attributes outside of the standard library.
 Also, for now, it is not possible to write deprecation messages either.
 "##,
 
-E0512: r##"
-Transmute with two differently sized types was attempted. Erroneous code
-example:
-
-```compile_fail,E0512
-fn takes_u8(_: u8) {}
-
-fn main() {
-    unsafe { takes_u8(::std::mem::transmute(0u16)); }
-    // error: cannot transmute between types of different sizes,
-    //        or dependently-sized types
-}
-```
-
-Please use types with same size or use the expected type directly. Example:
-
-```
-fn takes_u8(_: u8) {}
-
-fn main() {
-    unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok!
-    // or:
-    unsafe { takes_u8(0u8); } // ok!
-}
-```
-"##,
-
 E0517: r##"
 This error indicates that a `#[repr(..)]` attribute was placed on an
 unsupported item.
@@ -1847,84 +1760,6 @@ See [RFC 1522] for more details.
 [RFC 1522]: https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
 "##,
 
-E0591: r##"
-Per [RFC 401][rfc401], if you have a function declaration `foo`:
-
-```
-// For the purposes of this explanation, all of these
-// different kinds of `fn` declarations are equivalent:
-struct S;
-fn foo(x: S) { /* ... */ }
-# #[cfg(for_demonstration_only)]
-extern "C" { fn foo(x: S); }
-# #[cfg(for_demonstration_only)]
-impl S { fn foo(self) { /* ... */ } }
-```
-
-the type of `foo` is **not** `fn(S)`, as one might expect.
-Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`.
-However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`,
-so you rarely notice this:
-
-```
-# struct S;
-# fn foo(_: S) {}
-let x: fn(S) = foo; // OK, coerces
-```
-
-The reason that this matter is that the type `fn(S)` is not specific to
-any particular function: it's a function _pointer_. So calling `x()` results
-in a virtual call, whereas `foo()` is statically dispatched, because the type
-of `foo` tells us precisely what function is being called.
-
-As noted above, coercions mean that most code doesn't have to be
-concerned with this distinction. However, you can tell the difference
-when using **transmute** to convert a fn item into a fn pointer.
-
-This is sometimes done as part of an FFI:
-
-```compile_fail,E0591
-extern "C" fn foo(userdata: Box<i32>) {
-    /* ... */
-}
-
-# fn callback(_: extern "C" fn(*mut i32)) {}
-# use std::mem::transmute;
-# unsafe {
-let f: extern "C" fn(*mut i32) = transmute(foo);
-callback(f);
-# }
-```
-
-Here, transmute is being used to convert the types of the fn arguments.
-This pattern is incorrect because, because the type of `foo` is a function
-**item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
-is a function pointer, which is not zero-sized.
-This pattern should be rewritten. There are a few possible ways to do this:
-
-- change the original fn declaration to match the expected signature,
-  and do the cast in the fn body (the preferred option)
-- cast the fn item fo a fn pointer before calling transmute, as shown here:
-
-    ```
-    # extern "C" fn foo(_: Box<i32>) {}
-    # use std::mem::transmute;
-    # unsafe {
-    let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
-    let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
-    # }
-    ```
-
-The same applies to transmutes to `*mut fn()`, which were observed in practice.
-Note though that use of this type is generally incorrect.
-The intention is typically to describe a function pointer, but just `fn()`
-alone suffices for that. `*mut fn()` is a pointer to a fn pointer.
-(Since these values are typically just passed to C code, however, this rarely
-makes a difference in practice.)
-
-[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
-"##,
-
 E0593: r##"
 You tried to supply an `Fn`-based type with an incorrect number of arguments
 than what was expected.
@@ -1941,21 +1776,6 @@ fn main() {
 ```
 "##,
 
-E0601: r##"
-No `main` function was found in a binary crate. To fix this error, add a
-`main` function. For example:
-
-```
-fn main() {
-    // Your program will start here.
-    println!("Hello world!");
-}
-```
-
-If you don't know the basics of Rust, you can go look to the Rust Book to get
-started: https://doc.rust-lang.org/book/
-"##,
-
 E0602: r##"
 An unknown lint was used on the command line.
 
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index e7205dd47a6..bd19a002fe8 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -733,12 +733,12 @@ where
                 // Skip lifetime parameters of the enclosing item(s)
                 // Also skip the witness type, because that has no free regions.
 
-                for upvar_ty in substs.upvar_tys(def_id, self.tcx) {
+                for upvar_ty in substs.as_generator().upvar_tys(def_id, self.tcx) {
                     upvar_ty.visit_with(self);
                 }
 
-                substs.return_ty(def_id, self.tcx).visit_with(self);
-                substs.yield_ty(def_id, self.tcx).visit_with(self);
+                substs.as_generator().return_ty(def_id, self.tcx).visit_with(self);
+                substs.as_generator().yield_ty(def_id, self.tcx).visit_with(self);
             }
             _ => {
                 ty.super_visit_with(self);
@@ -902,7 +902,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
             ty::Generator(def_id, substs, movability) => {
                 let generics = self.tcx.generics_of(def_id);
                 let substs =
-                    self.tcx.mk_substs(substs.substs.iter().enumerate().map(|(index, &kind)| {
+                    self.tcx.mk_substs(substs.iter().enumerate().map(|(index, &kind)| {
                         if index < generics.parent_count {
                             // Accommodate missing regions in the parent kinds...
                             self.fold_kind_mapping_missing_regions_to_empty(kind)
@@ -912,7 +912,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
                         }
                     }));
 
-                self.tcx.mk_generator(def_id, ty::GeneratorSubsts { substs }, movability)
+                self.tcx.mk_generator(def_id, substs, movability)
             }
 
             ty::Param(..) => {
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index bd9899b644b..9c3cb3af9e7 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -35,7 +35,6 @@
 #![feature(const_transmute)]
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
-#![feature(inner_deref)]
 #![cfg_attr(windows, feature(libc))]
 #![feature(never_type)]
 #![feature(exhaustive_patterns)]
@@ -102,16 +101,12 @@ pub mod lint;
 pub mod middle {
     pub mod expr_use_visitor;
     pub mod cstore;
-    pub mod dead;
     pub mod dependency_format;
     pub mod diagnostic_items;
-    pub mod entry;
     pub mod exported_symbols;
     pub mod free_region;
-    pub mod intrinsicck;
     pub mod lib_features;
     pub mod lang_items;
-    pub mod liveness;
     pub mod mem_categorization;
     pub mod privacy;
     pub mod reachable;
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 59b4f240733..2b5212cb7ef 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -15,7 +15,7 @@ use crate::ty::layout::VariantIdx;
 use crate::ty::print::{FmtPrinter, Printer};
 use crate::ty::subst::{Subst, SubstsRef};
 use crate::ty::{
-    self, AdtDef, CanonicalUserTypeAnnotations, GeneratorSubsts, Region, Ty, TyCtxt,
+    self, AdtDef, CanonicalUserTypeAnnotations, Region, Ty, TyCtxt,
     UserTypeAnnotationIndex,
 };
 
@@ -2189,7 +2189,7 @@ pub enum AggregateKind<'tcx> {
     Adt(&'tcx AdtDef, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
 
     Closure(DefId, SubstsRef<'tcx>),
-    Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 26f718e858d..e87aabf9a05 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -197,7 +197,7 @@ impl<'tcx> Rvalue<'tcx> {
                 let ty = place.ty(local_decls, tcx).ty;
                 match ty.kind {
                     ty::Adt(adt_def, _) => adt_def.repr.discr_type().to_ty(tcx),
-                    ty::Generator(_, substs, _) => substs.discr_ty(tcx),
+                    ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
                     _ => {
                         // This can only be `0`, for now, so `u8` will suffice.
                         tcx.types.u8
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index ed8086b8faf..edc7922f46e 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -1,5 +1,5 @@
 use crate::ty::subst::SubstsRef;
-use crate::ty::{CanonicalUserTypeAnnotation, GeneratorSubsts, Ty};
+use crate::ty::{CanonicalUserTypeAnnotation, Ty};
 use crate::mir::*;
 use syntax_pos::Span;
 
@@ -230,12 +230,6 @@ macro_rules! make_mir_visitor {
                 self.super_substs(substs);
             }
 
-            fn visit_generator_substs(&mut self,
-                                      substs: & $($mutability)? GeneratorSubsts<'tcx>,
-                                    _: Location) {
-                self.super_generator_substs(substs);
-            }
-
             fn visit_local_decl(&mut self,
                                 local: Local,
                                 local_decl: & $($mutability)? LocalDecl<'tcx>) {
@@ -628,7 +622,7 @@ macro_rules! make_mir_visitor {
                                 generator_substs,
                                 _movability,
                             ) => {
-                                self.visit_generator_substs(generator_substs, location);
+                                self.visit_substs(generator_substs, location);
                             }
                         }
 
@@ -846,10 +840,6 @@ macro_rules! make_mir_visitor {
             fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
             }
 
-            fn super_generator_substs(&mut self,
-                                      _substs: & $($mutability)? GeneratorSubsts<'tcx>) {
-            }
-
             // Convenience methods
 
             fn visit_location(&mut self, body: & $($mutability)? Body<'tcx>, location: Location) {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2771ce69b9e..b48353e7330 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1345,7 +1345,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     mir_opt_level: usize = (1, parse_uint, [TRACKED],
         "set the MIR optimization level (0-3, default: 1)"),
     mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "emit noalias metadata for mutable references (default: yes on LLVM >= 6)"),
+        "emit noalias metadata for mutable references (default: no)"),
     dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "dump MIR state to file.
         `val` is used to select which passes and functions to dump. For example:
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 7f194c2fbbc..d96330bf0a9 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -610,7 +610,7 @@ pub struct VtableImplData<'tcx, N> {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
 pub struct VtableGeneratorData<'tcx, N> {
     pub generator_def_id: DefId,
-    pub substs: ty::GeneratorSubsts<'tcx>,
+    pub substs: SubstsRef<'tcx>,
     /// Nested obligations. This can be non-empty if the generator
     /// signature contains associated types.
     pub nested: Vec<N>
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index a7bb29c699e..5b4ec885d77 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1259,7 +1259,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
     obligation: &ProjectionTyObligation<'tcx>,
     vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>,
 ) -> Progress<'tcx> {
-    let gen_sig = vtable.substs.poly_sig(vtable.generator_def_id, selcx.tcx());
+    let gen_sig = vtable.substs.as_generator().poly_sig(vtable.generator_def_id, selcx.tcx());
     let Normalized {
         value: gen_sig,
         obligations
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 1fae2a2fe8d..4ee5700f43f 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2761,8 +2761,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 .collect(),
 
             ty::Generator(def_id, ref substs, _) => {
-                let witness = substs.witness(def_id, self.tcx());
+                let witness = substs.as_generator().witness(def_id, self.tcx());
                 substs
+                    .as_generator()
                     .upvar_tys(def_id, self.tcx())
                     .chain(iter::once(witness))
                     .collect()
@@ -3324,8 +3325,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         )?);
 
         Ok(VtableGeneratorData {
-            generator_def_id: generator_def_id,
-            substs: substs.clone(),
+            generator_def_id,
+            substs,
             nested: obligations,
         })
     }
@@ -3911,9 +3912,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         obligation: &TraitObligation<'tcx>,
         closure_def_id: DefId,
-        substs: ty::GeneratorSubsts<'tcx>,
+        substs: SubstsRef<'tcx>,
     ) -> ty::PolyTraitRef<'tcx> {
-        let gen_sig = substs.poly_sig(closure_def_id, self.tcx());
+        let gen_sig = substs.as_generator().poly_sig(closure_def_id, self.tcx());
 
         // (1) Feels icky to skip the binder here, but OTOH we know
         // that the self-type is an generator type and hence is
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5aad6c1dc18..eb380eb12d8 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -29,7 +29,7 @@ use crate::traits;
 use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals};
 use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
 use crate::ty::{TyS, TyKind, List};
-use crate::ty::{AdtKind, AdtDef, GeneratorSubsts, Region, Const};
+use crate::ty::{AdtKind, AdtDef, Region, Const};
 use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
 use crate::ty::RegionKind;
 use crate::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid, ConstVid};
@@ -2510,7 +2510,7 @@ impl<'tcx> TyCtxt<'tcx> {
     #[inline]
     pub fn mk_generator(self,
                         id: DefId,
-                        generator_substs: GeneratorSubsts<'tcx>,
+                        generator_substs: SubstsRef<'tcx>,
                         movability: hir::GeneratorMovability)
                         -> Ty<'tcx> {
         self.mk_ty(Generator(id, generator_substs, movability))
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index b513ef5a966..4ff5e1a7b8d 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -94,7 +94,7 @@ impl FlagComputation {
             &ty::Generator(_, ref substs, _) => {
                 self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                 self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
-                self.add_substs(&substs.substs);
+                self.add_substs(substs);
             }
 
             &ty::GeneratorWitness(ref ts) => {
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 34f806b15c0..93a8341e746 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -71,7 +71,7 @@ impl<'tcx> Instance<'tcx> {
                 ))
             }
             ty::Generator(def_id, substs, _) => {
-                let sig = substs.poly_sig(def_id, tcx);
+                let sig = substs.as_generator().poly_sig(def_id, tcx);
 
                 let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
                 let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
@@ -395,7 +395,7 @@ fn resolve_associated_item<'tcx>(
         traits::VtableGenerator(generator_data) => {
             Some(Instance {
                 def: ty::InstanceDef::Item(generator_data.generator_def_id),
-                substs: generator_data.substs.substs
+                substs: generator_data.substs
             })
         }
         traits::VtableClosure(closure_data) => {
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 6e01e1bf26a..ce7e1822d9a 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1,5 +1,5 @@
 use crate::session::{self, DataTypeKind};
-use crate::ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
+use crate::ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions, subst::SubstsRef};
 
 use syntax::ast::{self, Ident, IntTy, UintTy};
 use syntax::attr;
@@ -15,7 +15,6 @@ use std::ops::Bound;
 use crate::hir;
 use crate::ich::StableHashingContext;
 use crate::mir::{GeneratorLayout, GeneratorSavedLocal};
-use crate::ty::GeneratorSubsts;
 use crate::ty::subst::Subst;
 use rustc_index::bit_set::BitSet;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -671,7 +670,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 tcx.intern_layout(unit)
             }
 
-            ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, &substs)?,
+            ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?,
 
             ty::Closure(def_id, ref substs) => {
                 let tys = substs.as_closure().upvar_tys(def_id, tcx);
@@ -1406,12 +1405,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         &self,
         ty: Ty<'tcx>,
         def_id: hir::def_id::DefId,
-        substs: &GeneratorSubsts<'tcx>,
+        substs: SubstsRef<'tcx>,
     ) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
         use SavedLocalEligibility::*;
         let tcx = self.tcx;
 
-        let subst_field = |ty: Ty<'tcx>| { ty.subst(tcx, substs.substs) };
+        let subst_field = |ty: Ty<'tcx>| { ty.subst(tcx, substs) };
 
         let info = tcx.generator_layout(def_id);
         let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info);
@@ -1419,9 +1418,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         // Build a prefix layout, including "promoting" all ineligible
         // locals as part of the prefix. We compute the layout of all of
         // these fields at once to get optimal packing.
-        let discr_index = substs.prefix_tys(def_id, tcx).count();
+        let discr_index = substs.as_generator().prefix_tys(def_id, tcx).count();
         // FIXME(eddyb) set the correct vaidity range for the discriminant.
-        let discr_layout = self.layout_of(substs.discr_ty(tcx))?;
+        let discr_layout = self.layout_of(substs.as_generator().discr_ty(tcx))?;
         let discr = match &discr_layout.abi {
             Abi::Scalar(s) => s.clone(),
             _ => bug!(),
@@ -1430,7 +1429,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             .map(|local| subst_field(info.field_tys[local]))
             .map(|ty| tcx.mk_maybe_uninit(ty))
             .map(|ty| self.layout_of(ty));
-        let prefix_layouts = substs.prefix_tys(def_id, tcx)
+        let prefix_layouts = substs.as_generator().prefix_tys(def_id, tcx)
             .map(|ty| self.layout_of(ty))
             .chain(iter::once(Ok(discr_layout)))
             .chain(promoted_layouts)
@@ -2153,7 +2152,7 @@ where
             ty::Generator(def_id, ref substs, _) => {
                 match this.variants {
                     Variants::Single { index } => {
-                        substs.state_tys(def_id, tcx)
+                        substs.as_generator().state_tys(def_id, tcx)
                             .nth(index.as_usize()).unwrap()
                             .nth(i).unwrap()
                     }
@@ -2161,7 +2160,7 @@ where
                         if i == discr_index {
                             return discr_layout(discr);
                         }
-                        substs.prefix_tys(def_id, tcx).nth(i).unwrap()
+                        substs.as_generator().prefix_tys(def_id, tcx).nth(i).unwrap()
                     }
                 }
             }
diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs
index 3ea767d5115..80e77cdfad0 100644
--- a/src/librustc/ty/outlives.rs
+++ b/src/librustc/ty/outlives.rs
@@ -69,7 +69,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
             ty::Generator(def_id, ref substs, _) => {
                 // Same as the closure case
-                for upvar_ty in substs.upvar_tys(def_id, *self) {
+                for upvar_ty in substs.as_generator().upvar_tys(def_id, *self) {
                     self.compute_components(upvar_ty, out);
                 }
 
diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs
index 21c018d9ee6..df39d0ccc9e 100644
--- a/src/librustc/ty/print/obsolete.rs
+++ b/src/librustc/ty/print/obsolete.rs
@@ -8,7 +8,7 @@
 use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::ConstValue;
 use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, Const, GeneratorSubsts, Instance, Ty, TyCtxt};
+use rustc::ty::{self, Const, Instance, Ty, TyCtxt};
 use rustc::{bug, hir};
 use std::fmt::Write;
 use std::iter;
@@ -154,7 +154,7 @@ impl DefPathBasedNames<'tcx> {
                     self.push_type_name(sig.output(), output, debug);
                 }
             }
-            ty::Generator(def_id, GeneratorSubsts { substs }, _)
+            ty::Generator(def_id,  substs, _)
             | ty::Closure(def_id, substs) => {
                 self.push_def_path(def_id, output);
                 let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index ad4be788dae..73263892996 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -605,8 +605,8 @@ pub trait PrettyPrinter<'tcx>:
             }
             ty::Str => p!(write("str")),
             ty::Generator(did, substs, movability) => {
-                let upvar_tys = substs.upvar_tys(did, self.tcx());
-                let witness = substs.witness(did, self.tcx());
+                let upvar_tys = substs.as_generator().upvar_tys(did, self.tcx());
+                let witness = substs.as_generator().witness(did, self.tcx());
                 if movability == hir::GeneratorMovability::Movable {
                     p!(write("[generator"));
                 } else {
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 3f09bf749ed..e27236b47e0 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -163,7 +163,7 @@ pub enum TyKind<'tcx> {
 
     /// The anonymous type of a generator. Used to represent the type of
     /// `|a| yield a`.
-    Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
 
     /// A type representin the types stored inside a generator.
     /// This should only appear in GeneratorInteriors.
@@ -512,7 +512,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     /// variant indices.
     #[inline]
     pub fn discriminants(
-        &'tcx self,
+        self,
         def_id: DefId,
         tcx: TyCtxt<'tcx>,
     ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
@@ -524,7 +524,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     /// Calls `f` with a reference to the name of the enumerator for the given
     /// variant `v`.
     #[inline]
-    pub fn variant_name(&self, v: VariantIdx) -> Cow<'static, str> {
+    pub fn variant_name(self, v: VariantIdx) -> Cow<'static, str> {
         match v.as_usize() {
             Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
             Self::RETURNED => Cow::from(Self::RETURNED_NAME),
@@ -570,7 +570,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
 #[derive(Debug, Copy, Clone)]
 pub enum UpvarSubsts<'tcx> {
     Closure(SubstsRef<'tcx>),
-    Generator(GeneratorSubsts<'tcx>),
+    Generator(SubstsRef<'tcx>),
 }
 
 impl<'tcx> UpvarSubsts<'tcx> {
@@ -582,7 +582,7 @@ impl<'tcx> UpvarSubsts<'tcx> {
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let upvar_kinds = match self {
             UpvarSubsts::Closure(substs) => substs.as_closure().split(def_id, tcx).upvar_kinds,
-            UpvarSubsts::Generator(substs) => substs.split(def_id, tcx).upvar_kinds,
+            UpvarSubsts::Generator(substs) => substs.as_generator().split(def_id, tcx).upvar_kinds,
         };
         upvar_kinds.iter().map(|t| {
             if let GenericArgKind::Type(ty) = t.unpack() {
@@ -2109,7 +2109,8 @@ impl<'tcx> TyS<'tcx> {
     pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
         match self.kind {
             TyKind::Adt(adt, _) => Some(adt.variant_range()),
-            TyKind::Generator(def_id, substs, _) => Some(substs.variant_range(def_id, tcx)),
+            TyKind::Generator(def_id, substs, _) =>
+                Some(substs.as_generator().variant_range(def_id, tcx)),
             _ => None,
         }
     }
@@ -2126,7 +2127,7 @@ impl<'tcx> TyS<'tcx> {
         match self.kind {
             TyKind::Adt(adt, _) => Some(adt.discriminant_for_variant(tcx, variant_index)),
             TyKind::Generator(def_id, substs, _) =>
-                Some(substs.discriminant_for_variant(def_id, tcx, variant_index)),
+                Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index)),
             _ => None,
         }
     }
@@ -2149,7 +2150,7 @@ impl<'tcx> TyS<'tcx> {
                 out.extend(substs.regions())
             }
             Closure(_, ref substs ) |
-            Generator(_, GeneratorSubsts { ref substs }, _) => {
+            Generator(_, ref substs, _) => {
                 out.extend(substs.regions())
             }
             Projection(ref data) | UnnormalizedProjection(ref data) => {
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 537192b0a2e..7c5daaf14d7 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -5,7 +5,7 @@ use crate::infer::canonical::Canonical;
 use crate::ty::{self, Lift, List, Ty, TyCtxt, InferConst, ParamConst};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use crate::mir::interpret::ConstValue;
-use crate::ty::sty::ClosureSubsts;
+use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
 
 use rustc_serialize::{self, Encodable, Encoder, Decodable, Decoder};
 use syntax_pos::{Span, DUMMY_SP};
@@ -194,6 +194,14 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
         }
     }
 
+    /// Interpret these substitutions as the substitutions of a generator type.
+    /// Closure substitutions have a particular structure controlled by the
+    /// compiler that encodes information like the signature and generator kind;
+    /// see `ty::GeneratorSubsts` struct for more comments.
+    pub fn as_generator(&'tcx self) -> GeneratorSubsts<'tcx> {
+        GeneratorSubsts { substs: self }
+    }
+
     /// Creates a `InternalSubsts` that maps each generic parameter to itself.
     pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
         Self::for_item(tcx, def_id, |param, _| {
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
index 1895ab83674..f5b1902e3cc 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc/ty/walk.rs
@@ -110,12 +110,10 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
         ty::Adt(_, substs) | ty::Opaque(_, substs) => {
             stack.extend(substs.types().rev());
         }
-        ty::Closure(_, ref substs) => {
+        ty::Closure(_, ref substs)
+        | ty::Generator(_, ref substs, _) => {
             stack.extend(substs.types().rev());
         }
-        ty::Generator(_, ref substs, _) => {
-            stack.extend(substs.substs.types().rev());
-        }
         ty::GeneratorWitness(ts) => {
             stack.extend(ts.skip_binder().iter().cloned().rev());
         }
diff --git a/src/librustc_codegen_llvm/allocator.rs b/src/librustc_codegen_llvm/allocator.rs
index 5d43bf6ae28..f31765cea4f 100644
--- a/src/librustc_codegen_llvm/allocator.rs
+++ b/src/librustc_codegen_llvm/allocator.rs
@@ -68,7 +68,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
 
         let llbb = llvm::LLVMAppendBasicBlockInContext(llcx,
                                                        llfn,
-                                                       "entry\0".as_ptr() as *const _);
+                                                       "entry\0".as_ptr().cast());
 
         let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
         llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
@@ -80,7 +80,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
                                           args.as_ptr(),
                                           args.len() as c_uint,
                                           None,
-                                          "\0".as_ptr() as *const _);
+                                          "\0".as_ptr().cast());
         llvm::LLVMSetTailCall(ret, True);
         if output.is_some() {
             llvm::LLVMBuildRet(llbuilder, ret);
diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index c4368d2cb8b..e49c64923aa 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -546,7 +546,7 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext<LlvmCodegenBackend>,
         llvm::LLVMRustAddAnalysisPasses(module.module_llvm.tm, pm, module.module_llvm.llmod());
 
         if config.verify_llvm_ir {
-            let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
+            let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr().cast());
             llvm::LLVMRustAddPass(pm, pass.unwrap());
         }
 
@@ -581,12 +581,12 @@ pub(crate) fn run_pass_manager(cgcx: &CodegenContext<LlvmCodegenBackend>,
         // We always generate bitcode through ThinLTOBuffers,
         // which do not support anonymous globals
         if config.bitcode_needed() {
-            let pass = llvm::LLVMRustFindAndCreatePass("name-anon-globals\0".as_ptr() as *const _);
+            let pass = llvm::LLVMRustFindAndCreatePass("name-anon-globals\0".as_ptr().cast());
             llvm::LLVMRustAddPass(pm, pass.unwrap());
         }
 
         if config.verify_llvm_ir {
-            let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr() as *const _);
+            let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr().cast());
             llvm::LLVMRustAddPass(pm, pass.unwrap());
         }
 
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 78db90b57b5..b1a9552d56f 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -221,8 +221,8 @@ impl<'a> DiagnosticHandlers<'a> {
                llcx: &'a llvm::Context) -> Self {
         let data = Box::into_raw(Box::new((cgcx, handler)));
         unsafe {
-            llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data as *mut _);
-            llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, data as *mut _);
+            llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data.cast());
+            llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, data.cast());
         }
         DiagnosticHandlers { data, llcx }
     }
@@ -672,7 +672,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext<LlvmCodegenBackend>,
     let llglobal = llvm::LLVMAddGlobal(
         llmod,
         common::val_ty(llconst),
-        "rustc.embedded.module\0".as_ptr() as *const _,
+        "rustc.embedded.module\0".as_ptr().cast(),
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
 
@@ -684,7 +684,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext<LlvmCodegenBackend>,
     } else {
         ".llvmbc\0"
     };
-    llvm::LLVMSetSection(llglobal, section.as_ptr() as *const _);
+    llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
     llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
     llvm::LLVMSetGlobalConstant(llglobal, llvm::True);
 
@@ -692,7 +692,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext<LlvmCodegenBackend>,
     let llglobal = llvm::LLVMAddGlobal(
         llmod,
         common::val_ty(llconst),
-        "rustc.embedded.cmdline\0".as_ptr() as *const _,
+        "rustc.embedded.cmdline\0".as_ptr().cast(),
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
     let section = if  is_apple {
@@ -700,7 +700,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext<LlvmCodegenBackend>,
     } else {
         ".llvmcmd\0"
     };
-    llvm::LLVMSetSection(llglobal, section.as_ptr() as *const _);
+    llvm::LLVMSetSection(llglobal, section.as_ptr().cast());
     llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage);
 }
 
@@ -842,7 +842,7 @@ fn create_msvc_imps(
         for (imp_name, val) in globals {
             let imp = llvm::LLVMAddGlobal(llmod,
                                           i8p_ty,
-                                          imp_name.as_ptr() as *const _);
+                                          imp_name.as_ptr().cast());
             llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
             llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
         }
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index cba5ee3260c..d4df5b4a804 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -488,7 +488,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                 if let Some(section) = attrs.link_section {
                     let section = llvm::LLVMMDStringInContext(
                         self.llcx,
-                        section.as_str().as_ptr() as *const _,
+                        section.as_str().as_ptr().cast(),
                         section.as_str().len() as c_uint,
                     );
                     assert!(alloc.relocations().is_empty());
@@ -500,14 +500,14 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                         0..alloc.len());
                     let alloc = llvm::LLVMMDStringInContext(
                         self.llcx,
-                        bytes.as_ptr() as *const _,
+                        bytes.as_ptr().cast(),
                         bytes.len() as c_uint,
                     );
                     let data = [section, alloc];
                     let meta = llvm::LLVMMDNodeInContext(self.llcx, data.as_ptr(), 2);
                     llvm::LLVMAddNamedMetadataOperand(
                         self.llmod,
-                        "wasm.custom_sections\0".as_ptr() as *const _,
+                        "wasm.custom_sections\0".as_ptr().cast(),
                         meta,
                     );
                 }
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 58ce9703909..18a5970fcd0 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -211,7 +211,7 @@ pub unsafe fn create_module(
     // If skipping the PLT is enabled, we need to add some module metadata
     // to ensure intrinsic calls don't use it.
     if !sess.needs_plt() {
-        let avoid_plt = "RtLibUseGOT\0".as_ptr() as *const _;
+        let avoid_plt = "RtLibUseGOT\0".as_ptr().cast();
         llvm::LLVMRustAddModuleFlag(llmod, avoid_plt, 1);
     }
 
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs
index 04c9e93c7a5..9ed1c1730a6 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs
@@ -37,7 +37,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
 
     let section_var = unsafe {
         llvm::LLVMGetNamedGlobal(cx.llmod,
-                                 c_section_var_name.as_ptr() as *const _)
+                                 c_section_var_name.as_ptr().cast())
     };
 
     section_var.unwrap_or_else(|| {
@@ -52,7 +52,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
                                                      llvm_type).unwrap_or_else(||{
                 bug!("symbol `{}` is already defined", section_var_name)
             });
-            llvm::LLVMSetSection(section_var, section_name.as_ptr() as *const _);
+            llvm::LLVMSetSection(section_var, section_name.as_ptr().cast());
             llvm::LLVMSetInitializer(section_var, cx.const_bytes(section_contents));
             llvm::LLVMSetGlobalConstant(section_var, llvm::True);
             llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index e69f4b6aca1..438a660b8a8 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -30,7 +30,7 @@ use rustc::ty::Instance;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
                         PrimitiveExt, Size, TyLayout, VariantIdx};
-use rustc::ty::subst::GenericArgKind;
+use rustc::ty::subst::{GenericArgKind, SubstsRef};
 use rustc::session::config::{self, DebugInfo};
 use rustc::util::nodemap::FxHashMap;
 use rustc_fs_util::path_to_c_string;
@@ -692,9 +692,10 @@ pub fn type_metadata(
                                    Some(containing_scope)).finalize(cx)
         }
         ty::Generator(def_id, substs,  _) => {
-            let upvar_tys : Vec<_> = substs.prefix_tys(def_id, cx.tcx).map(|t| {
-                cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
-            }).collect();
+            let upvar_tys : Vec<_> = substs
+                .as_generator().prefix_tys(def_id, cx.tcx).map(|t| {
+                    cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
+                }).collect();
             prepare_enum_metadata(cx,
                                   t,
                                   def_id,
@@ -960,9 +961,9 @@ pub fn compile_unit_metadata(
             file_metadata,
             producer.as_ptr(),
             tcx.sess.opts.optimize != config::OptLevel::No,
-            flags.as_ptr() as *const _,
+            flags.as_ptr().cast(),
             0,
-            split_name.as_ptr() as *const _,
+            split_name.as_ptr().cast(),
             kind);
 
         if tcx.sess.opts.debugging_opts.profile {
@@ -991,7 +992,7 @@ pub fn compile_unit_metadata(
         if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
             let name_metadata = llvm::LLVMMDStringInContext(
                 debug_context.llcontext,
-                rustc_producer.as_ptr() as *const _,
+                rustc_producer.as_ptr().cast(),
                 rustc_producer.as_bytes().len() as c_uint,
             );
             llvm::LLVMAddNamedMetadataOperand(
@@ -1338,7 +1339,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
                 ty::Adt(adt, _) => VariantInfo::Adt(&adt.variants[index]),
                 ty::Generator(def_id, substs, _) => {
                     let generator_layout = cx.tcx.generator_layout(*def_id);
-                    VariantInfo::Generator(*substs, generator_layout, index)
+                    VariantInfo::Generator(substs, generator_layout, index)
                 }
                 _ => bug!(),
             }
@@ -1611,7 +1612,7 @@ enum EnumDiscriminantInfo<'ll> {
 #[derive(Copy, Clone)]
 enum VariantInfo<'tcx> {
     Adt(&'tcx ty::VariantDef),
-    Generator(ty::GeneratorSubsts<'tcx>, &'tcx GeneratorLayout<'tcx>, VariantIdx),
+    Generator(SubstsRef<'tcx>, &'tcx GeneratorLayout<'tcx>, VariantIdx),
 }
 
 impl<'tcx> VariantInfo<'tcx> {
@@ -1619,7 +1620,7 @@ impl<'tcx> VariantInfo<'tcx> {
         match self {
             VariantInfo::Adt(variant) => f(&variant.ident.as_str()),
             VariantInfo::Generator(substs, _, variant_index) =>
-                f(&substs.variant_name(*variant_index)),
+                f(&substs.as_generator().variant_name(*variant_index)),
         }
     }
 
@@ -1763,9 +1764,10 @@ fn prepare_enum_metadata(
                 })
                 .collect(),
             ty::Generator(_, substs, _) => substs
+                .as_generator()
                 .variant_range(enum_def_id, cx.tcx)
                 .map(|variant_index| {
-                    let name = SmallCStr::new(&substs.variant_name(variant_index));
+                    let name = SmallCStr::new(&substs.as_generator().variant_name(variant_index));
                     unsafe {
                         Some(llvm::LLVMRustDIBuilderCreateEnumerator(
                             DIB(cx),
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index e0e0cd5f739..6e4ed42c45e 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -127,20 +127,20 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
         if cx.sess().target.target.options.is_like_osx ||
            cx.sess().target.target.options.is_like_android {
             llvm::LLVMRustAddModuleFlag(cx.llmod,
-                                        "Dwarf Version\0".as_ptr() as *const _,
+                                        "Dwarf Version\0".as_ptr().cast(),
                                         2)
         }
 
         // Indicate that we want CodeView debug information on MSVC
         if cx.sess().target.target.options.is_like_msvc {
             llvm::LLVMRustAddModuleFlag(cx.llmod,
-                                        "CodeView\0".as_ptr() as *const _,
+                                        "CodeView\0".as_ptr().cast(),
                                         1)
         }
 
         // Prevent bitcode readers from deleting the debug info.
         let ptr = "Debug Info Version\0".as_ptr();
-        llvm::LLVMRustAddModuleFlag(cx.llmod, ptr as *const _,
+        llvm::LLVMRustAddModuleFlag(cx.llmod, ptr.cast(),
                                     llvm::LLVMRustDebugMetadataVersion());
     };
 }
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 2dce9b04c9e..541d3d98b79 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -257,7 +257,8 @@ pub fn target_feature_whitelist(sess: &Session)
         "hexagon" => HEXAGON_WHITELIST,
         "mips" | "mips64" => MIPS_WHITELIST,
         "powerpc" | "powerpc64" => POWERPC_WHITELIST,
-        "wasm32" => WASM_WHITELIST,
+        // wasm32 on emscripten does not support these target features
+        "wasm32" if !sess.target.target.options.is_like_emscripten => WASM_WHITELIST,
         _ => &[],
     }
 }
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index 81a99bc5019..d921bbc96ad 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -65,7 +65,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
             if let (&ty::Generator(_, substs, _), &layout::Variants::Single { index })
                  = (&layout.ty.kind, &layout.variants)
             {
-                write!(&mut name, "::{}", substs.variant_name(index)).unwrap();
+                write!(&mut name, "::{}", substs.as_generator().variant_name(index)).unwrap();
             }
             Some(name)
         }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index caaa500766d..f1cfac27033 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -142,12 +142,15 @@ impl ModuleConfig {
         // Copy what clang does by turning on loop vectorization at O2 and
         // slp vectorization at O3. Otherwise configure other optimization aspects
         // of this pass manager builder.
+        // Turn off vectorization for emscripten, as it's not very well supported.
         self.vectorize_loop = !sess.opts.cg.no_vectorize_loops &&
                              (sess.opts.optimize == config::OptLevel::Default ||
-                              sess.opts.optimize == config::OptLevel::Aggressive);
+                              sess.opts.optimize == config::OptLevel::Aggressive) &&
+                             !sess.target.target.options.is_like_emscripten;
 
         self.vectorize_slp = !sess.opts.cg.no_vectorize_slp &&
-                            sess.opts.optimize == config::OptLevel::Aggressive;
+                            sess.opts.optimize == config::OptLevel::Aggressive &&
+                            !sess.target.target.options.is_like_emscripten;
 
         // Some targets (namely, NVPTX) interact badly with the MergeFunctions
         // pass. This is because MergeFunctions can generate new function calls
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 5787447d623..9d2f8b42c70 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -636,7 +636,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                         ty::Generator(def_id, substs, _) => (def_id, substs),
                         _ => bug!("generator layout without generator substs"),
                     };
-                    let state_tys = gen_substs.state_tys(def_id, tcx);
+                    let state_tys = gen_substs.as_generator().state_tys(def_id, tcx);
 
                     generator_layout.variant_fields.iter()
                         .zip(state_tys)
diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs
index 5bcb3b4ceb3..cf575c54293 100644
--- a/src/librustc_codegen_utils/symbol_names/legacy.rs
+++ b/src/librustc_codegen_utils/symbol_names/legacy.rs
@@ -225,7 +225,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> {
             ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) |
             ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) |
             ty::Closure(def_id, substs) |
-            ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
+            ty::Generator(def_id, substs, _) => {
                 self.print_def_path(def_id, substs)
             }
             _ => self.pretty_print_type(ty),
diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs
index 2ad699d7c6f..55b148fceb2 100644
--- a/src/librustc_codegen_utils/symbol_names/v0.rs
+++ b/src/librustc_codegen_utils/symbol_names/v0.rs
@@ -415,7 +415,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
             ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs }) |
             ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs }) |
             ty::Closure(def_id, substs) |
-            ty::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
+            ty::Generator(def_id, substs, _) => {
                 self = self.print_def_path(def_id, substs)?;
             }
             ty::Foreign(def_id) => {
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index 3f1b91256c4..fd74d8673da 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -298,9 +298,31 @@ impl Diagnostic {
     /// * may contain a name of a function, variable, or type, but not whole expressions
     ///
     /// See `CodeSuggestion` for more information.
-    pub fn span_suggestion(&mut self, sp: Span, msg: &str,
-                                       suggestion: String,
-                                       applicability: Applicability) -> &mut Self {
+    pub fn span_suggestion(
+        &mut self,
+        sp: Span,
+        msg: &str,
+        suggestion: String,
+        applicability: Applicability,
+    ) -> &mut Self {
+        self.span_suggestion_with_style(
+            sp,
+            msg,
+            suggestion,
+            applicability,
+            SuggestionStyle::ShowCode,
+        );
+        self
+    }
+
+    pub fn span_suggestion_with_style(
+        &mut self,
+        sp: Span,
+        msg: &str,
+        suggestion: String,
+        applicability: Applicability,
+        style: SuggestionStyle,
+    ) -> &mut Self {
         self.suggestions.push(CodeSuggestion {
             substitutions: vec![Substitution {
                 parts: vec![SubstitutionPart {
@@ -309,16 +331,37 @@ impl Diagnostic {
                 }],
             }],
             msg: msg.to_owned(),
-            style: SuggestionStyle::ShowCode,
+            style,
             applicability,
         });
         self
     }
 
+    pub fn span_suggestion_verbose(
+        &mut self,
+        sp: Span,
+        msg: &str,
+        suggestion: String,
+        applicability: Applicability,
+    ) -> &mut Self {
+        self.span_suggestion_with_style(
+            sp,
+            msg,
+            suggestion,
+            applicability,
+            SuggestionStyle::ShowAlways,
+        );
+        self
+    }
+
     /// Prints out a message with multiple suggested edits of the code.
-    pub fn span_suggestions(&mut self, sp: Span, msg: &str,
-        suggestions: impl Iterator<Item = String>, applicability: Applicability) -> &mut Self
-    {
+    pub fn span_suggestions(
+        &mut self,
+        sp: Span,
+        msg: &str,
+        suggestions: impl Iterator<Item = String>,
+        applicability: Applicability,
+    ) -> &mut Self {
         self.suggestions.push(CodeSuggestion {
             substitutions: suggestions.map(|snippet| Substitution {
                 parts: vec![SubstitutionPart {
@@ -340,17 +383,13 @@ impl Diagnostic {
     pub fn span_suggestion_short(
         &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability
     ) -> &mut Self {
-        self.suggestions.push(CodeSuggestion {
-            substitutions: vec![Substitution {
-                parts: vec![SubstitutionPart {
-                    snippet: suggestion,
-                    span: sp,
-                }],
-            }],
-            msg: msg.to_owned(),
-            style: SuggestionStyle::HideCodeInline,
+        self.span_suggestion_with_style(
+            sp,
+            msg,
+            suggestion,
             applicability,
-        });
+            SuggestionStyle::HideCodeInline,
+        );
         self
     }
 
@@ -363,17 +402,13 @@ impl Diagnostic {
     pub fn span_suggestion_hidden(
         &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability
     ) -> &mut Self {
-        self.suggestions.push(CodeSuggestion {
-            substitutions: vec![Substitution {
-                parts: vec![SubstitutionPart {
-                    snippet: suggestion,
-                    span: sp,
-                }],
-            }],
-            msg: msg.to_owned(),
-            style: SuggestionStyle::HideCodeAlways,
+        self.span_suggestion_with_style(
+            sp,
+            msg,
+            suggestion,
             applicability,
-        });
+            SuggestionStyle::HideCodeAlways,
+        );
         self
     }
 
@@ -384,17 +419,13 @@ impl Diagnostic {
     pub fn tool_only_span_suggestion(
         &mut self, sp: Span, msg: &str, suggestion: String, applicability: Applicability
     ) -> &mut Self {
-        self.suggestions.push(CodeSuggestion {
-            substitutions: vec![Substitution {
-                parts: vec![SubstitutionPart {
-                    snippet: suggestion,
-                    span: sp,
-                }],
-            }],
-            msg: msg.to_owned(),
-            style: SuggestionStyle::CompletelyHidden,
+        self.span_suggestion_with_style(
+            sp,
+            msg,
+            suggestion,
             applicability,
-        });
+            SuggestionStyle::CompletelyHidden,
+        );
         self
     }
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 9aea46da68b..68f933363da 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -218,10 +218,14 @@ pub trait Emitter {
                sugg.msg.split_whitespace().count() < 10 &&
                // don't display multiline suggestions as labels
                !sugg.substitutions[0].parts[0].snippet.contains('\n') &&
-               // when this style is set we want the suggestion to be a message, not inline
-               sugg.style != SuggestionStyle::HideCodeAlways &&
-               // trivial suggestion for tooling's sake, never shown
-               sugg.style != SuggestionStyle::CompletelyHidden
+               ![
+                    // when this style is set we want the suggestion to be a message, not inline
+                    SuggestionStyle::HideCodeAlways,
+                    // trivial suggestion for tooling's sake, never shown
+                    SuggestionStyle::CompletelyHidden,
+                    // subtle suggestion, never shown inline
+                    SuggestionStyle::ShowAlways,
+               ].contains(&sugg.style)
             {
                 let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
                 let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index f9dc13ce97e..2fae584c153 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -81,6 +81,8 @@ pub enum SuggestionStyle {
     /// This will *not* show the code if the suggestion is inline *and* the suggested code is
     /// empty.
     ShowCode,
+    /// Always show the suggested code independently.
+    ShowAlways,
 }
 
 impl SuggestionStyle {
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index bf5e86017fc..870f804ed44 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -780,13 +780,10 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) {
     ty::provide(providers);
     traits::provide(providers);
     stability::provide(providers);
-    middle::intrinsicck::provide(providers);
-    middle::liveness::provide(providers);
     reachable::provide(providers);
     rustc_passes::provide(providers);
     rustc_traits::provide(providers);
     middle::region::provide(providers);
-    middle::entry::provide(providers);
     cstore::provide(providers);
     lint::provide(providers);
     rustc_lint::provide(providers);
@@ -892,7 +889,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
     time(sess, "misc checking 1", || {
         parallel!({
             entry_point = time(sess, "looking for entry point", || {
-                middle::entry::find_entry_point(tcx)
+                rustc_passes::entry::find_entry_point(tcx)
             });
 
             time(sess, "looking for plugin registrar", || {
@@ -973,7 +970,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
                     tcx.ensure().check_private_in_public(LOCAL_CRATE);
                 });
             }, {
-                time(sess, "death checking", || middle::dead::check_crate(tcx));
+                time(sess, "death checking", || rustc_passes::dead::check_crate(tcx));
             },  {
                 time(sess, "unused lib feature checking", || {
                     stability::check_unused_or_stable_features(tcx)
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 3d14a78c33f..aa6dfa50ddd 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -631,6 +631,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             };
                         }
 
+                        let is_non_exhaustive =
+                            def.non_enum_variant().is_field_list_non_exhaustive();
+                        if is_non_exhaustive && !def.did.is_local() {
+                            return FfiUnsafe {
+                                ty,
+                                reason: "this struct is non-exhaustive",
+                                help: None,
+                            };
+                        }
+
                         if def.non_enum_variant().fields.is_empty() {
                             return FfiUnsafe {
                                 ty,
@@ -730,8 +740,25 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             }
                         }
 
+                        if def.is_variant_list_non_exhaustive() && !def.did.is_local() {
+                            return FfiUnsafe {
+                                ty,
+                                reason: "this enum is non-exhaustive",
+                                help: None,
+                            };
+                        }
+
                         // Check the contained variants.
                         for variant in &def.variants {
+                            let is_non_exhaustive = variant.is_field_list_non_exhaustive();
+                            if is_non_exhaustive && !variant.def_id.is_local() {
+                                return FfiUnsafe {
+                                    ty,
+                                    reason: "this enum has non-exhaustive variants",
+                                    help: None,
+                                };
+                            }
+
                             for field in &variant.fields {
                                 let field_ty = cx.normalize_erasing_regions(
                                     ParamEnv::reveal_all(),
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 34f86707ad3..eed355cbc13 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -919,7 +919,7 @@ impl<'a, 'tcx> CrateMetadata {
         self.entry_unless_proc_macro(id)
             .and_then(|entry| entry.mir.map(|mir| mir.decode((self, tcx))))
             .unwrap_or_else(|| {
-                bug!("get_optimized_mir: missing MIR for `{:?}", self.local_def_id(id))
+                bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
             })
     }
 
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index cfa211ad5af..75d4b56fdb7 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1944,14 +1944,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     self.is_mutable(place.as_ref(), is_local_mutation_allowed),
                     self.errors_buffer.is_empty()
                 ) {
-                    // rust-lang/rust#46908: In pure NLL mode this code path should
-                    // be unreachable (and thus we signal an ICE in the else branch here).
-                    span_bug!(
-                        span,
+                    // rust-lang/rust#46908: In pure NLL mode this code path should be
+                    // unreachable, but we use `delay_span_bug` because we can hit this when
+                    // dereferencing a non-Copy raw pointer *and* have `-Ztreat-err-as-bug`
+                    // enabled. We don't want to ICE for that case, as other errors will have
+                    // been emitted (#52262).
+                    self.infcx.tcx.sess.delay_span_bug(span, &format!(
                         "Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
                         place,
                         kind,
-                    );
+                    ));
                 }
                 return false;
             }
diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
index 0e22ead62d1..b105664399a 100644
--- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
@@ -12,7 +12,7 @@ use rustc::mir::{
     SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection,
 };
 use rustc::ty::fold::TypeFoldable;
-use rustc::ty::{self, GeneratorSubsts, RegionVid, Ty};
+use rustc::ty::{self, RegionVid, Ty};
 use rustc::ty::subst::SubstsRef;
 
 pub(super) fn generate_constraints<'cx, 'tcx>(
@@ -91,13 +91,6 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
         self.super_ty(ty);
     }
 
-    /// We sometimes have `generator_substs` within an rvalue, or within a
-    /// call. Make them live at the location where they appear.
-    fn visit_generator_substs(&mut self, substs: &GeneratorSubsts<'tcx>, location: Location) {
-        self.add_regular_live_constraint(*substs, location);
-        self.super_generator_substs(substs);
-    }
-
     fn visit_statement(
         &mut self,
         statement: &Statement<'tcx>,
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index 014335711a5..88ad1fb1295 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -1,5 +1,5 @@
 use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, GeneratorSubsts, Ty, TypeFoldable};
+use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::mir::{Location, Body, Promoted};
 use rustc::mir::visit::{MutVisitor, TyContext};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
@@ -82,18 +82,4 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
     fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) {
         *constant = self.renumber_regions(&*constant);
     }
-
-    fn visit_generator_substs(&mut self,
-                              substs: &mut GeneratorSubsts<'tcx>,
-                              location: Location) {
-        debug!(
-            "visit_generator_substs(substs={:?}, location={:?})",
-            substs,
-            location,
-        );
-
-        *substs = self.renumber_regions(substs);
-
-        debug!("visit_generator_substs: substs={:?}", substs);
-    }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index f55889794c2..1563a27250e 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -759,13 +759,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
             PlaceTy { ty, variant_index: Some(variant_index) } => match ty.kind {
                 ty::Adt(adt_def, substs) => (&adt_def.variants[variant_index], substs),
                 ty::Generator(def_id, substs, _) => {
-                    let mut variants = substs.state_tys(def_id, tcx);
+                    let mut variants = substs.as_generator().state_tys(def_id, tcx);
                     let mut variant = match variants.nth(variant_index.into()) {
                         Some(v) => v,
                         None => {
                             bug!("variant_index of generator out of range: {:?}/{:?}",
                                  variant_index,
-                                 substs.state_tys(def_id, tcx).count())
+                                 substs.as_generator().state_tys(def_id, tcx).count())
                         }
                     };
                     return match variant.nth(field.index()) {
@@ -791,10 +791,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                 ty::Generator(def_id, substs, _) => {
                     // Only prefix fields (upvars and current state) are
                     // accessible without a variant index.
-                    return match substs.prefix_tys(def_id, tcx).nth(field.index()) {
+                    return match substs.as_generator().prefix_tys(def_id, tcx).nth(field.index()) {
                         Some(ty) => Ok(ty),
                         None => Err(FieldAccessError::OutOfRange {
-                            field_count: substs.prefix_tys(def_id, tcx).count(),
+                            field_count: substs.as_generator().prefix_tys(def_id, tcx).count(),
                         }),
                     }
                 }
@@ -1963,10 +1963,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 // It doesn't make sense to look at a field beyond the prefix;
                 // these require a variant index, and are not initialized in
                 // aggregate rvalues.
-                match substs.prefix_tys(def_id, tcx).nth(field_index) {
+                match substs.as_generator().prefix_tys(def_id, tcx).nth(field_index) {
                     Some(ty) => Ok(ty),
                     None => Err(FieldAccessError::OutOfRange {
-                        field_count: substs.prefix_tys(def_id, tcx).count(),
+                        field_count: substs.as_generator().prefix_tys(def_id, tcx).count(),
                     }),
                 }
             }
@@ -2541,7 +2541,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             // these extra requirements are basically like where
             // clauses on the struct.
             AggregateKind::Closure(def_id, substs)
-            | AggregateKind::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
+            | AggregateKind::Generator(def_id, substs, _) => {
                 self.prove_closure_bounds(tcx, *def_id, substs, location)
             }
 
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index e3efacff66a..5f695185643 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -19,7 +19,7 @@ use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 use rustc::middle::lang_items;
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::subst::{InternalSubsts, SubstsRef, Subst};
-use rustc::ty::{self, GeneratorSubsts, RegionVid, Ty, TyCtxt};
+use rustc::ty::{self, RegionVid, Ty, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_errors::DiagnosticBuilder;
@@ -90,7 +90,7 @@ pub enum DefiningTy<'tcx> {
     /// The MIR is a generator. The signature is that generators take
     /// no parameters and return the result of
     /// `ClosureSubsts::generator_return_ty`.
-    Generator(DefId, ty::GeneratorSubsts<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
 
     /// The MIR is a fn item with the given `DefId` and substs. The signature
     /// of the function can be bound then with the `fn_sig` query.
@@ -113,7 +113,7 @@ impl<'tcx> DefiningTy<'tcx> {
                 substs.as_closure().upvar_tys(def_id, tcx)
             ),
             DefiningTy::Generator(def_id, substs, _) => {
-                Either::Right(Either::Left(substs.upvar_tys(def_id, tcx)))
+                Either::Right(Either::Left(substs.as_generator().upvar_tys(def_id, tcx)))
             }
             DefiningTy::FnDef(..) | DefiningTy::Const(..) => {
                 Either::Right(Either::Right(iter::empty()))
@@ -334,7 +334,7 @@ impl<'tcx> UniversalRegions<'tcx> {
                 err.note(&format!(
                     "defining type: {:?} with generator substs {:#?}",
                     def_id,
-                    &substs.substs[..]
+                    &substs[..]
                 ));
 
                 // FIXME: As above, we'd like to print out the region
@@ -470,7 +470,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
 
         let yield_ty = match defining_ty {
             DefiningTy::Generator(def_id, substs, _) => {
-                Some(substs.yield_ty(def_id, self.infcx.tcx))
+                Some(substs.as_generator().yield_ty(def_id, self.infcx.tcx))
             }
             _ => None,
         };
@@ -549,7 +549,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         let identity_substs = InternalSubsts::identity_for_item(tcx, closure_base_def_id);
         let fr_substs = match defining_ty {
             DefiningTy::Closure(_, ref substs)
-            | DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => {
+            | DefiningTy::Generator(_, ref substs, _) => {
                 // In the case of closures, we rely on the fact that
                 // the first N elements in the ClosureSubsts are
                 // inherited from the `closure_base_def_id`.
@@ -612,7 +612,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
 
             DefiningTy::Generator(def_id, substs, movability) => {
                 assert_eq!(self.mir_def_id, def_id);
-                let output = substs.return_ty(def_id, tcx);
+                let output = substs.as_generator().return_ty(def_id, tcx);
                 let generator_ty = tcx.mk_generator(def_id, substs, movability);
                 let inputs_and_output = self.infcx.tcx.intern_type_list(&[generator_ty, output]);
                 ty::Binder::dummy(inputs_and_output)
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 9c30d950990..6b6eac5add2 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -146,7 +146,7 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
             let (yield_ty, return_ty) = if body.generator_kind.is_some() {
                 let gen_sig = match ty.kind {
                     ty::Generator(gen_def_id, gen_substs, ..) =>
-                        gen_substs.sig(gen_def_id, tcx),
+                        gen_substs.as_generator().sig(gen_def_id, tcx),
                     _ =>
                         span_bug!(tcx.hir().span(id),
                                   "generator w/o generator type: {:?}", ty),
diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs
index dc3b7694c35..f9200f8c1c0 100644
--- a/src/librustc_mir/interpret/intrinsics/type_name.rs
+++ b/src/librustc_mir/interpret/intrinsics/type_name.rs
@@ -68,8 +68,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
             | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
             | ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs })
             | ty::Closure(def_id, substs)
-            | ty::Generator(def_id, ty::GeneratorSubsts { substs }, _)
-            => self.print_def_path(def_id, substs),
+            | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
             ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
 
             ty::GeneratorWitness(_) => {
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 861e5ebef87..4bdd71f9602 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -664,14 +664,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     bits_discr
                 };
                 // Make sure we catch invalid discriminants
-                let index = match &rval.layout.ty.kind {
+                let index = match rval.layout.ty.kind {
                     ty::Adt(adt, _) => adt
                         .discriminants(self.tcx.tcx)
                         .find(|(_, var)| var.val == real_discr),
-                    ty::Generator(def_id, substs, _) => substs
-                        .discriminants(*def_id, self.tcx.tcx)
-                        .find(|(_, var)| var.val == real_discr),
+                    ty::Generator(def_id, substs, _) => {
+                        let substs = substs.as_generator();
+                        substs
+                            .discriminants(def_id, self.tcx.tcx)
+                            .find(|(_, var)| var.val == real_discr)
+                    }
                     _ => bug!("tagged layout for non-adt non-generator"),
+
                 }.ok_or_else(
                     || err_unsup!(InvalidDiscriminant(raw_discr.erase_tag()))
                 )?;
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 1166ca9bf24..3ba989529f1 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -594,6 +594,13 @@ where
             StaticKind::Promoted(promoted, promoted_substs) => {
                 let substs = self.subst_from_frame_and_normalize_erasing_regions(promoted_substs);
                 let instance = ty::Instance::new(place_static.def_id, substs);
+
+                // Even after getting `substs` from the frame, this instance may still be
+                // polymorphic because `ConstProp` will try to promote polymorphic MIR.
+                if instance.needs_subst() {
+                    throw_inval!(TooGeneric);
+                }
+
                 self.const_eval_raw(GlobalId {
                     instance,
                     promoted: Some(promoted),
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index d089eafbb07..78008e2fcd3 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -169,7 +169,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
     // Check if this is a generator, if so, return the drop glue for it
     if let Some(&ty::TyS { kind: ty::Generator(gen_def_id, substs, _), .. }) = ty {
         let body = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
-        return body.subst(tcx, substs.substs);
+        return body.subst(tcx, substs);
     }
 
     let substs = if let Some(ty) = ty {
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 21ca339eb96..38a04ce8f38 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -39,12 +39,6 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
     fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
         *substs = self.tcx.erase_regions(substs);
     }
-
-    fn visit_statement(&mut self,
-                       statement: &mut Statement<'tcx>,
-                       location: Location) {
-        self.super_statement(statement, location);
-    }
 }
 
 pub struct EraseRegions;
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index bfc5eb5a94e..a648fadde43 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -1126,6 +1126,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         // Get the interior types and substs which typeck computed
         let (upvars, interior, discr_ty, movable) = match gen_ty.kind {
             ty::Generator(_, substs, movability) => {
+                let substs = substs.as_generator();
                 (substs.upvar_tys(def_id, tcx).collect(),
                  substs.witness(def_id, tcx),
                  substs.discr_ty(tcx),
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index bdbf040276d..f7ba6f1ec69 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -798,7 +798,7 @@ where
             // It effetively only contains upvars until the generator transformation runs.
             // See librustc_body/transform/generator.rs for more details.
             ty::Generator(def_id, substs, _) => {
-                let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
+                let tys : Vec<_> = substs.as_generator().upvar_tys(def_id, self.tcx()).collect();
                 self.open_drop_for_tuple(&tys)
             }
             ty::Tuple(..) => {
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index 596ec6c19bc..9d29a230314 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -15,3 +15,5 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
+rustc_target = { path = "../librustc_target" }
+rustc_index = { path = "../librustc_index" }
diff --git a/src/librustc/middle/dead.rs b/src/librustc_passes/dead.rs
index 7c75a1447e2..f2aef2c12c7 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -2,18 +2,18 @@
 // closely. The idea is that all reachable symbols are live, codes called
 // from live codes are live, and everything else is dead.
 
-use crate::hir::Node;
-use crate::hir::{self, PatKind, TyKind};
-use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use crate::hir::itemlikevisit::ItemLikeVisitor;
-
-use crate::hir::def::{CtorOf, Res, DefKind};
-use crate::hir::CodegenFnAttrFlags;
-use crate::hir::def_id::{DefId, LOCAL_CRATE};
-use crate::lint;
-use crate::middle::privacy;
-use crate::ty::{self, DefIdTree, TyCtxt};
-use crate::util::nodemap::FxHashSet;
+use rustc::hir::Node;
+use rustc::hir::{self, PatKind, TyKind};
+use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+
+use rustc::hir::def::{CtorOf, Res, DefKind};
+use rustc::hir::CodegenFnAttrFlags;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::lint;
+use rustc::middle::privacy;
+use rustc::ty::{self, DefIdTree, TyCtxt};
+use rustc::util::nodemap::FxHashSet;
 
 use rustc_data_structures::fx::FxHashMap;
 
diff --git a/src/librustc/middle/entry.rs b/src/librustc_passes/entry.rs
index 660fe14ba07..bf68807a0c2 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -1,15 +1,15 @@
-use crate::hir::map as hir_map;
-use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
-use crate::session::{config, Session};
-use crate::session::config::EntryFnType;
+use rustc::hir::map as hir_map;
+use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
+use rustc::session::{config, Session};
+use rustc::session::config::EntryFnType;
 use syntax::attr;
 use syntax::entry::EntryPointType;
 use syntax::symbol::sym;
 use syntax_pos::Span;
-use crate::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
-use crate::hir::itemlikevisit::ItemLikeVisitor;
-use crate::ty::TyCtxt;
-use crate::ty::query::Providers;
+use rustc::hir::{HirId, Item, ItemKind, ImplItem, TraitItem};
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::ty::TyCtxt;
+use rustc::ty::query::Providers;
 
 struct EntryContext<'a, 'tcx> {
     session: &'a Session,
diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs
index af07c790e2a..1c61eb35497 100644
--- a/src/librustc_passes/error_codes.rs
+++ b/src/librustc_passes/error_codes.rs
@@ -319,6 +319,188 @@ async fn foo() {}
 
 Switch to the Rust 2018 edition to use `async fn`.
 "##,
+
+// This shouldn't really ever trigger since the repeated value error comes first
+E0136: r##"
+A binary can only have one entry point, and by default that entry point is the
+function `main()`. If there are multiple such functions, please rename one.
+"##,
+
+E0137: r##"
+More than one function was declared with the `#[main]` attribute.
+
+Erroneous code example:
+
+```compile_fail,E0137
+#![feature(main)]
+
+#[main]
+fn foo() {}
+
+#[main]
+fn f() {} // error: multiple functions with a `#[main]` attribute
+```
+
+This error indicates that the compiler found multiple functions with the
+`#[main]` attribute. This is an error because there must be a unique entry
+point into a Rust program. Example:
+
+```
+#![feature(main)]
+
+#[main]
+fn f() {} // ok!
+```
+"##,
+
+E0138: r##"
+More than one function was declared with the `#[start]` attribute.
+
+Erroneous code example:
+
+```compile_fail,E0138
+#![feature(start)]
+
+#[start]
+fn foo(argc: isize, argv: *const *const u8) -> isize {}
+
+#[start]
+fn f(argc: isize, argv: *const *const u8) -> isize {}
+// error: multiple 'start' functions
+```
+
+This error indicates that the compiler found multiple functions with the
+`#[start]` attribute. This is an error because there must be a unique entry
+point into a Rust program. Example:
+
+```
+#![feature(start)]
+
+#[start]
+fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
+```
+"##,
+
+E0601: r##"
+No `main` function was found in a binary crate. To fix this error, add a
+`main` function. For example:
+
+```
+fn main() {
+    // Your program will start here.
+    println!("Hello world!");
+}
+```
+
+If you don't know the basics of Rust, you can go look to the Rust Book to get
+started: https://doc.rust-lang.org/book/
+"##,
+
+E0591: r##"
+Per [RFC 401][rfc401], if you have a function declaration `foo`:
+
+```
+// For the purposes of this explanation, all of these
+// different kinds of `fn` declarations are equivalent:
+struct S;
+fn foo(x: S) { /* ... */ }
+# #[cfg(for_demonstration_only)]
+extern "C" { fn foo(x: S); }
+# #[cfg(for_demonstration_only)]
+impl S { fn foo(self) { /* ... */ } }
+```
+
+the type of `foo` is **not** `fn(S)`, as one might expect.
+Rather, it is a unique, zero-sized marker type written here as `typeof(foo)`.
+However, `typeof(foo)` can be _coerced_ to a function pointer `fn(S)`,
+so you rarely notice this:
+
+```
+# struct S;
+# fn foo(_: S) {}
+let x: fn(S) = foo; // OK, coerces
+```
+
+The reason that this matter is that the type `fn(S)` is not specific to
+any particular function: it's a function _pointer_. So calling `x()` results
+in a virtual call, whereas `foo()` is statically dispatched, because the type
+of `foo` tells us precisely what function is being called.
+
+As noted above, coercions mean that most code doesn't have to be
+concerned with this distinction. However, you can tell the difference
+when using **transmute** to convert a fn item into a fn pointer.
+
+This is sometimes done as part of an FFI:
+
+```compile_fail,E0591
+extern "C" fn foo(userdata: Box<i32>) {
+    /* ... */
+}
+
+# fn callback(_: extern "C" fn(*mut i32)) {}
+# use std::mem::transmute;
+# unsafe {
+let f: extern "C" fn(*mut i32) = transmute(foo);
+callback(f);
+# }
+```
+
+Here, transmute is being used to convert the types of the fn arguments.
+This pattern is incorrect because, because the type of `foo` is a function
+**item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
+is a function pointer, which is not zero-sized.
+This pattern should be rewritten. There are a few possible ways to do this:
+
+- change the original fn declaration to match the expected signature,
+  and do the cast in the fn body (the preferred option)
+- cast the fn item fo a fn pointer before calling transmute, as shown here:
+
+    ```
+    # extern "C" fn foo(_: Box<i32>) {}
+    # use std::mem::transmute;
+    # unsafe {
+    let f: extern "C" fn(*mut i32) = transmute(foo as extern "C" fn(_));
+    let f: extern "C" fn(*mut i32) = transmute(foo as usize); // works too
+    # }
+    ```
+
+The same applies to transmutes to `*mut fn()`, which were observed in practice.
+Note though that use of this type is generally incorrect.
+The intention is typically to describe a function pointer, but just `fn()`
+alone suffices for that. `*mut fn()` is a pointer to a fn pointer.
+(Since these values are typically just passed to C code, however, this rarely
+makes a difference in practice.)
+
+[rfc401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
+"##,
+
+E0512: r##"
+Transmute with two differently sized types was attempted. Erroneous code
+example:
+
+```compile_fail,E0512
+fn takes_u8(_: u8) {}
+
+fn main() {
+    unsafe { takes_u8(::std::mem::transmute(0u16)); }
+    // error: cannot transmute between types of different sizes,
+    //        or dependently-sized types
+}
+```
+
+Please use types with same size or use the expected type directly. Example:
+
+```
+fn takes_u8(_: u8) {}
+
+fn main() {
+    unsafe { takes_u8(::std::mem::transmute(0i8)); } // ok!
+    // or:
+    unsafe { takes_u8(0u8); } // ok!
+}
+```
+"##,
+
 ;
     E0226, // only a single explicit lifetime bound is permitted
     E0472, // asm! is unsupported on this target
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index 7b5aea8ac98..91a7e9f5d7f 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -1,14 +1,14 @@
-use crate::hir::def::{Res, DefKind};
-use crate::hir::def_id::DefId;
-use crate::ty::{self, Ty, TyCtxt};
-use crate::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx};
-use crate::ty::query::Providers;
+use rustc::hir::def::{Res, DefKind};
+use rustc::hir::def_id::DefId;
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx};
+use rustc::ty::query::Providers;
 
 use rustc_target::spec::abi::Abi::RustIntrinsic;
 use rustc_index::vec::Idx;
 use syntax_pos::{Span, sym};
-use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use crate::hir;
+use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
+use rustc::hir;
 
 fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 6c7958fb365..db59d8e101f 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -13,6 +13,10 @@
 
 #[macro_use]
 extern crate rustc;
+#[macro_use]
+extern crate log;
+#[macro_use]
+extern crate syntax;
 
 use rustc::ty::query::Providers;
 
@@ -22,7 +26,14 @@ pub mod ast_validation;
 pub mod hir_stats;
 pub mod layout_test;
 pub mod loops;
+pub mod dead;
+pub mod entry;
+mod liveness;
+mod intrinsicck;
 
 pub fn provide(providers: &mut Providers<'_>) {
+    entry::provide(providers);
     loops::provide(providers);
+    liveness::provide(providers);
+    intrinsicck::provide(providers);
 }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc_passes/liveness.rs
index a654a26eb0b..fb06808619f 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -96,17 +96,17 @@
 use self::LiveNodeKind::*;
 use self::VarKind::*;
 
-use crate::hir;
-use crate::hir::{Expr, HirId};
-use crate::hir::def::*;
-use crate::hir::def_id::DefId;
-use crate::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
-use crate::hir::Node;
-use crate::hir::ptr::P;
-use crate::ty::{self, TyCtxt};
-use crate::ty::query::Providers;
-use crate::lint;
-use crate::util::nodemap::{HirIdMap, HirIdSet};
+use rustc::hir;
+use rustc::hir::{Expr, HirId};
+use rustc::hir::def::*;
+use rustc::hir::def_id::DefId;
+use rustc::hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
+use rustc::hir::Node;
+use rustc::hir::ptr::P;
+use rustc::ty::{self, TyCtxt};
+use rustc::ty::query::Providers;
+use rustc::lint;
+use rustc::util::nodemap::{HirIdMap, HirIdSet};
 
 use errors::Applicability;
 use rustc_data_structures::fx::FxIndexMap;
@@ -373,7 +373,7 @@ fn visit_fn<'tcx>(
 
     for param in &body.params {
         let is_shorthand = match param.pat.kind {
-            crate::hir::PatKind::Struct(..) => true,
+            rustc::hir::PatKind::Struct(..) => true,
             _ => false,
         };
         param.pat.each_binding(|_bm, hir_id, _x, ident| {
@@ -411,7 +411,7 @@ fn add_from_pat(ir: &mut IrMaps<'_>, pat: &P<hir::Pat>) {
     let mut pats = VecDeque::new();
     pats.push_back(pat);
     while let Some(pat) = pats.pop_front() {
-        use crate::hir::PatKind::*;
+        use rustc::hir::PatKind::*;
         match &pat.kind {
             Binding(.., inner_pat) => {
                 pats.extend(inner_pat.iter());
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e7292b52ab3..68d3bb00abc 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -9,7 +9,6 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
-#![feature(inner_deref)]
 #![feature(crate_visibility_modifier)]
 #![feature(label_break_value)]
 #![feature(mem_take)]
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index e3c898610cd..70b508d4786 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -1,6 +1,5 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(nll)]
-#![feature(inner_deref)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_target/abi/call/asmjs.rs b/src/librustc_target/abi/call/asmjs.rs
new file mode 100644
index 00000000000..92c86372a86
--- /dev/null
+++ b/src/librustc_target/abi/call/asmjs.rs
@@ -0,0 +1,47 @@
+use crate::abi::call::{FnType, ArgType, Uniform};
+use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+
+// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128
+
+// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
+// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.
+
+fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
+    where Ty: TyLayoutMethods<'a, C> + Copy,
+          C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
+{
+    if ret.layout.is_aggregate() {
+        if let Some(unit) = ret.layout.homogeneous_aggregate(cx).unit() {
+            let size = ret.layout.size;
+            if unit.size == size {
+                ret.cast_to(Uniform {
+                    unit,
+                    total: size
+                });
+                return;
+            }
+        }
+
+        ret.make_indirect();
+    }
+}
+
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
+    if arg.layout.is_aggregate() {
+        arg.make_indirect_byval();
+    }
+}
+
+pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
+    where Ty: TyLayoutMethods<'a, C> + Copy,
+          C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
+{
+    if !fty.ret.is_ignore() {
+        classify_ret_ty(cx, &mut fty.ret);
+    }
+
+    for arg in &mut fty.args {
+        if arg.is_ignore() { continue; }
+        classify_arg_ty(arg);
+    }
+}
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 17bad189bcf..bc21113527e 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -5,6 +5,7 @@ use crate::spec::{self, HasTargetSpec};
 mod aarch64;
 mod amdgpu;
 mod arm;
+mod asmjs;
 mod hexagon;
 mod mips;
 mod mips64;
@@ -21,7 +22,6 @@ mod x86;
 mod x86_64;
 mod x86_win64;
 mod wasm32;
-mod wasm32_bindgen_compat;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
 pub enum PassMode {
@@ -557,6 +557,14 @@ impl<'a, Ty> FnType<'a, Ty> {
             "powerpc" => powerpc::compute_abi_info(cx, self),
             "powerpc64" => powerpc64::compute_abi_info(cx, self),
             "s390x" => s390x::compute_abi_info(cx, self),
+            "asmjs" => asmjs::compute_abi_info(cx, self),
+            "wasm32" => {
+                if cx.target_spec().llvm_target.contains("emscripten") {
+                    asmjs::compute_abi_info(cx, self)
+                } else {
+                    wasm32::compute_abi_info(self)
+                }
+            }
             "msp430" => msp430::compute_abi_info(self),
             "sparc" => sparc::compute_abi_info(cx, self),
             "sparc64" => sparc64::compute_abi_info(cx, self),
@@ -565,9 +573,6 @@ impl<'a, Ty> FnType<'a, Ty> {
             "hexagon" => hexagon::compute_abi_info(self),
             "riscv32" => riscv::compute_abi_info(self, 32),
             "riscv64" => riscv::compute_abi_info(self, 64),
-            "wasm32" if cx.target_spec().target_os != "emscripten"
-                => wasm32_bindgen_compat::compute_abi_info(self),
-            "wasm32" | "asmjs" => wasm32::compute_abi_info(cx, self),
             a => return Err(format!("unrecognized arch \"{}\" in target specification", a))
         }
 
diff --git a/src/librustc_target/abi/call/wasm32.rs b/src/librustc_target/abi/call/wasm32.rs
index 27799edab91..1fdcbb8e39b 100644
--- a/src/librustc_target/abi/call/wasm32.rs
+++ b/src/librustc_target/abi/call/wasm32.rs
@@ -1,60 +1,20 @@
-use crate::abi::call::{FnType, ArgType, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
+use crate::abi::call::{FnType, ArgType};
 
-fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgType<'a, Ty>) -> bool
-    where Ty: TyLayoutMethods<'a, C> + Copy,
-          C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
-{
-    if val.layout.is_aggregate() {
-        if let Some(unit) = val.layout.homogeneous_aggregate(cx).unit() {
-            let size = val.layout.size;
-            if unit.size == size {
-                val.cast_to(Uniform {
-                    unit,
-                    total: size
-                });
-                return true;
-            }
-        }
-    }
-    false
-}
-
-
-fn classify_ret_ty<'a, Ty, C>(cx: &C, ret: &mut ArgType<'a, Ty>)
-    where Ty: TyLayoutMethods<'a, C> + Copy,
-          C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
-{
+fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
     ret.extend_integer_width_to(32);
-    if ret.layout.is_aggregate() {
-        if !unwrap_trivial_aggregate(cx, ret) {
-            ret.make_indirect();
-        }
-    }
 }
 
-fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>)
-    where Ty: TyLayoutMethods<'a, C> + Copy,
-          C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
-{
+fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
     arg.extend_integer_width_to(32);
-    if arg.layout.is_aggregate() {
-        if !unwrap_trivial_aggregate(cx, arg) {
-            arg.make_indirect_byval();
-        }
-    }
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType<'a, Ty>)
-    where Ty: TyLayoutMethods<'a, C> + Copy,
-          C: LayoutOf<Ty = Ty, TyLayout = TyLayout<'a, Ty>> + HasDataLayout
-{
+pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
     if !fty.ret.is_ignore() {
-        classify_ret_ty(cx, &mut fty.ret);
+        classify_ret_ty(&mut fty.ret);
     }
 
     for arg in &mut fty.args {
         if arg.is_ignore() { continue; }
-        classify_arg_ty(cx, arg);
+        classify_arg_ty(arg);
     }
 }
diff --git a/src/librustc_target/abi/call/wasm32_bindgen_compat.rs b/src/librustc_target/abi/call/wasm32_bindgen_compat.rs
deleted file mode 100644
index 2645e30594c..00000000000
--- a/src/librustc_target/abi/call/wasm32_bindgen_compat.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// This is not and has never been a correct C ABI for WebAssembly, but
-// for a long time this was the C ABI that Rust used. wasm-bindgen
-// depends on ABI details for this ABI and is incompatible with the
-// correct C ABI, so this ABI is being kept around until wasm-bindgen
-// can be fixed to work with the correct ABI. See #63649 for further
-// discussion.
-
-use crate::abi::call::{FnType, ArgType};
-
-fn classify_ret_ty<Ty>(ret: &mut ArgType<'_, Ty>) {
-    ret.extend_integer_width_to(32);
-}
-
-fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>) {
-    arg.extend_integer_width_to(32);
-}
-
-pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>) {
-    if !fty.ret.is_ignore() {
-        classify_ret_ty(&mut fty.ret);
-    }
-
-    for arg in &mut fty.args {
-        if arg.is_ignore() { continue; }
-        classify_arg_ty(arg);
-    }
-}
diff --git a/src/librustc_target/spec/asmjs_unknown_emscripten.rs b/src/librustc_target/spec/asmjs_unknown_emscripten.rs
index e8f9c1f3d61..6dc140cf160 100644
--- a/src/librustc_target/spec/asmjs_unknown_emscripten.rs
+++ b/src/librustc_target/spec/asmjs_unknown_emscripten.rs
@@ -1,10 +1,40 @@
-use super::{LinkerFlavor, Target, wasm32_unknown_emscripten};
+use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};
 
 pub fn target() -> Result<Target, String> {
-    let mut target = wasm32_unknown_emscripten::target()?;
-    target.options.post_link_args
-        .entry(LinkerFlavor::Em)
-        .or_default()
-        .extend(vec!["-s".to_string(), "WASM=0".to_string()]);
-    Ok(target)
+    let mut args = LinkArgs::new();
+    args.insert(LinkerFlavor::Em,
+                vec!["-s".to_string(),
+                     "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
+                     "-s".to_string(),
+                     "ABORTING_MALLOC=0".to_string(),
+                     "-s".to_string(),
+                     "WASM=0".to_string()]);
+
+    let opts = TargetOptions {
+        dynamic_linking: false,
+        executables: true,
+        exe_suffix: ".js".to_string(),
+        linker_is_gnu: true,
+        allow_asm: false,
+        obj_is_bitcode: true,
+        is_like_emscripten: true,
+        max_atomic_width: Some(32),
+        post_link_args: args,
+        target_family: Some("unix".to_string()),
+        codegen_backend: "emscripten".to_string(),
+        .. Default::default()
+    };
+    Ok(Target {
+        llvm_target: "asmjs-unknown-emscripten".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        target_os: "emscripten".to_string(),
+        target_env: String::new(),
+        target_vendor: "unknown".to_string(),
+        data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(),
+        arch: "asmjs".to_string(),
+        linker_flavor: LinkerFlavor::Em,
+        options: opts,
+    })
 }
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index cf1a84dec97..25add0cc6a4 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -462,6 +462,7 @@ supported_targets! {
     ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
     ("wasm32-unknown-unknown", wasm32_unknown_unknown),
     ("wasm32-wasi", wasm32_wasi),
+    ("wasm32-experimental-emscripten", wasm32_experimental_emscripten),
 
     ("thumbv6m-none-eabi", thumbv6m_none_eabi),
     ("thumbv7m-none-eabi", thumbv7m_none_eabi),
diff --git a/src/librustc_target/spec/wasm32_experimental_emscripten.rs b/src/librustc_target/spec/wasm32_experimental_emscripten.rs
new file mode 100644
index 00000000000..b802bee25ae
--- /dev/null
+++ b/src/librustc_target/spec/wasm32_experimental_emscripten.rs
@@ -0,0 +1,44 @@
+use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};
+
+pub fn target() -> Result<Target, String> {
+    let mut post_link_args = LinkArgs::new();
+    post_link_args.insert(LinkerFlavor::Em,
+                          vec!["-s".to_string(),
+                               "WASM=1".to_string(),
+                               "-s".to_string(),
+                               "ASSERTIONS=1".to_string(),
+                               "-s".to_string(),
+                               "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
+                               "-g3".to_string()]);
+
+    let opts = TargetOptions {
+        dynamic_linking: false,
+        executables: true,
+        // Today emcc emits two files - a .js file to bootstrap and
+        // possibly interpret the wasm, and a .wasm file
+        exe_suffix: ".js".to_string(),
+        linker_is_gnu: true,
+        link_env: vec![("EMCC_WASM_BACKEND".to_string(), "1".to_string())],
+        allow_asm: false,
+        obj_is_bitcode: true,
+        is_like_emscripten: true,
+        max_atomic_width: Some(32),
+        post_link_args,
+        limit_rdylib_exports: false,
+        target_family: Some("unix".to_string()),
+        .. Default::default()
+    };
+    Ok(Target {
+        llvm_target: "wasm32-unknown-unknown".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        target_os: "emscripten".to_string(),
+        target_env: String::new(),
+        target_vendor: "unknown".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
+        arch: "wasm32".to_string(),
+        linker_flavor: LinkerFlavor::Em,
+        options: opts,
+    })
+}
diff --git a/src/librustc_target/spec/wasm32_unknown_emscripten.rs b/src/librustc_target/spec/wasm32_unknown_emscripten.rs
index 6a2c8c49537..e0df36884bf 100644
--- a/src/librustc_target/spec/wasm32_unknown_emscripten.rs
+++ b/src/librustc_target/spec/wasm32_unknown_emscripten.rs
@@ -1,46 +1,45 @@
-use super::wasm32_base;
-use super::{LinkArgs, LinkerFlavor, Target, TargetOptions, PanicStrategy};
+use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};
 
 pub fn target() -> Result<Target, String> {
+    // FIXME(nikic) BINARYEN_TRAP_MODE=clamp is needed to avoid trapping in our
+    // -Zsaturating-float-casts implementation. This can be dropped if/when
+    // we have native fpto[su]i.sat intrinsics, or the implementation otherwise
+    // stops relying on non-trapping fpto[su]i.
     let mut post_link_args = LinkArgs::new();
     post_link_args.insert(LinkerFlavor::Em,
                           vec!["-s".to_string(),
-                               "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
-                               "-s".to_string(),
-                               "ASSERTIONS=1".to_string(),
+                               "BINARYEN=1".to_string(),
                                "-s".to_string(),
-                               "DISABLE_EXCEPTION_CATCHING=1".to_string(),
+                               "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
                                "-s".to_string(),
-                               "ABORTING_MALLOC=0".to_string(),
-                               // FIXME(tlively): Enable this linker option once libc type errors
-                               // are resolved. See https://github.com/rust-lang/libc/pull/1478.
-                               // "-Wl,--fatal-warnings".to_string(),
-                               ]);
+                               "BINARYEN_TRAP_MODE='clamp'".to_string()]);
 
     let opts = TargetOptions {
-        // emcc emits two files - a .js file to instantiate the wasm and supply platform
-        // functionality, and a .wasm file.
+        dynamic_linking: false,
+        executables: true,
+        // Today emcc emits two files - a .js file to bootstrap and
+        // possibly interpret the wasm, and a .wasm file
         exe_suffix: ".js".to_string(),
-        linker: None,
         linker_is_gnu: true,
+        allow_asm: false,
+        obj_is_bitcode: true,
         is_like_emscripten: true,
-        // FIXME(tlively): Emscripten supports unwinding, but we would have to pass
-        // -enable-emscripten-cxx-exceptions to LLVM at codegen time and merge
-        // https://reviews.llvm.org/rG5c3cdef84b82464756bb571c13c31cf7773860c3to use it.
-        panic_strategy: PanicStrategy::Abort,
+        max_atomic_width: Some(32),
         post_link_args,
+        limit_rdylib_exports: false,
         target_family: Some("unix".to_string()),
-        .. wasm32_base::options()
+        codegen_backend: "emscripten".to_string(),
+        .. Default::default()
     };
     Ok(Target {
-        llvm_target: "wasm32-unknown-emscripten".to_string(),
+        llvm_target: "asmjs-unknown-emscripten".to_string(),
         target_endian: "little".to_string(),
         target_pointer_width: "32".to_string(),
         target_c_int_width: "32".to_string(),
         target_os: "emscripten".to_string(),
         target_env: String::new(),
         target_vendor: "unknown".to_string(),
-        data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
+        data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(),
         arch: "wasm32".to_string(),
         linker_flavor: LinkerFlavor::Em,
         options: opts,
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index 7db1a7413c7..88e62db9a10 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -223,7 +223,7 @@ fn dtorck_constraint_for_ty<'tcx>(
             // *do* incorporate the upvars here.
 
             let constraint = DtorckConstraint {
-                outlives: substs.upvar_tys(def_id, tcx).map(|t| t.into()).collect(),
+                outlives: substs.as_generator().upvar_tys(def_id, tcx).map(|t| t.into()).collect(),
                 dtorck_types: vec![],
                 overflows: vec![],
             };
diff --git a/src/librustc_traits/generic_types.rs b/src/librustc_traits/generic_types.rs
index 91ca6415bdc..cc5348623fa 100644
--- a/src/librustc_traits/generic_types.rs
+++ b/src/librustc_traits/generic_types.rs
@@ -73,7 +73,9 @@ crate fn closure(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
 }
 
 crate fn generator(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
-    tcx.mk_generator(def_id, ty::GeneratorSubsts {
-        substs: InternalSubsts::bound_vars_for_item(tcx, def_id),
-    }, hir::GeneratorMovability::Movable)
+    tcx.mk_generator(
+        def_id,
+        InternalSubsts::bound_vars_for_item(tcx, def_id),
+        hir::GeneratorMovability::Movable
+    )
 }
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 03f0860c660..8b97bf643e9 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -113,21 +113,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         });
         if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types {
-            let substs = ty::GeneratorSubsts { substs };
+            let generator_substs = substs.as_generator();
             self.demand_eqtype(
                 expr.span,
                 yield_ty,
-                substs.yield_ty(expr_def_id, self.tcx),
+                generator_substs.yield_ty(expr_def_id, self.tcx),
             );
             self.demand_eqtype(
                 expr.span,
                 liberated_sig.output(),
-                substs.return_ty(expr_def_id, self.tcx),
+                generator_substs.return_ty(expr_def_id, self.tcx),
             );
             self.demand_eqtype(
                 expr.span,
                 interior,
-                substs.witness(expr_def_id, self.tcx),
+                generator_substs.witness(expr_def_id, self.tcx),
             );
             return self.tcx.mk_generator(expr_def_id, substs, movability);
         }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 26a8f79b8d8..e2e8c09bb58 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -67,7 +67,6 @@ This API is completely unstable and subject to change.
 #![feature(nll)]
 #![feature(slice_patterns)]
 #![feature(never_type)]
-#![feature(inner_deref)]
 #![feature(mem_take)]
 
 #![recursion_limit="256"]
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 7de2583b9f6..da3b52afadf 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -360,7 +360,7 @@ impl<'a> fmt::Display for Html<'a> {
                     ("target_arch", Some(arch)) => match &*arch.as_str() {
                         "aarch64" => "AArch64",
                         "arm" => "ARM",
-                        "asmjs" => "JavaScript",
+                        "asmjs" => "asm.js",
                         "mips" => "MIPS",
                         "mips64" => "MIPS-64",
                         "msp430" => "MSP430",
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 539bf5dfe28..faa8eab7a29 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -14,7 +14,6 @@
 #![feature(crate_visibility_modifier)]
 #![feature(const_fn)]
 #![feature(drain_filter)]
-#![feature(inner_deref)]
 #![feature(never_type)]
 #![feature(mem_take)]
 #![feature(unicode_internals)]
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index a5e7cd992f2..46bbd8855de 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -185,7 +185,6 @@ impl UdpSocket {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(udp_peer_addr)]
     /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
@@ -199,14 +198,13 @@ impl UdpSocket {
     /// [`NotConnected`]: ../../std/io/enum.ErrorKind.html#variant.NotConnected
     ///
     /// ```no_run
-    /// #![feature(udp_peer_addr)]
     /// use std::net::UdpSocket;
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
     /// assert_eq!(socket.peer_addr().unwrap_err().kind(),
     ///            ::std::io::ErrorKind::NotConnected);
     /// ```
-    #[unstable(feature = "udp_peer_addr", issue = "59127")]
+    #[stable(feature = "udp_peer_addr", since = "1.40.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         self.0.peer_addr()
     }
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 28fb4024404..638ce1679b8 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -15,9 +15,11 @@ use crate::intrinsics;
 use crate::mem;
 use crate::ptr;
 use crate::raw;
+use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::stdio::panic_output;
 use crate::sys_common::rwlock::RWLock;
-use crate::sys_common::{thread_info, util, backtrace};
+use crate::sys_common::{thread_info, util};
+use crate::sys_common::backtrace::{self, RustBacktrace};
 use crate::thread;
 
 #[cfg(not(test))]
@@ -158,16 +160,10 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
 fn default_hook(info: &PanicInfo<'_>) {
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
-    let log_backtrace = if cfg!(feature = "backtrace") {
-        let panics = update_panic_count(0);
-
-        if panics >= 2 {
-            Some(backtrace_rs::PrintFmt::Full)
-        } else {
-            backtrace::log_enabled()
-        }
+    let backtrace_env = if update_panic_count(0) >= 2 {
+        RustBacktrace::Print(backtrace_rs::PrintFmt::Full)
     } else {
-        None
+        backtrace::rust_backtrace_env()
     };
 
     // The current implementation always returns `Some`.
@@ -187,16 +183,16 @@ fn default_hook(info: &PanicInfo<'_>) {
         let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
                          name, msg, location);
 
-        if cfg!(feature = "backtrace") {
-            use crate::sync::atomic::{AtomicBool, Ordering};
-
-            static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
+        static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 
-            if let Some(format) = log_backtrace {
-                let _ = backtrace::print(err, format);
-            } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
-                let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
-                                       environment variable to display a backtrace.");
+        match backtrace_env {
+            RustBacktrace::Print(format) => drop(backtrace::print(err, format)),
+            RustBacktrace::Disabled => {}
+            RustBacktrace::RuntimeDisabled => {
+                if FIRST_PANIC.swap(false, Ordering::SeqCst) {
+                    let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
+                                           environment variable to display a backtrace.");
+                }
             }
         }
     };
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index cf45eb0daba..63e35d5ed91 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -44,12 +44,9 @@ fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindS
         sys::args::init(argc, argv);
 
         // Let's run some code!
-        #[cfg(feature = "backtrace")]
         let exit_code = panic::catch_unwind(|| {
             sys_common::backtrace::__rust_begin_short_backtrace(move || main())
         });
-        #[cfg(not(feature = "backtrace"))]
-        let exit_code = panic::catch_unwind(move || main());
 
         sys_common::cleanup();
         exit_code.unwrap_or(101) as isize
diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs
index d7e733b7fa0..952ba40ee87 100644
--- a/src/libstd/sys/unix/fast_thread_local.rs
+++ b/src/libstd/sys/unix/fast_thread_local.rs
@@ -10,8 +10,7 @@
 // fallback implementation to use as well.
 //
 // Due to rust-lang/rust#18804, make sure this is not generic!
-#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox",
-          target_os = "emscripten"))]
+#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox"))]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
     use crate::mem;
     use crate::sys_common::thread_local::register_dtor_fallback;
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 01711d415d8..9c406ec39cc 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -7,6 +7,7 @@ use crate::io;
 use crate::borrow::Cow;
 use crate::io::prelude::*;
 use crate::path::{self, Path, PathBuf};
+use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
 use backtrace_rs::{BacktraceFmt, BytesOrWideString, PrintFmt};
@@ -115,8 +116,10 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
     Ok(())
 }
 
-/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
-#[inline(never)]
+/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
+/// this is only inline(never) when backtraces in libstd are enabled, otherwise
+/// it's fine to optimize away.
+#[cfg_attr(feature = "backtrace", inline(never))]
 pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
 where
     F: FnOnce() -> T,
@@ -126,42 +129,49 @@ where
     f()
 }
 
+pub enum RustBacktrace {
+    Print(PrintFmt),
+    Disabled,
+    RuntimeDisabled,
+}
+
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
-pub fn log_enabled() -> Option<PrintFmt> {
-    use crate::sync::atomic::{self, Ordering};
+pub fn rust_backtrace_env() -> RustBacktrace {
+    // If the `backtrace` feature of this crate isn't enabled quickly return
+    // `None` so this can be constant propagated all over the place to turn
+    // optimize away callers.
+    if !cfg!(feature = "backtrace") {
+        return RustBacktrace::Disabled;
+    }
 
     // Setting environment variables for Fuchsia components isn't a standard
     // or easily supported workflow. For now, always display backtraces.
     if cfg!(target_os = "fuchsia") {
-        return Some(PrintFmt::Full);
+        return RustBacktrace::Print(PrintFmt::Full);
     }
 
     static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
     match ENABLED.load(Ordering::SeqCst) {
         0 => {}
-        1 => return None,
-        2 => return Some(PrintFmt::Short),
-        _ => return Some(PrintFmt::Full),
+        1 => return RustBacktrace::RuntimeDisabled,
+        2 => return RustBacktrace::Print(PrintFmt::Short),
+        _ => return RustBacktrace::Print(PrintFmt::Full),
     }
 
-    let val = env::var_os("RUST_BACKTRACE").and_then(|x| {
-        if &x == "0" {
-            None
-        } else if &x == "full" {
-            Some(PrintFmt::Full)
-        } else {
-            Some(PrintFmt::Short)
-        }
-    });
-    ENABLED.store(
-        match val {
-            Some(v) => v as isize,
-            None => 1,
-        },
-        Ordering::SeqCst,
-    );
-    val
+    let (format, cache) = env::var_os("RUST_BACKTRACE")
+        .map(|x| {
+            if &x == "0" {
+                (RustBacktrace::RuntimeDisabled, 1)
+            } else if &x == "full" {
+                (RustBacktrace::Print(PrintFmt::Full), 3)
+            } else {
+                (RustBacktrace::Print(PrintFmt::Short), 2)
+            }
+        })
+        .unwrap_or((RustBacktrace::RuntimeDisabled, 1));
+    ENABLED.store(cache, Ordering::SeqCst);
+    format
 }
 
 /// Prints the filename of the backtrace frame.
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 764041d2f42..0ffa6ace2e4 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -465,12 +465,9 @@ impl Builder {
             }
 
             thread_info::set(imp::guard::current(), their_thread);
-            #[cfg(feature = "backtrace")]
             let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                 crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
             }));
-            #[cfg(not(feature = "backtrace"))]
-            let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
             *their_packet.get() = Some(try_result);
         };
 
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 3bf2b8be1fe..e1ae01b602a 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -15,10 +15,10 @@
 use crate::cmp;
 use crate::error::Error;
 use crate::fmt;
-use crate::ops::{Add, Sub, AddAssign, SubAssign};
+use crate::ops::{Add, AddAssign, Sub, SubAssign};
 use crate::sys::time;
-use crate::sys_common::FromInner;
 use crate::sys_common::mutex::Mutex;
+use crate::sys_common::FromInner;
 
 #[stable(feature = "time", since = "1.3.0")]
 pub use core::time::Duration;
@@ -216,17 +216,17 @@ impl Instant {
         // * https://bugzilla.mozilla.org/show_bug.cgi?id=1487778 - a similar
         //   Firefox bug
         //
-        // It simply seems that this it just happens so that a lot in the wild
-        // we're seeing panics across various platforms where consecutive calls
+        // It seems that this just happens a lot in the wild.
+        // We're seeing panics across various platforms where consecutive calls
         // to `Instant::now`, such as via the `elapsed` function, are panicking
         // as they're going backwards. Placed here is a last-ditch effort to try
         // to fix things up. We keep a global "latest now" instance which is
         // returned instead of what the OS says if the OS goes backwards.
         //
-        // To hopefully mitigate the impact of this though a few platforms are
+        // To hopefully mitigate the impact of this, a few platforms are
         // whitelisted as "these at least haven't gone backwards yet".
         if time::Instant::actually_monotonic() {
-            return Instant(os_now)
+            return Instant(os_now);
         }
 
         static LOCK: Mutex = Mutex::new();
@@ -353,8 +353,7 @@ impl Add<Duration> for Instant {
     ///
     /// [`checked_add`]: ../../std/time/struct.Instant.html#method.checked_add
     fn add(self, other: Duration) -> Instant {
-        self.checked_add(other)
-            .expect("overflow when adding duration to instant")
+        self.checked_add(other).expect("overflow when adding duration to instant")
     }
 }
 
@@ -370,8 +369,7 @@ impl Sub<Duration> for Instant {
     type Output = Instant;
 
     fn sub(self, other: Duration) -> Instant {
-        self.checked_sub(other)
-            .expect("overflow when subtracting duration from instant")
+        self.checked_sub(other).expect("overflow when subtracting duration from instant")
     }
 }
 
@@ -464,8 +462,7 @@ impl SystemTime {
     /// println!("{:?}", difference);
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
-    pub fn duration_since(&self, earlier: SystemTime)
-                          -> Result<Duration, SystemTimeError> {
+    pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
@@ -532,8 +529,7 @@ impl Add<Duration> for SystemTime {
     ///
     /// [`checked_add`]: ../../std/time/struct.SystemTime.html#method.checked_add
     fn add(self, dur: Duration) -> SystemTime {
-        self.checked_add(dur)
-            .expect("overflow when adding duration to instant")
+        self.checked_add(dur).expect("overflow when adding duration to instant")
     }
 }
 
@@ -549,8 +545,7 @@ impl Sub<Duration> for SystemTime {
     type Output = SystemTime;
 
     fn sub(self, dur: Duration) -> SystemTime {
-        self.checked_sub(dur)
-            .expect("overflow when subtracting duration from instant")
+        self.checked_sub(dur).expect("overflow when subtracting duration from instant")
     }
 }
 
@@ -626,7 +621,9 @@ impl SystemTimeError {
 
 #[stable(feature = "time2", since = "1.8.0")]
 impl Error for SystemTimeError {
-    fn description(&self) -> &str { "other time was not earlier than self" }
+    fn description(&self) -> &str {
+        "other time was not earlier than self"
+    }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
@@ -644,17 +641,16 @@ impl FromInner<time::SystemTime> for SystemTime {
 
 #[cfg(test)]
 mod tests {
-    use super::{Instant, SystemTime, Duration, UNIX_EPOCH};
+    use super::{Duration, Instant, SystemTime, UNIX_EPOCH};
 
     macro_rules! assert_almost_eq {
-        ($a:expr, $b:expr) => ({
+        ($a:expr, $b:expr) => {{
             let (a, b) = ($a, $b);
             if a != b {
-                let (a, b) = if a > b {(a, b)} else {(b, a)};
-                assert!(a - Duration::new(0, 1000) <= b,
-                        "{:?} is not almost equal to {:?}", a, b);
+                let (a, b) = if a > b { (a, b) } else { (b, a) };
+                assert!(a - Duration::new(0, 1000) <= b, "{:?} is not almost equal to {:?}", a, b);
             }
-        })
+        }};
     }
 
     #[test]
@@ -729,7 +725,7 @@ mod tests {
     fn instant_saturating_duration_since_nopanic() {
         let a = Instant::now();
         let ret = (a - Duration::new(1, 0)).saturating_duration_since(a);
-        assert_eq!(ret, Duration::new(0,0));
+        assert_eq!(ret, Duration::new(0, 0));
     }
 
     #[test]
@@ -755,15 +751,14 @@ mod tests {
 
         let second = Duration::new(1, 0);
         assert_almost_eq!(a.duration_since(a - second).unwrap(), second);
-        assert_almost_eq!(a.duration_since(a + second).unwrap_err()
-                           .duration(), second);
+        assert_almost_eq!(a.duration_since(a + second).unwrap_err().duration(), second);
 
         assert_almost_eq!(a - second + second, a);
         assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
 
         let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
-        let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000)
-            + Duration::new(0, 500_000_000);
+        let one_second_from_epoch2 =
+            UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000);
         assert_eq!(one_second_from_epoch, one_second_from_epoch2);
 
         // checked_add_duration will not panic on overflow
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 4ad0bd06d99..f376c19a66c 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -17,6 +17,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
 use log::{debug, trace};
 use std::mem;
 
+const TURBOFISH: &'static str = "use `::<...>` instead of `<...>` to specify type arguments";
 /// Creates a placeholder argument.
 crate fn dummy_arg(ident: Ident) -> Param {
     let pat = P(Pat {
@@ -543,35 +544,154 @@ impl<'a> Parser<'a> {
     }
 
     /// Produces an error if comparison operators are chained (RFC #558).
-    /// We only need to check the LHS, not the RHS, because all comparison ops
-    /// have same precedence and are left-associative.
-    crate fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) -> PResult<'a, ()> {
-        debug_assert!(outer_op.is_comparison(),
-                      "check_no_chained_comparison: {:?} is not comparison",
-                      outer_op);
+    /// We only need to check the LHS, not the RHS, because all comparison ops have same
+    /// precedence (see `fn precedence`) and are left-associative (see `fn fixity`).
+    ///
+    /// This can also be hit if someone incorrectly writes `foo<bar>()` when they should have used
+    /// the turbofish (`foo::<bar>()`) syntax. We attempt some heuristic recovery if that is the
+    /// case.
+    ///
+    /// Keep in mind that given that `outer_op.is_comparison()` holds and comparison ops are left
+    /// associative we can infer that we have:
+    ///
+    ///           outer_op
+    ///           /   \
+    ///     inner_op   r2
+    ///        /  \
+    ///     l1    r1
+    crate fn check_no_chained_comparison(
+        &mut self,
+        lhs: &Expr,
+        outer_op: &AssocOp,
+    ) -> PResult<'a, Option<P<Expr>>> {
+        debug_assert!(
+            outer_op.is_comparison(),
+            "check_no_chained_comparison: {:?} is not comparison",
+            outer_op,
+        );
+
+        let mk_err_expr = |this: &Self, span| {
+            Ok(Some(this.mk_expr(span, ExprKind::Err, ThinVec::new())))
+        };
+
         match lhs.kind {
             ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
                 // Respan to include both operators.
-                let op_span = op.span.to(self.token.span);
+                let op_span = op.span.to(self.prev_span);
                 let mut err = self.struct_span_err(
                     op_span,
                     "chained comparison operators require parentheses",
                 );
+
+                let suggest = |err: &mut DiagnosticBuilder<'_>| {
+                    err.span_suggestion_verbose(
+                        op_span.shrink_to_lo(),
+                        TURBOFISH,
+                        "::".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                };
+
                 if op.node == BinOpKind::Lt &&
                     *outer_op == AssocOp::Less ||  // Include `<` to provide this recommendation
                     *outer_op == AssocOp::Greater  // even in a case like the following:
                 {                                  //     Foo<Bar<Baz<Qux, ()>>>
-                    err.help(
-                        "use `::<...>` instead of `<...>` if you meant to specify type arguments");
-                    err.help("or use `(...)` if you meant to specify fn arguments");
-                    // These cases cause too many knock-down errors, bail out (#61329).
-                    return Err(err);
+                    if *outer_op == AssocOp::Less {
+                        let snapshot = self.clone();
+                        self.bump();
+                        // So far we have parsed `foo<bar<`, consume the rest of the type args.
+                        let modifiers = [
+                            (token::Lt, 1),
+                            (token::Gt, -1),
+                            (token::BinOp(token::Shr), -2),
+                        ];
+                        self.consume_tts(1, &modifiers[..]);
+
+                        if !&[
+                            token::OpenDelim(token::Paren),
+                            token::ModSep,
+                        ].contains(&self.token.kind) {
+                            // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
+                            // parser and bail out.
+                            mem::replace(self, snapshot.clone());
+                        }
+                    }
+                    return if token::ModSep == self.token.kind {
+                        // We have some certainty that this was a bad turbofish at this point.
+                        // `foo< bar >::`
+                        suggest(&mut err);
+
+                        let snapshot = self.clone();
+                        self.bump(); // `::`
+
+                        // Consume the rest of the likely `foo<bar>::new()` or return at `foo<bar>`.
+                        match self.parse_expr() {
+                            Ok(_) => {
+                                // 99% certain that the suggestion is correct, continue parsing.
+                                err.emit();
+                                // FIXME: actually check that the two expressions in the binop are
+                                // paths and resynthesize new fn call expression instead of using
+                                // `ExprKind::Err` placeholder.
+                                mk_err_expr(self, lhs.span.to(self.prev_span))
+                            }
+                            Err(mut expr_err) => {
+                                expr_err.cancel();
+                                // Not entirely sure now, but we bubble the error up with the
+                                // suggestion.
+                                mem::replace(self, snapshot);
+                                Err(err)
+                            }
+                        }
+                    } else if token::OpenDelim(token::Paren) == self.token.kind {
+                        // We have high certainty that this was a bad turbofish at this point.
+                        // `foo< bar >(`
+                        suggest(&mut err);
+                        // Consume the fn call arguments.
+                        match self.consume_fn_args() {
+                            Err(()) => Err(err),
+                            Ok(()) => {
+                                err.emit();
+                                // FIXME: actually check that the two expressions in the binop are
+                                // paths and resynthesize new fn call expression instead of using
+                                // `ExprKind::Err` placeholder.
+                                mk_err_expr(self, lhs.span.to(self.prev_span))
+                            }
+                        }
+                    } else {
+                        // All we know is that this is `foo < bar >` and *nothing* else. Try to
+                        // be helpful, but don't attempt to recover.
+                        err.help(TURBOFISH);
+                        err.help("or use `(...)` if you meant to specify fn arguments");
+                        // These cases cause too many knock-down errors, bail out (#61329).
+                        Err(err)
+                    };
                 }
                 err.emit();
             }
             _ => {}
         }
-        Ok(())
+        Ok(None)
+    }
+
+    fn consume_fn_args(&mut self) -> Result<(), ()> {
+        let snapshot = self.clone();
+        self.bump(); // `(`
+
+        // Consume the fn call arguments.
+        let modifiers = [
+            (token::OpenDelim(token::Paren), 1),
+            (token::CloseDelim(token::Paren), -1),
+        ];
+        self.consume_tts(1, &modifiers[..]);
+
+        if self.token.kind == token::Eof {
+            // Not entirely sure that what we consumed were fn arguments, rollback.
+            mem::replace(self, snapshot);
+            Err(())
+        } else {
+            // 99% certain that the suggestion is correct, continue parsing.
+            Ok(())
+        }
     }
 
     crate fn maybe_report_ambiguous_plus(
@@ -1364,6 +1484,23 @@ impl<'a> Parser<'a> {
         err
     }
 
+    fn consume_tts(
+        &mut self,
+        mut acc: i64, // `i64` because malformed code can have more closing delims than opening.
+        // Not using `FxHashMap` due to `token::TokenKind: !Eq + !Hash`.
+        modifier: &[(token::TokenKind, i64)],
+    ) {
+        while acc > 0 {
+            if let Some((_, val)) = modifier.iter().find(|(t, _)| *t == self.token.kind) {
+                acc += *val;
+            }
+            if self.token.kind == token::Eof {
+                break;
+            }
+            self.bump();
+        }
+    }
+
     /// Replace duplicated recovered parameters with `_` pattern to avoid unecessary errors.
     ///
     /// This is necessary because at this point we don't know whether we parsed a function with
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 23674ad589d..b459782d237 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -238,7 +238,9 @@ impl<'a> Parser<'a> {
 
             self.bump();
             if op.is_comparison() {
-                self.check_no_chained_comparison(&lhs, &op)?;
+                if let Some(expr) = self.check_no_chained_comparison(&lhs, &op)? {
+                    return Ok(expr);
+                }
             }
             // Special cases:
             if op == AssocOp::As {
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 7eb2a73a11a..48f9e301610 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -4,7 +4,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use crate::ptr::P;
 use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
 use crate::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind};
-use crate::mut_visit::{noop_visit_pat, MutVisitor};
+use crate::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor};
 use crate::parse::token::{self};
 use crate::print::pprust;
 use crate::source_map::{respan, Span, Spanned};
@@ -481,6 +481,10 @@ impl<'a> Parser<'a> {
     fn make_all_value_bindings_mutable(pat: &mut P<Pat>) -> bool {
         struct AddMut(bool);
         impl MutVisitor for AddMut {
+            fn visit_mac(&mut self, mac: &mut Mac) {
+                noop_visit_mac(mac, self);
+            }
+
             fn visit_pat(&mut self, pat: &mut P<Pat>) {
                 if let PatKind::Ident(BindingMode::ByValue(ref mut m @ Mutability::Immutable), ..)
                     = pat.kind
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index e8f3434b958..8b76080fc68 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -1478,9 +1478,9 @@ pub fn run_test(
 ) {
     let TestDescAndFn { desc, testfn } = test;
 
-    // FIXME: Re-enable emscripten once it can catch panics again
-    let ignore_because_no_process_support = desc.should_panic != ShouldPanic::No
-        && (cfg!(target_arch = "wasm32") || cfg!(target_os = "emscripten"));
+    let ignore_because_no_process_support = cfg!(target_arch = "wasm32")
+        && !cfg!(target_os = "emscripten")
+        && desc.should_panic != ShouldPanic::No;
 
     if force_ignore || desc.ignore || ignore_because_no_process_support {
         monitor_ch.send((desc, TrIgnored, None, Vec::new())).unwrap();
diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs
index c3727b3013f..b95fb5df710 100644
--- a/src/libtest/tests.rs
+++ b/src/libtest/tests.rs
@@ -2,7 +2,7 @@ use super::*;
 
 use crate::test::{
     filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, RunStrategy,
-    ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts,
+    ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailedMsg,
     TrIgnored, TrOk,
 };
 use std::sync::mpsc::channel;
@@ -90,9 +90,7 @@ pub fn ignored_tests_result_in_ignored() {
     assert!(res == TrIgnored);
 }
 
-// FIXME: Re-enable emscripten once it can catch panics again
 #[test]
-#[cfg(not(target_os = "emscripten"))]
 fn test_should_panic() {
     fn f() {
         panic!();
@@ -112,9 +110,7 @@ fn test_should_panic() {
     assert!(res == TrOk);
 }
 
-// FIXME: Re-enable emscripten once it can catch panics again
 #[test]
-#[cfg(not(target_os = "emscripten"))]
 fn test_should_panic_good_message() {
     fn f() {
         panic!("an error message");
@@ -134,11 +130,8 @@ fn test_should_panic_good_message() {
     assert!(res == TrOk);
 }
 
-// FIXME: Re-enable emscripten once it can catch panics again
 #[test]
-#[cfg(not(target_os = "emscripten"))]
 fn test_should_panic_bad_message() {
-    use crate::tests::TrFailedMsg;
     fn f() {
         panic!("an error message");
     }
@@ -159,9 +152,7 @@ fn test_should_panic_bad_message() {
     assert!(res == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
 }
 
-// FIXME: Re-enable emscripten once it can catch panics again
 #[test]
-#[cfg(not(target_os = "emscripten"))]
 fn test_should_panic_but_succeeds() {
     fn f() {}
     let desc = TestDescAndFn {
diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs
index 7fa61d15f77..2acf95de97e 100644
--- a/src/test/codegen/c-variadic.rs
+++ b/src/test/codegen/c-variadic.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten compiled with panic=abort by default
 // compile-flags: -C no-prepopulate-passes
 // ignore-tidy-linelength
 
diff --git a/src/test/codegen/drop.rs b/src/test/codegen/drop.rs
index 49e40d5f243..307c4e2c1e2 100644
--- a/src/test/codegen/drop.rs
+++ b/src/test/codegen/drop.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten compiled with panic=abort by default
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/extern-functions.rs b/src/test/codegen/extern-functions.rs
index 786f2c8422b..a935d886522 100644
--- a/src/test/codegen/extern-functions.rs
+++ b/src/test/codegen/extern-functions.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten compiled with panic=abort by default
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/external-no-mangle-statics.rs b/src/test/codegen/external-no-mangle-statics.rs
index ee61814678c..e44373926b7 100644
--- a/src/test/codegen/external-no-mangle-statics.rs
+++ b/src/test/codegen/external-no-mangle-statics.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten default visibility is hidden
 // compile-flags: -O
 // `#[no_mangle]`d static variables always have external linkage, i.e., no `internal` in their
 // definitions
diff --git a/src/test/codegen/link_section.rs b/src/test/codegen/link_section.rs
index 88b8692b0ac..86c1365fdb7 100644
--- a/src/test/codegen/link_section.rs
+++ b/src/test/codegen/link_section.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten default visibility is hidden
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/no-output-asm-is-volatile.rs b/src/test/codegen/no-output-asm-is-volatile.rs
index 47b38d29417..ad497b25a9e 100644
--- a/src/test/codegen/no-output-asm-is-volatile.rs
+++ b/src/test/codegen/no-output-asm-is-volatile.rs
@@ -1,5 +1,7 @@
 // compile-flags: -O
 
+// ignore-asmjs
+
 #![feature(asm)]
 #![crate_type = "lib"]
 
diff --git a/src/test/codegen/personality_lifetimes.rs b/src/test/codegen/personality_lifetimes.rs
index c82ae476b1b..05888c0e733 100644
--- a/src/test/codegen/personality_lifetimes.rs
+++ b/src/test/codegen/personality_lifetimes.rs
@@ -1,5 +1,4 @@
 // ignore-msvc
-// ignore-emscripten compiled with panic=abort by default
 
 // compile-flags: -O -C no-prepopulate-passes
 
diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs
index afefb9c9f71..5521c3c849f 100644
--- a/src/test/codegen/repr-transparent-aggregates-2.rs
+++ b/src/test/codegen/repr-transparent-aggregates-2.rs
@@ -1,7 +1,7 @@
 // compile-flags: -C no-prepopulate-passes
 
 // ignore-aarch64
-// ignore-emscripten
+// ignore-asmjs
 // ignore-mips64
 // ignore-powerpc
 // ignore-powerpc64
@@ -9,6 +9,7 @@
 // ignore-s390x
 // ignore-sparc
 // ignore-sparc64
+// ignore-wasm
 // ignore-x86
 // ignore-x86_64
 // See repr-transparent.rs
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
index 0a687078cd8..acb993d51fb 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
index 9d47339d163..58667af7e50 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
index 770b2a73037..affbe17d334 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
index 33c86050666..43472d9dece 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
index f7a8986242d..471d49b7841 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
index a4070317a62..bd8ba8b6cd7 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
index 0800a498cb7..8ad9e9004c2 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
index adc44ffd811..ecffca960da 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
index 9c236f19636..79e6ed54690 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
index a922161affa..db92a94fca8 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
index 9624acb383f..90d9ec3cedd 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
index 7b9b1aec6c8..2761392e6a9 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
@@ -1,3 +1,4 @@
+// ignore-emscripten
 // min-llvm-version 7.0
 
 // compile-flags: -C no-prepopulate-passes
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
index 6639e5d652b..1dd2c2ccb83 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
index 5e82ea023d8..09f31bdd6bb 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
index 8ca2ca86076..dc87651c2aa 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
@@ -1,3 +1,5 @@
+// ignore-emscripten
+
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
index 237d15a5c68..adee796d247 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
@@ -119,140 +119,140 @@ extern "platform-intrinsic" {
 // CHECK-LABEL: @sadd_i8x2
 #[no_mangle]
 pub unsafe fn sadd_i8x2(x: i8x2, y: i8x2) -> i8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{[0-9a-z]+}}, <2 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.sadd.sat.v2i8(<2 x i8> %{{[0-9]+}}, <2 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x4
 #[no_mangle]
 pub unsafe fn sadd_i8x4(x: i8x4, y: i8x4) -> i8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{[0-9a-z]+}}, <4 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> %{{[0-9]+}}, <4 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x8
 #[no_mangle]
 pub unsafe fn sadd_i8x8(x: i8x8, y: i8x8) -> i8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{[0-9a-z]+}}, <8 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.sadd.sat.v8i8(<8 x i8> %{{[0-9]+}}, <8 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x16
 #[no_mangle]
 pub unsafe fn sadd_i8x16(x: i8x16, y: i8x16) -> i8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{[0-9a-z]+}}, <16 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x32
 #[no_mangle]
 pub unsafe fn sadd_i8x32(x: i8x32, y: i8x32) -> i8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{[0-9a-z]+}}, <32 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.sadd.sat.v32i8(<32 x i8> %{{[0-9]+}}, <32 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i8x64
 #[no_mangle]
 pub unsafe fn sadd_i8x64(x: i8x64, y: i8x64) -> i8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{[0-9a-z]+}}, <64 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.sadd.sat.v64i8(<64 x i8> %{{[0-9]+}}, <64 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x2
 #[no_mangle]
 pub unsafe fn sadd_i16x2(x: i16x2, y: i16x2) -> i16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{[0-9a-z]+}}, <2 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.sadd.sat.v2i16(<2 x i16> %{{[0-9]+}}, <2 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x4
 #[no_mangle]
 pub unsafe fn sadd_i16x4(x: i16x4, y: i16x4) -> i16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{[0-9a-z]+}}, <4 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.sadd.sat.v4i16(<4 x i16> %{{[0-9]+}}, <4 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x8
 #[no_mangle]
 pub unsafe fn sadd_i16x8(x: i16x8, y: i16x8) -> i16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{[0-9a-z]+}}, <8 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x16
 #[no_mangle]
 pub unsafe fn sadd_i16x16(x: i16x16, y: i16x16) -> i16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{[0-9a-z]+}}, <16 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.sadd.sat.v16i16(<16 x i16> %{{[0-9]+}}, <16 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i16x32
 #[no_mangle]
 pub unsafe fn sadd_i16x32(x: i16x32, y: i16x32) -> i16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{[0-9a-z]+}}, <32 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.sadd.sat.v32i16(<32 x i16> %{{[0-9]+}}, <32 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x2
 #[no_mangle]
 pub unsafe fn sadd_i32x2(x: i32x2, y: i32x2) -> i32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{[0-9a-z]+}}, <2 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.sadd.sat.v2i32(<2 x i32> %{{[0-9]+}}, <2 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x4
 #[no_mangle]
 pub unsafe fn sadd_i32x4(x: i32x4, y: i32x4) -> i32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{[0-9a-z]+}}, <4 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.sadd.sat.v4i32(<4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x8
 #[no_mangle]
 pub unsafe fn sadd_i32x8(x: i32x8, y: i32x8) -> i32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{[0-9a-z]+}}, <8 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.sadd.sat.v8i32(<8 x i32> %{{[0-9]+}}, <8 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i32x16
 #[no_mangle]
 pub unsafe fn sadd_i32x16(x: i32x16, y: i32x16) -> i32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{[0-9a-z]+}}, <16 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.sadd.sat.v16i32(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i64x2
 #[no_mangle]
 pub unsafe fn sadd_i64x2(x: i64x2, y: i64x2) -> i64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{[0-9a-z]+}}, <2 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.sadd.sat.v2i64(<2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i64x4
 #[no_mangle]
 pub unsafe fn sadd_i64x4(x: i64x4, y: i64x4) -> i64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{[0-9a-z]+}}, <4 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.sadd.sat.v4i64(<4 x i64> %{{[0-9]+}}, <4 x i64> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i64x8
 #[no_mangle]
 pub unsafe fn sadd_i64x8(x: i64x8, y: i64x8) -> i64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{[0-9a-z]+}}, <8 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.sadd.sat.v8i64(<8 x i64> %{{[0-9]+}}, <8 x i64> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i128x2
 #[no_mangle]
 pub unsafe fn sadd_i128x2(x: i128x2, y: i128x2) -> i128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{[0-9a-z]+}}, <2 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.sadd.sat.v2i128(<2 x i128> %{{[0-9]+}}, <2 x i128> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @sadd_i128x4
 #[no_mangle]
 pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{[0-9a-z]+}}, <4 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.sadd.sat.v4i128(<4 x i128> %{{[0-9]+}}, <4 x i128> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
@@ -261,140 +261,140 @@ pub unsafe fn sadd_i128x4(x: i128x4, y: i128x4) -> i128x4 {
 // CHECK-LABEL: @uadd_u8x2
 #[no_mangle]
 pub unsafe fn uadd_u8x2(x: u8x2, y: u8x2) -> u8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{[0-9a-z]+}}, <2 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> %{{[0-9]+}}, <2 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x4
 #[no_mangle]
 pub unsafe fn uadd_u8x4(x: u8x4, y: u8x4) -> u8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{[0-9a-z]+}}, <4 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.uadd.sat.v4i8(<4 x i8> %{{[0-9]+}}, <4 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x8
 #[no_mangle]
 pub unsafe fn uadd_u8x8(x: u8x8, y: u8x8) -> u8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{[0-9a-z]+}}, <8 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.uadd.sat.v8i8(<8 x i8> %{{[0-9]+}}, <8 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x16
 #[no_mangle]
 pub unsafe fn uadd_u8x16(x: u8x16, y: u8x16) -> u8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{[0-9a-z]+}}, <16 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x32
 #[no_mangle]
 pub unsafe fn uadd_u8x32(x: u8x32, y: u8x32) -> u8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{[0-9a-z]+}}, <32 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.uadd.sat.v32i8(<32 x i8> %{{[0-9]+}}, <32 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u8x64
 #[no_mangle]
 pub unsafe fn uadd_u8x64(x: u8x64, y: u8x64) -> u8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{[0-9a-z]+}}, <64 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.uadd.sat.v64i8(<64 x i8> %{{[0-9]+}}, <64 x i8> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x2
 #[no_mangle]
 pub unsafe fn uadd_u16x2(x: u16x2, y: u16x2) -> u16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{[0-9a-z]+}}, <2 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.uadd.sat.v2i16(<2 x i16> %{{[0-9]+}}, <2 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x4
 #[no_mangle]
 pub unsafe fn uadd_u16x4(x: u16x4, y: u16x4) -> u16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{[0-9a-z]+}}, <4 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.uadd.sat.v4i16(<4 x i16> %{{[0-9]+}}, <4 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x8
 #[no_mangle]
 pub unsafe fn uadd_u16x8(x: u16x8, y: u16x8) -> u16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{[0-9a-z]+}}, <8 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x16
 #[no_mangle]
 pub unsafe fn uadd_u16x16(x: u16x16, y: u16x16) -> u16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{[0-9a-z]+}}, <16 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.uadd.sat.v16i16(<16 x i16> %{{[0-9]+}}, <16 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u16x32
 #[no_mangle]
 pub unsafe fn uadd_u16x32(x: u16x32, y: u16x32) -> u16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{[0-9a-z]+}}, <32 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.uadd.sat.v32i16(<32 x i16> %{{[0-9]+}}, <32 x i16> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x2
 #[no_mangle]
 pub unsafe fn uadd_u32x2(x: u32x2, y: u32x2) -> u32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{[0-9a-z]+}}, <2 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.uadd.sat.v2i32(<2 x i32> %{{[0-9]+}}, <2 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x4
 #[no_mangle]
 pub unsafe fn uadd_u32x4(x: u32x4, y: u32x4) -> u32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{[0-9a-z]+}}, <4 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.uadd.sat.v4i32(<4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x8
 #[no_mangle]
 pub unsafe fn uadd_u32x8(x: u32x8, y: u32x8) -> u32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{[0-9a-z]+}}, <8 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.uadd.sat.v8i32(<8 x i32> %{{[0-9]+}}, <8 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u32x16
 #[no_mangle]
 pub unsafe fn uadd_u32x16(x: u32x16, y: u32x16) -> u32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{[0-9a-z]+}}, <16 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.uadd.sat.v16i32(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u64x2
 #[no_mangle]
 pub unsafe fn uadd_u64x2(x: u64x2, y: u64x2) -> u64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{[0-9a-z]+}}, <2 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.uadd.sat.v2i64(<2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u64x4
 #[no_mangle]
 pub unsafe fn uadd_u64x4(x: u64x4, y: u64x4) -> u64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{[0-9a-z]+}}, <4 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.uadd.sat.v4i64(<4 x i64> %{{[0-9]+}}, <4 x i64> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u64x8
 #[no_mangle]
 pub unsafe fn uadd_u64x8(x: u64x8, y: u64x8) -> u64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{[0-9a-z]+}}, <8 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.uadd.sat.v8i64(<8 x i64> %{{[0-9]+}}, <8 x i64> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u128x2
 #[no_mangle]
 pub unsafe fn uadd_u128x2(x: u128x2, y: u128x2) -> u128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{[0-9a-z]+}}, <2 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.uadd.sat.v2i128(<2 x i128> %{{[0-9]+}}, <2 x i128> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
 // CHECK-LABEL: @uadd_u128x4
 #[no_mangle]
 pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{[0-9a-z]+}}, <4 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.uadd.sat.v4i128(<4 x i128> %{{[0-9]+}}, <4 x i128> %{{[0-9]+}})
     simd_saturating_add(x, y)
 }
 
@@ -405,140 +405,140 @@ pub unsafe fn uadd_u128x4(x: u128x4, y: u128x4) -> u128x4 {
 // CHECK-LABEL: @ssub_i8x2
 #[no_mangle]
 pub unsafe fn ssub_i8x2(x: i8x2, y: i8x2) -> i8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{[0-9a-z]+}}, <2 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> %{{[0-9]+}}, <2 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x4
 #[no_mangle]
 pub unsafe fn ssub_i8x4(x: i8x4, y: i8x4) -> i8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{[0-9a-z]+}}, <4 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.ssub.sat.v4i8(<4 x i8> %{{[0-9]+}}, <4 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x8
 #[no_mangle]
 pub unsafe fn ssub_i8x8(x: i8x8, y: i8x8) -> i8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{[0-9a-z]+}}, <8 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.ssub.sat.v8i8(<8 x i8> %{{[0-9]+}}, <8 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x16
 #[no_mangle]
 pub unsafe fn ssub_i8x16(x: i8x16, y: i8x16) -> i8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{[0-9a-z]+}}, <16 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.ssub.sat.v16i8(<16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x32
 #[no_mangle]
 pub unsafe fn ssub_i8x32(x: i8x32, y: i8x32) -> i8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{[0-9a-z]+}}, <32 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.ssub.sat.v32i8(<32 x i8> %{{[0-9]+}}, <32 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i8x64
 #[no_mangle]
 pub unsafe fn ssub_i8x64(x: i8x64, y: i8x64) -> i8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{[0-9a-z]+}}, <64 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.ssub.sat.v64i8(<64 x i8> %{{[0-9]+}}, <64 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x2
 #[no_mangle]
 pub unsafe fn ssub_i16x2(x: i16x2, y: i16x2) -> i16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{[0-9a-z]+}}, <2 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.ssub.sat.v2i16(<2 x i16> %{{[0-9]+}}, <2 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x4
 #[no_mangle]
 pub unsafe fn ssub_i16x4(x: i16x4, y: i16x4) -> i16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{[0-9a-z]+}}, <4 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.ssub.sat.v4i16(<4 x i16> %{{[0-9]+}}, <4 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x8
 #[no_mangle]
 pub unsafe fn ssub_i16x8(x: i16x8, y: i16x8) -> i16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{[0-9a-z]+}}, <8 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.ssub.sat.v8i16(<8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x16
 #[no_mangle]
 pub unsafe fn ssub_i16x16(x: i16x16, y: i16x16) -> i16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{[0-9a-z]+}}, <16 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.ssub.sat.v16i16(<16 x i16> %{{[0-9]+}}, <16 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i16x32
 #[no_mangle]
 pub unsafe fn ssub_i16x32(x: i16x32, y: i16x32) -> i16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{[0-9a-z]+}}, <32 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.ssub.sat.v32i16(<32 x i16> %{{[0-9]+}}, <32 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x2
 #[no_mangle]
 pub unsafe fn ssub_i32x2(x: i32x2, y: i32x2) -> i32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{[0-9a-z]+}}, <2 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.ssub.sat.v2i32(<2 x i32> %{{[0-9]+}}, <2 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x4
 #[no_mangle]
 pub unsafe fn ssub_i32x4(x: i32x4, y: i32x4) -> i32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{[0-9a-z]+}}, <4 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.ssub.sat.v4i32(<4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x8
 #[no_mangle]
 pub unsafe fn ssub_i32x8(x: i32x8, y: i32x8) -> i32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{[0-9a-z]+}}, <8 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.ssub.sat.v8i32(<8 x i32> %{{[0-9]+}}, <8 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i32x16
 #[no_mangle]
 pub unsafe fn ssub_i32x16(x: i32x16, y: i32x16) -> i32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{[0-9a-z]+}}, <16 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.ssub.sat.v16i32(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i64x2
 #[no_mangle]
 pub unsafe fn ssub_i64x2(x: i64x2, y: i64x2) -> i64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{[0-9a-z]+}}, <2 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.ssub.sat.v2i64(<2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i64x4
 #[no_mangle]
 pub unsafe fn ssub_i64x4(x: i64x4, y: i64x4) -> i64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{[0-9a-z]+}}, <4 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.ssub.sat.v4i64(<4 x i64> %{{[0-9]+}}, <4 x i64> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i64x8
 #[no_mangle]
 pub unsafe fn ssub_i64x8(x: i64x8, y: i64x8) -> i64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{[0-9a-z]+}}, <8 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.ssub.sat.v8i64(<8 x i64> %{{[0-9]+}}, <8 x i64> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i128x2
 #[no_mangle]
 pub unsafe fn ssub_i128x2(x: i128x2, y: i128x2) -> i128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{[0-9a-z]+}}, <2 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.ssub.sat.v2i128(<2 x i128> %{{[0-9]+}}, <2 x i128> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @ssub_i128x4
 #[no_mangle]
 pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{[0-9a-z]+}}, <4 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.ssub.sat.v4i128(<4 x i128> %{{[0-9]+}}, <4 x i128> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
@@ -547,139 +547,139 @@ pub unsafe fn ssub_i128x4(x: i128x4, y: i128x4) -> i128x4 {
 // CHECK-LABEL: @usub_u8x2
 #[no_mangle]
 pub unsafe fn usub_u8x2(x: u8x2, y: u8x2) -> u8x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{[0-9a-z]+}}, <2 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %{{[0-9]+}}, <2 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x4
 #[no_mangle]
 pub unsafe fn usub_u8x4(x: u8x4, y: u8x4) -> u8x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{[0-9a-z]+}}, <4 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i8> @llvm.usub.sat.v4i8(<4 x i8> %{{[0-9]+}}, <4 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x8
 #[no_mangle]
 pub unsafe fn usub_u8x8(x: u8x8, y: u8x8) -> u8x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{[0-9a-z]+}}, <8 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i8> @llvm.usub.sat.v8i8(<8 x i8> %{{[0-9]+}}, <8 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x16
 #[no_mangle]
 pub unsafe fn usub_u8x16(x: u8x16, y: u8x16) -> u8x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{[0-9a-z]+}}, <16 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i8> @llvm.usub.sat.v16i8(<16 x i8> %{{[0-9]+}}, <16 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x32
 #[no_mangle]
 pub unsafe fn usub_u8x32(x: u8x32, y: u8x32) -> u8x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{[0-9a-z]+}}, <32 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i8> @llvm.usub.sat.v32i8(<32 x i8> %{{[0-9]+}}, <32 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u8x64
 #[no_mangle]
 pub unsafe fn usub_u8x64(x: u8x64, y: u8x64) -> u8x64 {
-    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{[0-9a-z]+}}, <64 x i8> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <64 x i8> @llvm.usub.sat.v64i8(<64 x i8> %{{[0-9]+}}, <64 x i8> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x2
 #[no_mangle]
 pub unsafe fn usub_u16x2(x: u16x2, y: u16x2) -> u16x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{[0-9a-z]+}}, <2 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %{{[0-9]+}}, <2 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x4
 #[no_mangle]
 pub unsafe fn usub_u16x4(x: u16x4, y: u16x4) -> u16x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{[0-9a-z]+}}, <4 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i16> @llvm.usub.sat.v4i16(<4 x i16> %{{[0-9]+}}, <4 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x8
 #[no_mangle]
 pub unsafe fn usub_u16x8(x: u16x8, y: u16x8) -> u16x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{[0-9a-z]+}}, <8 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i16> @llvm.usub.sat.v8i16(<8 x i16> %{{[0-9]+}}, <8 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x16
 #[no_mangle]
 pub unsafe fn usub_u16x16(x: u16x16, y: u16x16) -> u16x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{[0-9a-z]+}}, <16 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i16> @llvm.usub.sat.v16i16(<16 x i16> %{{[0-9]+}}, <16 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u16x32
 #[no_mangle]
 pub unsafe fn usub_u16x32(x: u16x32, y: u16x32) -> u16x32 {
-    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{[0-9a-z]+}}, <32 x i16> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <32 x i16> @llvm.usub.sat.v32i16(<32 x i16> %{{[0-9]+}}, <32 x i16> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x2
 #[no_mangle]
 pub unsafe fn usub_u32x2(x: u32x2, y: u32x2) -> u32x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{[0-9a-z]+}}, <2 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i32> @llvm.usub.sat.v2i32(<2 x i32> %{{[0-9]+}}, <2 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x4
 #[no_mangle]
 pub unsafe fn usub_u32x4(x: u32x4, y: u32x4) -> u32x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{[0-9a-z]+}}, <4 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %{{[0-9]+}}, <4 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x8
 #[no_mangle]
 pub unsafe fn usub_u32x8(x: u32x8, y: u32x8) -> u32x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{[0-9a-z]+}}, <8 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> %{{[0-9]+}}, <8 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u32x16
 #[no_mangle]
 pub unsafe fn usub_u32x16(x: u32x16, y: u32x16) -> u32x16 {
-    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{[0-9a-z]+}}, <16 x i32> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <16 x i32> @llvm.usub.sat.v16i32(<16 x i32> %{{[0-9]+}}, <16 x i32> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u64x2
 #[no_mangle]
 pub unsafe fn usub_u64x2(x: u64x2, y: u64x2) -> u64x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{[0-9a-z]+}}, <2 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i64> @llvm.usub.sat.v2i64(<2 x i64> %{{[0-9]+}}, <2 x i64> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u64x4
 #[no_mangle]
 pub unsafe fn usub_u64x4(x: u64x4, y: u64x4) -> u64x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{[0-9a-z]+}}, <4 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i64> @llvm.usub.sat.v4i64(<4 x i64> %{{[0-9]+}}, <4 x i64> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u64x8
 #[no_mangle]
 pub unsafe fn usub_u64x8(x: u64x8, y: u64x8) -> u64x8 {
-    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{[0-9a-z]+}}, <8 x i64> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <8 x i64> @llvm.usub.sat.v8i64(<8 x i64> %{{[0-9]+}}, <8 x i64> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u128x2
 #[no_mangle]
 pub unsafe fn usub_u128x2(x: u128x2, y: u128x2) -> u128x2 {
-    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{[0-9a-z]+}}, <2 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <2 x i128> @llvm.usub.sat.v2i128(<2 x i128> %{{[0-9]+}}, <2 x i128> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
 
 // CHECK-LABEL: @usub_u128x4
 #[no_mangle]
 pub unsafe fn usub_u128x4(x: u128x4, y: u128x4) -> u128x4 {
-    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{[0-9a-z]+}}, <4 x i128> %{{[0-9a-z]+}})
+    // CHECK: %{{[0-9]+}} = call <4 x i128> @llvm.usub.sat.v4i128(<4 x i128> %{{[0-9]+}}, <4 x i128> %{{[0-9]+}})
     simd_saturating_sub(x, y)
 }
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
index 54366401486..cd8130f9231 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
@@ -29,7 +29,7 @@ extern "platform-intrinsic" {
 // CHECK-LABEL: @bitmask_int
 #[no_mangle]
 pub unsafe fn bitmask_int(x: i32x2) -> u8 {
-    // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{[0-9a-z]+}}, <i32 31, i32 31>
+    // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{[0-9]+}}, <i32 31, i32 31>
     // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1>
     // CHECK: [[C:%[0-9]+]] = bitcast <2 x i1> [[B]] to i2
     // CHECK: %{{[0-9]+}} = zext i2 [[C]] to i8
@@ -39,7 +39,7 @@ pub unsafe fn bitmask_int(x: i32x2) -> u8 {
 // CHECK-LABEL: @bitmask_uint
 #[no_mangle]
 pub unsafe fn bitmask_uint(x: u32x2) -> u8 {
-    // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{[0-9a-z]+}}, <i32 31, i32 31>
+    // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> %{{[0-9]+}}, <i32 31, i32 31>
     // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1>
     // CHECK: [[C:%[0-9]+]] = bitcast <2 x i1> [[B]] to i2
     // CHECK: %{{[0-9]+}} = zext i2 [[C]] to i8
@@ -49,7 +49,7 @@ pub unsafe fn bitmask_uint(x: u32x2) -> u8 {
 // CHECK-LABEL: @bitmask_int16
 #[no_mangle]
 pub unsafe fn bitmask_int16(x: i8x16) -> u16 {
-    // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{[0-9a-z]+}}, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
+    // CHECK: [[A:%[0-9]+]] = lshr <16 x i8> %{{[0-9]+}}, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
     // CHECK: [[B:%[0-9]+]] = trunc <16 x i8> [[A]] to <16 x i1>
     // CHECK: %{{[0-9]+}} = bitcast <16 x i1> [[B]] to i16
     // CHECK-NOT: zext
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
index 3b1f4398f90..3389104219d 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
@@ -1,3 +1,4 @@
+// ignore-emscripten
 // ignore-tidy-linelength
 
 // compile-flags: -C no-prepopulate-passes
diff --git a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
index 9fce849e523..dd0a9801bc5 100644
--- a/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
+++ b/src/test/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
@@ -1,3 +1,4 @@
+// ignore-emscripten
 // ignore-tidy-linelength
 
 // compile-flags: -C no-prepopulate-passes
diff --git a/src/test/codegen/union-abi.rs b/src/test/codegen/union-abi.rs
index 98a9ff9cbe4..7339df17b05 100644
--- a/src/test/codegen/union-abi.rs
+++ b/src/test/codegen/union-abi.rs
@@ -1,4 +1,3 @@
-// ignore-emscripten vectors passed directly
 // compile-flags: -C no-prepopulate-passes
 
 // This test that using union forward the abi of the inner type, as
diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/compile-fail/weak-lang-item.rs
index 3fa3822831b..768b936dc27 100644
--- a/src/test/compile-fail/weak-lang-item.rs
+++ b/src/test/compile-fail/weak-lang-item.rs
@@ -1,7 +1,7 @@
 // aux-build:weak-lang-items.rs
 // error-pattern: `#[panic_handler]` function required, but not found
 // error-pattern: language item required, but not found: `eh_personality`
-// ignore-emscripten compiled with panic=abort, personality not required
+// ignore-wasm32-bare compiled with panic=abort, personality not required
 
 #![no_std]
 
diff --git a/src/test/incremental/change_crate_dep_kind.rs b/src/test/incremental/change_crate_dep_kind.rs
index 2bcb06d6eb8..f5d1acb621b 100644
--- a/src/test/incremental/change_crate_dep_kind.rs
+++ b/src/test/incremental/change_crate_dep_kind.rs
@@ -1,7 +1,6 @@
 // Test that we detect changes to the `dep_kind` query. If the change is not
 // detected then -Zincremental-verify-ich will trigger an assertion.
 
-// ignore-emscripten compiled with panic=abort by default
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph -Cpanic=unwind
 // build-pass (FIXME(62277): could be check-pass?)
diff --git a/src/test/incremental/commandline-args.rs b/src/test/incremental/commandline-args.rs
index 08a0232f661..e5b84267b29 100644
--- a/src/test/incremental/commandline-args.rs
+++ b/src/test/incremental/commandline-args.rs
@@ -1,7 +1,6 @@
 // Test that changing a tracked commandline argument invalidates
 // the cache while changing an untracked one doesn't.
 
-// ignore-asmjs wasm2js does not support source maps yet
 // revisions:rpass1 rpass2 rpass3
 // compile-flags: -Z query-dep-graph
 
diff --git a/src/test/incremental/remapped_paths_cc/main.rs b/src/test/incremental/remapped_paths_cc/main.rs
index b01f02444ea..12411a92879 100644
--- a/src/test/incremental/remapped_paths_cc/main.rs
+++ b/src/test/incremental/remapped_paths_cc/main.rs
@@ -2,7 +2,6 @@
 // compile-flags: -Z query-dep-graph -g
 // aux-build:extern_crate.rs
 
-// ignore-asmjs wasm2js does not support source maps yet
 // This test case makes sure that we detect if paths emitted into debuginfo
 // are changed, even when the change happens in an external crate.
 
diff --git a/src/test/incremental/span_hash_stable/main.rs b/src/test/incremental/span_hash_stable/main.rs
index 367416430f8..f1d7de14559 100644
--- a/src/test/incremental/span_hash_stable/main.rs
+++ b/src/test/incremental/span_hash_stable/main.rs
@@ -3,7 +3,6 @@
 // the spans and this test makes sure that we handle them correctly by hashing
 // file:line:column instead of raw byte offset.
 
-// ignore-asmjs wasm2js does not support source maps yet
 // revisions:rpass1 rpass2
 // compile-flags: -g -Z query-dep-graph
 
diff --git a/src/test/incremental/spans_in_type_debuginfo.rs b/src/test/incremental/spans_in_type_debuginfo.rs
index f5cae15a4bc..8ed469db6e6 100644
--- a/src/test/incremental/spans_in_type_debuginfo.rs
+++ b/src/test/incremental/spans_in_type_debuginfo.rs
@@ -1,7 +1,6 @@
 // Test that moving a type definition within a source file does not affect
 // re-compilation.
 
-// ignore-asmjs wasm2js does not support source maps yet
 // revisions:rpass1 rpass2
 // compile-flags: -Z query-dep-graph -g
 
diff --git a/src/test/incremental/spans_significant_w_debuginfo.rs b/src/test/incremental/spans_significant_w_debuginfo.rs
index e6fdc7cb3a0..87c97ba06c4 100644
--- a/src/test/incremental/spans_significant_w_debuginfo.rs
+++ b/src/test/incremental/spans_significant_w_debuginfo.rs
@@ -3,7 +3,6 @@
 
 // revisions:rpass1 rpass2
 
-// ignore-asmjs wasm2js does not support source maps yet
 // compile-flags: -g -Z query-dep-graph
 
 #![feature(rustc_attrs)]
diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs
index 4b66c07b093..8dc6b73edf6 100644
--- a/src/test/mir-opt/box_expr.rs
+++ b/src/test/mir-opt/box_expr.rs
@@ -1,4 +1,4 @@
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(box_syntax)]
 
diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs
index b595c100039..109304d6d22 100644
--- a/src/test/mir-opt/generator-storage-dead-unwind.rs
+++ b/src/test/mir-opt/generator-storage-dead-unwind.rs
@@ -1,4 +1,4 @@
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 // Test that we generate StorageDead on unwind paths for generators.
 //
diff --git a/src/test/mir-opt/issue-41110.rs b/src/test/mir-opt/issue-41110.rs
index 8824496fdb0..e73390f52b5 100644
--- a/src/test/mir-opt/issue-41110.rs
+++ b/src/test/mir-opt/issue-41110.rs
@@ -1,4 +1,4 @@
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 // check that we don't emit multiple drop flags when they are not needed.
 
diff --git a/src/test/mir-opt/issue-62289.rs b/src/test/mir-opt/issue-62289.rs
index 93250fd48d8..a3b517e9bca 100644
--- a/src/test/mir-opt/issue-62289.rs
+++ b/src/test/mir-opt/issue-62289.rs
@@ -1,7 +1,7 @@
 // check that we don't forget to drop the Box if we early return before
 // initializing it
 // ignore-tidy-linelength
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(box_syntax)]
 
diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no-spurious-drop-after-call.rs
index 370cd593b02..782bc31186c 100644
--- a/src/test/mir-opt/no-spurious-drop-after-call.rs
+++ b/src/test/mir-opt/no-spurious-drop-after-call.rs
@@ -1,4 +1,4 @@
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 // Test that after the call to `std::mem::drop` we do not generate a
 // MIR drop of the argument. (We used to have a `DROP(_2)` in the code
diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs
index eaa1fbd69ec..da73cc96348 100644
--- a/src/test/mir-opt/packed-struct-drop-aligned.rs
+++ b/src/test/mir-opt/packed-struct-drop-aligned.rs
@@ -1,4 +1,4 @@
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 fn main() {
     let mut x = Packed(Aligned(Droppy(0)));
diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs
index 71beaa73663..3245d38b258 100644
--- a/src/test/mir-opt/remove_fake_borrows.rs
+++ b/src/test/mir-opt/remove_fake_borrows.rs
@@ -1,6 +1,6 @@
 // Test that the fake borrows for matches are removed after borrow checking.
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare
 
 fn match_guard(x: Option<&&i32>, c: bool) -> i32 {
     match x {
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index a0bdfb3ab8b..db36a1fab5f 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -1,4 +1,4 @@
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // ignore-tidy-linelength
 // compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats
 
diff --git a/src/test/run-make/wasm-custom-section/Makefile b/src/test/run-make/wasm-custom-section/Makefile
index 2f48b852566..7c64dc58bf7 100644
--- a/src/test/run-make/wasm-custom-section/Makefile
+++ b/src/test/run-make/wasm-custom-section/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
-# only-wasm32-bare
+# only-wasm32
 
 all:
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown
diff --git a/src/test/run-make/wasm-custom-sections-opt/Makefile b/src/test/run-make/wasm-custom-sections-opt/Makefile
index 76698c0aae3..fec7643d20c 100644
--- a/src/test/run-make/wasm-custom-sections-opt/Makefile
+++ b/src/test/run-make/wasm-custom-sections-opt/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
-# only-wasm32-bare
+# only-wasm32
 
 all:
 	$(RUSTC) foo.rs -O --target wasm32-unknown-unknown
diff --git a/src/test/run-make/wasm-export-all-symbols/Makefile b/src/test/run-make/wasm-export-all-symbols/Makefile
index 7e47ba4850e..15403d8d410 100644
--- a/src/test/run-make/wasm-export-all-symbols/Makefile
+++ b/src/test/run-make/wasm-export-all-symbols/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
-# only-wasm32-bare
+# only-wasm32
 
 all:
 	$(RUSTC) bar.rs --target wasm32-unknown-unknown
diff --git a/src/test/run-make/wasm-import-module/Makefile b/src/test/run-make/wasm-import-module/Makefile
index fe63e66f242..255d8f1ef0e 100644
--- a/src/test/run-make/wasm-import-module/Makefile
+++ b/src/test/run-make/wasm-import-module/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
- # only-wasm32-bare
+ # only-wasm32
 
 all:
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown
diff --git a/src/test/run-make/wasm-panic-small/Makefile b/src/test/run-make/wasm-panic-small/Makefile
index 68397e4bc6e..b9141f93d53 100644
--- a/src/test/run-make/wasm-panic-small/Makefile
+++ b/src/test/run-make/wasm-panic-small/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
-# only-wasm32-bare
+# only-wasm32
 
 all:
 	$(RUSTC) foo.rs -C lto -O --target wasm32-unknown-unknown --cfg a
diff --git a/src/test/run-make/wasm-symbols-not-exported/Makefile b/src/test/run-make/wasm-symbols-not-exported/Makefile
index 62bd0f0872e..b17e04b7717 100644
--- a/src/test/run-make/wasm-symbols-not-exported/Makefile
+++ b/src/test/run-make/wasm-symbols-not-exported/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
-# only-wasm32-bare
+# only-wasm32
 
 all:
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown
diff --git a/src/test/run-make/wasm-symbols-not-imported/Makefile b/src/test/run-make/wasm-symbols-not-imported/Makefile
index 7a923375c18..b8f64e06f31 100644
--- a/src/test/run-make/wasm-symbols-not-imported/Makefile
+++ b/src/test/run-make/wasm-symbols-not-imported/Makefile
@@ -1,6 +1,6 @@
 -include ../../run-make-fulldeps/tools.mk
 
-# only-wasm32-bare
+# only-wasm32
 
 all:
 	$(RUSTC) foo.rs --target wasm32-unknown-unknown
diff --git a/src/test/ui/abi/statics/static-mut-foreign.rs b/src/test/ui/abi/statics/static-mut-foreign.rs
index b30e8f00e40..5d6fa416b98 100644
--- a/src/test/ui/abi/statics/static-mut-foreign.rs
+++ b/src/test/ui/abi/statics/static-mut-foreign.rs
@@ -5,10 +5,6 @@
 
 // ignore-wasm32-bare no libc to test ffi with
 
-// FIXME: This will work on emscripten once libc is updated to include
-// rust-lang/libc/#1478
-// ignore-emscripten libc type mismatch
-
 #![feature(rustc_private)]
 
 extern crate libc;
diff --git a/src/test/ui/async-await/async-fn-size-moved-locals.rs b/src/test/ui/async-await/async-fn-size-moved-locals.rs
index b63d5408a71..3ffcbb58595 100644
--- a/src/test/ui/async-await/async-fn-size-moved-locals.rs
+++ b/src/test/ui/async-await/async-fn-size-moved-locals.rs
@@ -7,7 +7,7 @@
 //
 // See issue #59123 for a full explanation.
 
-// ignore-emscripten (sizes don't match)
+// ignore-wasm32-bare (sizes don't match)
 // run-pass
 
 // edition:2018
diff --git a/src/test/ui/async-await/issue-60709.rs b/src/test/ui/async-await/issue-60709.rs
index 61f6ed1b7b2..9ee419c4a56 100644
--- a/src/test/ui/async-await/issue-60709.rs
+++ b/src/test/ui/async-await/issue-60709.rs
@@ -3,7 +3,6 @@
 // compile-flags: -Copt-level=z -Cdebuginfo=2 --edition=2018
 
 // run-pass
-// ignore-asmjs wasm2js does not support source maps yet
 
 use std::future::Future;
 use std::task::Poll;
diff --git a/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
index 4e0a238c5d4..ea4a9e5afa5 100644
--- a/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
+++ b/src/test/ui/binding/fn-arg-incomplete-pattern-drop-order.rs
@@ -2,7 +2,7 @@
 // Check that partially moved from function parameters are dropped after the
 // named bindings that move from them.
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 use std::{panic, cell::RefCell};
 
diff --git a/src/test/ui/binding/match-arm-statics.rs b/src/test/ui/binding/match-arm-statics.rs
index e6d17def147..5f7e357eeb2 100644
--- a/src/test/ui/binding/match-arm-statics.rs
+++ b/src/test/ui/binding/match-arm-statics.rs
@@ -1,7 +1,6 @@
 // run-pass
 #![allow(dead_code)]
 // compile-flags: -g
-// ignore-asmjs wasm2js does not support source maps yet
 
 #[derive(PartialEq, Eq)]
 struct NewBool(bool);
diff --git a/src/test/ui/builtin-clone-unwind.rs b/src/test/ui/builtin-clone-unwind.rs
index 1fd91440a78..339bcfa1060 100644
--- a/src/test/ui/builtin-clone-unwind.rs
+++ b/src/test/ui/builtin-clone-unwind.rs
@@ -2,7 +2,7 @@
 
 #![allow(unused_variables)]
 #![allow(unused_imports)]
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 // Test that builtin implementations of `Clone` cleanup everything
 // in case of unwinding.
diff --git a/src/test/ui/catch-unwind-bang.rs b/src/test/ui/catch-unwind-bang.rs
index c2c21bca7ef..f181991713b 100644
--- a/src/test/ui/catch-unwind-bang.rs
+++ b/src/test/ui/catch-unwind-bang.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 fn worker() -> ! {
     panic!()
diff --git a/src/test/ui/consts/const-eval/issue-50814.rs b/src/test/ui/consts/const-eval/issue-50814.rs
index 274967ef60d..b85cecda16e 100644
--- a/src/test/ui/consts/const-eval/issue-50814.rs
+++ b/src/test/ui/consts/const-eval/issue-50814.rs
@@ -11,7 +11,6 @@ struct Sum<A,B>(A,B);
 
 impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A,B> {
     const MAX: u8 = A::MAX + B::MAX; //~ ERROR any use of this value will cause an error
-    //~| ERROR any use of this value will cause an error
 }
 
 fn foo<T>(_: T) -> &'static u8 {
diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr
index de3459c72dd..707dfee7cd5 100644
--- a/src/test/ui/consts/const-eval/issue-50814.stderr
+++ b/src/test/ui/consts/const-eval/issue-50814.stderr
@@ -9,21 +9,13 @@ LL |     const MAX: u8 = A::MAX + B::MAX;
    = note: `#[deny(const_err)]` on by default
 
 error[E0080]: evaluation of constant expression failed
-  --> $DIR/issue-50814.rs:18:5
+  --> $DIR/issue-50814.rs:17:5
    |
 LL |     &Sum::<U8,U8>::MAX
    |     ^-----------------
    |      |
    |      referenced constant has errors
 
-error: any use of this value will cause an error
-  --> $DIR/issue-50814.rs:13:21
-   |
-LL |     const MAX: u8 = A::MAX + B::MAX;
-   |     ----------------^^^^^^^^^^^^^^^-
-   |                     |
-   |                     attempt to add with overflow
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/issue-64908.rs b/src/test/ui/consts/const-eval/issue-64908.rs
new file mode 100644
index 00000000000..d2e09507284
--- /dev/null
+++ b/src/test/ui/consts/const-eval/issue-64908.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+// This test verifies that the `ConstProp` pass doesn't cause an ICE when evaluating polymorphic
+// promoted MIR.
+
+pub trait ArrowPrimitiveType {
+    type Native;
+}
+
+pub fn new<T: ArrowPrimitiveType>() {
+    assert_eq!(0, std::mem::size_of::<T::Native>());
+}
+
+impl ArrowPrimitiveType for () {
+    type Native = ();
+}
+
+fn main() {
+    new::<()>();
+}
diff --git a/src/test/ui/consts/const-int-saturating-arith.rs b/src/test/ui/consts/const-int-saturating-arith.rs
index d0a3eccd177..394d6c17f5a 100644
--- a/src/test/ui/consts/const-int-saturating-arith.rs
+++ b/src/test/ui/consts/const-int-saturating-arith.rs
@@ -1,4 +1,5 @@
 // run-pass
+// ignore-emscripten no i128 support
 #![feature(const_saturating_int_methods)]
 
 const INT_U32_NO: u32 = (42 as u32).saturating_add(2);
diff --git a/src/test/ui/debuginfo-lto.rs b/src/test/ui/debuginfo-lto.rs
index 43f75b0344b..e4beee9e737 100644
--- a/src/test/ui/debuginfo-lto.rs
+++ b/src/test/ui/debuginfo-lto.rs
@@ -7,7 +7,6 @@
 // aux-build:debuginfo-lto-aux.rs
 // compile-flags: -C lto -g
 // no-prefer-dynamic
-// ignore-asmjs wasm2js does not support source maps yet
 
 extern crate debuginfo_lto_aux;
 
diff --git a/src/test/ui/did_you_mean/issue-40396.rs b/src/test/ui/did_you_mean/issue-40396.rs
index 6902779f33d..18933552054 100644
--- a/src/test/ui/did_you_mean/issue-40396.rs
+++ b/src/test/ui/did_you_mean/issue-40396.rs
@@ -1,16 +1,8 @@
-fn foo() {
+fn main() {
     (0..13).collect<Vec<i32>>();
     //~^ ERROR chained comparison
-}
-
-fn bar() {
     Vec<i32>::new();
     //~^ ERROR chained comparison
-}
-
-fn qux() {
     (0..13).collect<Vec<i32>();
     //~^ ERROR chained comparison
 }
-
-fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr
index 7a08fda27e3..7fc7c2628c4 100644
--- a/src/test/ui/did_you_mean/issue-40396.stderr
+++ b/src/test/ui/did_you_mean/issue-40396.stderr
@@ -2,28 +2,31 @@ error: chained comparison operators require parentheses
   --> $DIR/issue-40396.rs:2:20
    |
 LL |     (0..13).collect<Vec<i32>>();
-   |                    ^^^^^^^^
+   |                    ^^^^^
+help: use `::<...>` instead of `<...>` to specify type arguments
    |
-   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
-   = help: or use `(...)` if you meant to specify fn arguments
+LL |     (0..13).collect::<Vec<i32>>();
+   |                    ^^
 
 error: chained comparison operators require parentheses
-  --> $DIR/issue-40396.rs:7:8
+  --> $DIR/issue-40396.rs:4:8
    |
 LL |     Vec<i32>::new();
-   |        ^^^^^^^
+   |        ^^^^^
+help: use `::<...>` instead of `<...>` to specify type arguments
    |
-   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
-   = help: or use `(...)` if you meant to specify fn arguments
+LL |     Vec::<i32>::new();
+   |        ^^
 
 error: chained comparison operators require parentheses
-  --> $DIR/issue-40396.rs:12:20
+  --> $DIR/issue-40396.rs:6:20
    |
 LL |     (0..13).collect<Vec<i32>();
-   |                    ^^^^^^^^
+   |                    ^^^^^
+help: use `::<...>` instead of `<...>` to specify type arguments
    |
-   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
-   = help: or use `(...)` if you meant to specify fn arguments
+LL |     (0..13).collect::<Vec<i32>();
+   |                    ^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index bec86d6465a..91063edf0f6 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -5,7 +5,7 @@
 
 // run-pass
 // edition:2018
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(slice_patterns)]
 #![allow(unused)]
diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs
index 7fd3f420a6d..8516bc3d964 100644
--- a/src/test/ui/drop/dynamic-drop.rs
+++ b/src/test/ui/drop/dynamic-drop.rs
@@ -2,7 +2,7 @@
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(generators, generator_trait, untagged_unions)]
 #![feature(slice_patterns)]
diff --git a/src/test/ui/extern/extern-const.fixed b/src/test/ui/extern/extern-const.fixed
index 9d96b4f63fb..0eec9fb3ee6 100644
--- a/src/test/ui/extern/extern-const.fixed
+++ b/src/test/ui/extern/extern-const.fixed
@@ -5,8 +5,7 @@
 // compile. To sidestep this by using one that *is* defined.
 
 // run-rustfix
-// ignore-wasm32-bare no external library to link to.
-// ignore-asmjs wasm2js does not support source maps yet
+// ignore-wasm32 no external library to link to.
 // compile-flags: -g
 #![feature(rustc_private)]
 extern crate libc;
diff --git a/src/test/ui/extern/extern-const.rs b/src/test/ui/extern/extern-const.rs
index 7cef5b3497b..ca5d7ddf27e 100644
--- a/src/test/ui/extern/extern-const.rs
+++ b/src/test/ui/extern/extern-const.rs
@@ -5,8 +5,7 @@
 // compile. To sidestep this by using one that *is* defined.
 
 // run-rustfix
-// ignore-wasm32-bare no external library to link to.
-// ignore-asmjs wasm2js does not support source maps yet
+// ignore-wasm32 no external library to link to.
 // compile-flags: -g
 #![feature(rustc_private)]
 extern crate libc;
diff --git a/src/test/ui/extern/extern-const.stderr b/src/test/ui/extern/extern-const.stderr
index 258202b6903..77406be2095 100644
--- a/src/test/ui/extern/extern-const.stderr
+++ b/src/test/ui/extern/extern-const.stderr
@@ -1,5 +1,5 @@
 error: extern items cannot be `const`
-  --> $DIR/extern-const.rs:16:5
+  --> $DIR/extern-const.rs:15:5
    |
 LL |     const rust_dbg_static_mut: libc::c_int;
    |     ^^^^^ help: try using a static value: `static`
diff --git a/src/test/ui/generator/issue-58888.rs b/src/test/ui/generator/issue-58888.rs
index d42d09d401e..43b37a9afc2 100644
--- a/src/test/ui/generator/issue-58888.rs
+++ b/src/test/ui/generator/issue-58888.rs
@@ -1,6 +1,5 @@
 // run-pass
 // compile-flags: -g
-// ignore-asmjs wasm2js does not support source maps yet
 
 #![feature(generators, generator_trait)]
 
diff --git a/src/test/ui/generator/panic-drops.rs b/src/test/ui/generator/panic-drops.rs
index b1a5cc67e86..5ac97585f4b 100644
--- a/src/test/ui/generator/panic-drops.rs
+++ b/src/test/ui/generator/panic-drops.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled as panic=abort by default
 
 #![feature(generators, generator_trait)]
 
diff --git a/src/test/ui/generator/panic-safe.rs b/src/test/ui/generator/panic-safe.rs
index 06c02618019..5f6778674dc 100644
--- a/src/test/ui/generator/panic-safe.rs
+++ b/src/test/ui/generator/panic-safe.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(generators, generator_trait)]
 
diff --git a/src/test/ui/generator/resume-after-return.rs b/src/test/ui/generator/resume-after-return.rs
index ab18be58155..71a68ff684a 100644
--- a/src/test/ui/generator/resume-after-return.rs
+++ b/src/test/ui/generator/resume-after-return.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(generators, generator_trait)]
 
diff --git a/src/test/ui/generator/size-moved-locals.rs b/src/test/ui/generator/size-moved-locals.rs
index 2864fbb2f3c..01db971434b 100644
--- a/src/test/ui/generator/size-moved-locals.rs
+++ b/src/test/ui/generator/size-moved-locals.rs
@@ -11,7 +11,6 @@
 
 // edition:2018
 // ignore-wasm32 issue #62807
-// ignore-asmjs issue #62807
 
 #![feature(generators, generator_trait)]
 
diff --git a/src/test/ui/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs
index bac6c8d872b..0154f049950 100644
--- a/src/test/ui/intrinsics/intrinsics-integer.rs
+++ b/src/test/ui/intrinsics/intrinsics-integer.rs
@@ -1,4 +1,5 @@
 // run-pass
+// ignore-emscripten no i128 support
 
 #![feature(intrinsics)]
 
diff --git a/src/test/ui/issues/issue-14875.rs b/src/test/ui/issues/issue-14875.rs
index 29e974ad83d..a2fd7962458 100644
--- a/src/test/ui/issues/issue-14875.rs
+++ b/src/test/ui/issues/issue-14875.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare always compiled as panic=abort right now
 
 // Check that values are not leaked when a dtor panics (#14875)
 
diff --git a/src/test/ui/issues/issue-23477.rs b/src/test/ui/issues/issue-23477.rs
index 988ebe03ccf..1ce05ba390d 100644
--- a/src/test/ui/issues/issue-23477.rs
+++ b/src/test/ui/issues/issue-23477.rs
@@ -1,5 +1,4 @@
 // build-pass
-// ignore-asmjs wasm2js does not support source maps yet
 // compile-flags: -g
 
 pub struct Dst {
diff --git a/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs b/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs
index f08bcdfe6d1..773792c7a3f 100644
--- a/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs
+++ b/src/test/ui/issues/issue-24687-embed-debuginfo/main.rs
@@ -1,7 +1,6 @@
 // run-pass
 // aux-build:issue-24687-lib.rs
 // compile-flags:-g
-// ignore-asmjs wasm2js does not support source maps yet
 
 extern crate issue_24687_lib as d;
 
diff --git a/src/test/ui/issues/issue-24945-repeat-dash-opts.rs b/src/test/ui/issues/issue-24945-repeat-dash-opts.rs
index 0f92fc2f7f3..cf3834952c6 100644
--- a/src/test/ui/issues/issue-24945-repeat-dash-opts.rs
+++ b/src/test/ui/issues/issue-24945-repeat-dash-opts.rs
@@ -3,7 +3,6 @@
 // as options to the compiler.
 
 // compile-flags:-g -g -O -O
-// ignore-asmjs wasm2js does not support source maps yet
 
 fn main() {
     assert_eq!(1, 1);
diff --git a/src/test/ui/issues/issue-26484.rs b/src/test/ui/issues/issue-26484.rs
index 2a8750d3e43..3b40b3dd8f0 100644
--- a/src/test/ui/issues/issue-26484.rs
+++ b/src/test/ui/issues/issue-26484.rs
@@ -1,6 +1,5 @@
 // run-pass
 // compile-flags:-g
-// ignore-asmjs wasm2js does not support source maps yet
 
 fn helper<F: FnOnce(usize) -> bool>(_f: F) {
     print!("");
diff --git a/src/test/ui/issues/issue-29948.rs b/src/test/ui/issues/issue-29948.rs
index 5237a2f67bd..8ede8143ea6 100644
--- a/src/test/ui/issues/issue-29948.rs
+++ b/src/test/ui/issues/issue-29948.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 use std::panic;
 
diff --git a/src/test/ui/issues/issue-33096.rs b/src/test/ui/issues/issue-33096.rs
index 2501e1430b3..f0b472e2fe8 100644
--- a/src/test/ui/issues/issue-33096.rs
+++ b/src/test/ui/issues/issue-33096.rs
@@ -1,6 +1,5 @@
 // run-pass
 // compile-flags: -g
-// ignore-asmjs wasm2js does not support source maps yet
 
 use std::ops::Deref;
 
diff --git a/src/test/ui/issues/issue-33992.rs b/src/test/ui/issues/issue-33992.rs
index a6b137ba645..94fccff9fc6 100644
--- a/src/test/ui/issues/issue-33992.rs
+++ b/src/test/ui/issues/issue-33992.rs
@@ -1,7 +1,7 @@
 // run-pass
 // ignore-windows
 // ignore-macos
-// ignore-emscripten common linkage not implemented right now
+// ignore-wasm32-bare common linkage not implemented right now
 
 #![feature(linkage)]
 
diff --git a/src/test/ui/issues/issue-34569.rs b/src/test/ui/issues/issue-34569.rs
index 88dcdd41138..1f68560509e 100644
--- a/src/test/ui/issues/issue-34569.rs
+++ b/src/test/ui/issues/issue-34569.rs
@@ -1,6 +1,5 @@
 // run-pass
 // compile-flags:-g
-// ignore-asmjs wasm2js does not support source maps yet
 
 // In this test we just want to make sure that the code below does not lead to
 // a debuginfo verification assertion during compilation. This was caused by the
diff --git a/src/test/ui/issues/issue-36856.rs b/src/test/ui/issues/issue-36856.rs
index 5657ba69f94..f2dfaf3dd36 100644
--- a/src/test/ui/issues/issue-36856.rs
+++ b/src/test/ui/issues/issue-36856.rs
@@ -2,7 +2,6 @@
 // Regression test for #36856.
 
 // compile-flags:-g
-// ignore-asmjs wasm2js does not support source maps yet
 
 fn g() -> bool {
     false
diff --git a/src/test/ui/issues/issue-42210.rs b/src/test/ui/issues/issue-42210.rs
index 01a5d563639..318e3099f98 100644
--- a/src/test/ui/issues/issue-42210.rs
+++ b/src/test/ui/issues/issue-42210.rs
@@ -2,7 +2,6 @@
 // Regression test for #42210.
 
 // compile-flags: -g
-// ignore-asmjs wasm2js does not support source maps yet
 
 trait Foo {
     fn foo() { }
diff --git a/src/test/ui/issues/issue-43853.rs b/src/test/ui/issues/issue-43853.rs
index 2a932db05af..47c3ab59aa2 100644
--- a/src/test/ui/issues/issue-43853.rs
+++ b/src/test/ui/issues/issue-43853.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 use std::panic;
 
diff --git a/src/test/ui/issues/issue-45731.rs b/src/test/ui/issues/issue-45731.rs
index 5c5ac59873a..d20c07276a8 100644
--- a/src/test/ui/issues/issue-45731.rs
+++ b/src/test/ui/issues/issue-45731.rs
@@ -1,7 +1,6 @@
 // run-pass
 #![allow(unused_variables)]
 // compile-flags:--test -g
-// ignore-asmjs wasm2js does not support source maps yet
 
 #[cfg(target_os = "macos")]
 #[test]
diff --git a/src/test/ui/issues/issue-46519.rs b/src/test/ui/issues/issue-46519.rs
index 40c3117f01c..461ea2498b0 100644
--- a/src/test/ui/issues/issue-46519.rs
+++ b/src/test/ui/issues/issue-46519.rs
@@ -1,8 +1,6 @@
 // run-pass
 // compile-flags:--test -O
 
-// ignore-emscripten compiled with panic=abort by default
-
 #[test]
 #[should_panic(expected = "creating inhabited type")]
 fn test() {
diff --git a/src/test/ui/issues/issue-48508.rs b/src/test/ui/issues/issue-48508.rs
index b7aa6422876..385192b882b 100644
--- a/src/test/ui/issues/issue-48508.rs
+++ b/src/test/ui/issues/issue-48508.rs
@@ -8,7 +8,6 @@
 
 // compile-flags:-g
 // ignore-pretty issue #37195
-// ignore-asmjs wasm2js does not support source maps yet
 
 #![feature(non_ascii_idents)]
 
diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs
index 767e06c4e90..79cc107d4fe 100644
--- a/src/test/ui/issues/issue-49579.rs
+++ b/src/test/ui/issues/issue-49579.rs
@@ -1,4 +1,5 @@
 // build-pass (FIXME(62277): could be check-pass?)
+// ignore-emscripten no i128 support
 
 fn fibs(n: u32) -> impl Iterator<Item=u128> {
     (0 .. n)
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs
index 67feb3ff6ae..24c61425b8e 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs
@@ -1,5 +1,3 @@
-#![feature(inner_deref)]
-
 fn main() {
     let _result = &Some(42).as_deref();
 //~^ ERROR no method named `as_deref` found for type `std::option::Option<{integer}>`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
index 345f91437b8..0eb7bf02475 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `as_deref` found for type `std::option::Option<{integer}>` in the current scope
-  --> $DIR/option-as_deref.rs:4:29
+  --> $DIR/option-as_deref.rs:2:29
    |
 LL |     let _result = &Some(42).as_deref();
    |                             ^^^^^^^^ help: there is a method with a similar name: `as_ref`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs
index 56aead8d0e0..67ad73f5847 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs
@@ -1,5 +1,3 @@
-#![feature(inner_deref)]
-
 fn main() {
     let _result = &mut Some(42).as_deref_mut();
 //~^ ERROR no method named `as_deref_mut` found for type `std::option::Option<{integer}>`
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
index 29fd15fb396..845ddb52319 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `as_deref_mut` found for type `std::option::Option<{integer}>` in the current scope
-  --> $DIR/option-as_deref_mut.rs:4:33
+  --> $DIR/option-as_deref_mut.rs:2:33
    |
 LL |     let _result = &mut Some(42).as_deref_mut();
    |                                 ^^^^^^^^^^^^ method not found in `std::option::Option<{integer}>`
diff --git a/src/test/ui/issues/issue-52262.rs b/src/test/ui/issues/issue-52262.rs
new file mode 100644
index 00000000000..2195b895557
--- /dev/null
+++ b/src/test/ui/issues/issue-52262.rs
@@ -0,0 +1,25 @@
+// compile-flags:-Ztreat-err-as-bug=5
+#[derive(Debug)]
+enum MyError {
+    NotFound { key: Vec<u8> },
+    Err41,
+}
+
+impl std::error::Error for MyError {}
+
+impl std::fmt::Display for MyError {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        match self {
+            MyError::NotFound { key } => write!(
+                f,
+                "unknown error with code {}.",
+                String::from_utf8(*key).unwrap()
+                //~^ ERROR cannot move out of `*key` which is behind a shared reference
+            ),
+            MyError::Err41 => write!(f, "Sit by a lake"),
+        }
+    }
+}
+fn main() {
+    println!("Hello, world!");
+}
diff --git a/src/test/ui/issues/issue-52262.stderr b/src/test/ui/issues/issue-52262.stderr
new file mode 100644
index 00000000000..7312976c801
--- /dev/null
+++ b/src/test/ui/issues/issue-52262.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of `*key` which is behind a shared reference
+  --> $DIR/issue-52262.rs:16:35
+   |
+LL |                 String::from_utf8(*key).unwrap()
+   |                                   ^^^^ move occurs because `*key` has type `std::vec::Vec<u8>`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/issues/issue-58463.rs b/src/test/ui/issues/issue-58463.rs
index af93f76221d..8ab845366b7 100644
--- a/src/test/ui/issues/issue-58463.rs
+++ b/src/test/ui/issues/issue-58463.rs
@@ -1,7 +1,5 @@
 // run-pass
 // compile-flags:-C debuginfo=2
-// ignore-asmjs wasm2js does not support source maps yet
-
 fn foo() -> impl Copy {
     foo
 }
diff --git a/src/test/ui/iterators/iter-count-overflow-debug.rs b/src/test/ui/iterators/iter-count-overflow-debug.rs
index fdd285dcad2..d6612035750 100644
--- a/src/test/ui/iterators/iter-count-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-count-overflow-debug.rs
@@ -1,6 +1,6 @@
 // run-pass
 // only-32bit too impatient for 2⁶⁴ items
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes -C opt-level=3
 
 use std::panic;
diff --git a/src/test/ui/iterators/iter-position-overflow-debug.rs b/src/test/ui/iterators/iter-position-overflow-debug.rs
index b578999af8e..f1eded31702 100644
--- a/src/test/ui/iterators/iter-position-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-position-overflow-debug.rs
@@ -1,6 +1,6 @@
 // run-pass
 // only-32bit too impatient for 2⁶⁴ items
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes -C opt-level=3
 
 use std::panic;
diff --git a/src/test/ui/iterators/iter-step-overflow-debug.rs b/src/test/ui/iterators/iter-step-overflow-debug.rs
index 3872a03b682..5d67c7cbb42 100644
--- a/src/test/ui/iterators/iter-step-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-step-overflow-debug.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes
 
 use std::panic;
diff --git a/src/test/ui/iterators/iter-sum-overflow-debug.rs b/src/test/ui/iterators/iter-sum-overflow-debug.rs
index 4a9e8cdb72e..ee4ab4d24c6 100644
--- a/src/test/ui/iterators/iter-sum-overflow-debug.rs
+++ b/src/test/ui/iterators/iter-sum-overflow-debug.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C debug_assertions=yes
 
 use std::panic;
diff --git a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
index 6bd1425e324..429f8e0bc96 100644
--- a/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
+++ b/src/test/ui/iterators/iter-sum-overflow-overflow-checks.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: -C overflow-checks
 
 use std::panic;
diff --git a/src/test/ui/macros/macro-comma-behavior-rpass.rs b/src/test/ui/macros/macro-comma-behavior-rpass.rs
index 1c791bb1ca3..9f1a31d1ae2 100644
--- a/src/test/ui/macros/macro-comma-behavior-rpass.rs
+++ b/src/test/ui/macros/macro-comma-behavior-rpass.rs
@@ -13,8 +13,6 @@
 // compile-flags: --test -C debug_assertions=yes
 // revisions: std core
 
-// ignore-emscripten compiled with panic=abort by default
-
 #![cfg_attr(core, no_std)]
 
 #[cfg(std)] use std::fmt;
diff --git a/src/test/ui/mir/mir_calls_to_shims.rs b/src/test/ui/mir/mir_calls_to_shims.rs
index de8d958af45..6f13d5612ce 100644
--- a/src/test/ui/mir/mir_calls_to_shims.rs
+++ b/src/test/ui/mir/mir_calls_to_shims.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(fn_traits)]
 #![feature(never_type)]
diff --git a/src/test/ui/mir/mir_drop_order.rs b/src/test/ui/mir/mir_drop_order.rs
index 2bc5cf1c976..2949437b1e4 100644
--- a/src/test/ui/mir/mir_drop_order.rs
+++ b/src/test/ui/mir/mir_drop_order.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 use std::cell::RefCell;
 use std::panic;
diff --git a/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs
index ced3c61ec16..d210abdf499 100644
--- a/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs
+++ b/src/test/ui/numbers-arithmetic/float-int-invalid-const-cast.rs
@@ -1,4 +1,5 @@
 // run-pass
+// ignore-emscripten no i128 support
 
 #![deny(const_err)]
 
diff --git a/src/test/ui/numbers-arithmetic/i128.rs b/src/test/ui/numbers-arithmetic/i128.rs
index ef558c0aa0c..ea0ef95e4f1 100644
--- a/src/test/ui/numbers-arithmetic/i128.rs
+++ b/src/test/ui/numbers-arithmetic/i128.rs
@@ -1,6 +1,9 @@
 // run-pass
 #![allow(overflowing_literals)]
 
+// ignore-emscripten i128 doesn't work
+
+
 #![feature(test)]
 
 extern crate test;
diff --git a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
index c1959866e5c..e9927304f23 100644
--- a/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
+++ b/src/test/ui/numbers-arithmetic/next-power-of-two-overflow-debug.rs
@@ -1,6 +1,6 @@
 // run-pass
 // compile-flags: -C debug_assertions=yes
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // ignore-emscripten dies with an LLVM error
 
 use std::panic;
diff --git a/src/test/ui/numbers-arithmetic/u128-as-f32.rs b/src/test/ui/numbers-arithmetic/u128-as-f32.rs
index 2671a267f4a..bef7deb6276 100644
--- a/src/test/ui/numbers-arithmetic/u128-as-f32.rs
+++ b/src/test/ui/numbers-arithmetic/u128-as-f32.rs
@@ -1,4 +1,5 @@
 // run-pass
+// ignore-emscripten u128 not supported
 
 #![feature(test)]
 #![deny(overflowing_literals)]
diff --git a/src/test/ui/numbers-arithmetic/u128.rs b/src/test/ui/numbers-arithmetic/u128.rs
index 0b2305c6e8b..93940716323 100644
--- a/src/test/ui/numbers-arithmetic/u128.rs
+++ b/src/test/ui/numbers-arithmetic/u128.rs
@@ -1,4 +1,6 @@
 // run-pass
+// ignore-emscripten u128 not supported
+
 
 #![feature(test)]
 
diff --git a/src/test/ui/panic-runtime/transitive-link-a-bunch.rs b/src/test/ui/panic-runtime/transitive-link-a-bunch.rs
index 6dcb852a366..5d72771c2dc 100644
--- a/src/test/ui/panic-runtime/transitive-link-a-bunch.rs
+++ b/src/test/ui/panic-runtime/transitive-link-a-bunch.rs
@@ -4,7 +4,7 @@
 // aux-build:wants-panic-runtime-abort.rs
 // aux-build:panic-runtime-lang-items.rs
 // error-pattern: is not compiled with this crate's panic strategy `unwind`
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![no_std]
 #![no_main]
diff --git a/src/test/ui/panic-runtime/want-unwind-got-abort.rs b/src/test/ui/panic-runtime/want-unwind-got-abort.rs
index e7811d40b5b..4c25c09d643 100644
--- a/src/test/ui/panic-runtime/want-unwind-got-abort.rs
+++ b/src/test/ui/panic-runtime/want-unwind-got-abort.rs
@@ -1,7 +1,7 @@
 // error-pattern:is incompatible with this crate's strategy of `unwind`
 // aux-build:panic-runtime-abort.rs
 // aux-build:panic-runtime-lang-items.rs
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![no_std]
 #![no_main]
diff --git a/src/test/ui/panic-runtime/want-unwind-got-abort2.rs b/src/test/ui/panic-runtime/want-unwind-got-abort2.rs
index 44671796c01..478af451e7f 100644
--- a/src/test/ui/panic-runtime/want-unwind-got-abort2.rs
+++ b/src/test/ui/panic-runtime/want-unwind-got-abort2.rs
@@ -2,7 +2,7 @@
 // aux-build:panic-runtime-abort.rs
 // aux-build:wants-panic-runtime-abort.rs
 // aux-build:panic-runtime-lang-items.rs
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![no_std]
 #![no_main]
diff --git a/src/test/ui/panic-uninitialized-zeroed.rs b/src/test/ui/panic-uninitialized-zeroed.rs
index 72b844d8b48..b0d66295618 100644
--- a/src/test/ui/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/panic-uninitialized-zeroed.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding
 // This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
 // in a runtime panic.
 
diff --git a/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs
new file mode 100644
index 00000000000..97a405b6999
--- /dev/null
+++ b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.rs
@@ -0,0 +1,26 @@
+// Regression test; used to ICE with 'visit_mac disabled by default' due to a
+// `MutVisitor` in `fn make_all_value_bindings_mutable` (`parse/parser/pat.rs`).
+
+macro_rules! mac1 {
+    ($eval:expr) => {
+        let mut $eval = ();
+        //~^ ERROR `mut` must be followed by a named binding
+    };
+}
+
+macro_rules! mac2 {
+    ($eval:pat) => {
+        let mut $eval = ();
+        //~^ ERROR `mut` must be followed by a named binding
+        //~| ERROR expected identifier, found `does_not_exist!()`
+    };
+}
+
+fn foo() {
+    mac1! { does_not_exist!() }
+    //~^ ERROR cannot find macro `does_not_exist` in this scope
+    mac2! { does_not_exist!() }
+    //~^ ERROR cannot find macro `does_not_exist` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr
new file mode 100644
index 00000000000..dd193d6a86e
--- /dev/null
+++ b/src/test/ui/parser/issue-65122-mac-invoc-in-mut-patterns.stderr
@@ -0,0 +1,45 @@
+error: `mut` must be followed by a named binding
+  --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:6:13
+   |
+LL |         let mut $eval = ();
+   |             ^^^^^^^^^ help: remove the `mut` prefix: `does_not_exist!()`
+...
+LL |     mac1! { does_not_exist!() }
+   |     --------------------------- in this macro invocation
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: expected identifier, found `does_not_exist!()`
+  --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:17
+   |
+LL |         let mut $eval = ();
+   |                 ^^^^^ expected identifier
+...
+LL |     mac2! { does_not_exist!() }
+   |     --------------------------- in this macro invocation
+
+error: `mut` must be followed by a named binding
+  --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:13:13
+   |
+LL |         let mut $eval = ();
+   |             ^^^ help: remove the `mut` prefix: `does_not_exist!()`
+...
+LL |     mac2! { does_not_exist!() }
+   |     --------------------------- in this macro invocation
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: cannot find macro `does_not_exist` in this scope
+  --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13
+   |
+LL |     mac1! { does_not_exist!() }
+   |             ^^^^^^^^^^^^^^
+
+error: cannot find macro `does_not_exist` in this scope
+  --> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13
+   |
+LL |     mac2! { does_not_exist!() }
+   |             ^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs
index 3dcc0c8f3d4..9c7a25d589a 100644
--- a/src/test/ui/parser/require-parens-for-chained-comparison.rs
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs
@@ -3,15 +3,24 @@ struct X;
 
 fn main() {
     false == false == false;
-    //~^ ERROR: chained comparison operators require parentheses
+    //~^ ERROR chained comparison operators require parentheses
 
     false == 0 < 2;
-    //~^ ERROR: chained comparison operators require parentheses
-    //~| ERROR: mismatched types
-    //~| ERROR: mismatched types
+    //~^ ERROR chained comparison operators require parentheses
+    //~| ERROR mismatched types
+    //~| ERROR mismatched types
 
     f<X>();
     //~^ ERROR chained comparison operators require parentheses
-    //~| HELP: use `::<...>` instead of `<...>`
-    //~| HELP: or use `(...)`
+    //~| HELP use `::<...>` instead of `<...>` to specify type arguments
+
+    f<Result<Option<X>, Option<Option<X>>>(1, 2);
+    //~^ ERROR chained comparison operators require parentheses
+    //~| HELP use `::<...>` instead of `<...>` to specify type arguments
+
+    use std::convert::identity;
+    let _ = identity<u8>;
+    //~^ ERROR chained comparison operators require parentheses
+    //~| HELP use `::<...>` instead of `<...>` to specify type arguments
+    //~| HELP or use `(...)` if you meant to specify fn arguments
 }
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
index e927f4c3248..5aa37a40cbd 100644
--- a/src/test/ui/parser/require-parens-for-chained-comparison.stderr
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
@@ -2,21 +2,41 @@ error: chained comparison operators require parentheses
   --> $DIR/require-parens-for-chained-comparison.rs:5:11
    |
 LL |     false == false == false;
-   |           ^^^^^^^^^^^^^^^^^
+   |           ^^^^^^^^^^^
 
 error: chained comparison operators require parentheses
   --> $DIR/require-parens-for-chained-comparison.rs:8:11
    |
 LL |     false == 0 < 2;
-   |           ^^^^^^^^
+   |           ^^^^^^
 
 error: chained comparison operators require parentheses
   --> $DIR/require-parens-for-chained-comparison.rs:13:6
    |
 LL |     f<X>();
-   |      ^^^^
+   |      ^^^
+help: use `::<...>` instead of `<...>` to specify type arguments
    |
-   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
+LL |     f::<X>();
+   |      ^^
+
+error: chained comparison operators require parentheses
+  --> $DIR/require-parens-for-chained-comparison.rs:17:6
+   |
+LL |     f<Result<Option<X>, Option<Option<X>>>(1, 2);
+   |      ^^^^^^^^
+help: use `::<...>` instead of `<...>` to specify type arguments
+   |
+LL |     f::<Result<Option<X>, Option<Option<X>>>(1, 2);
+   |      ^^
+
+error: chained comparison operators require parentheses
+  --> $DIR/require-parens-for-chained-comparison.rs:22:21
+   |
+LL |     let _ = identity<u8>;
+   |                     ^^^^
+   |
+   = help: use `::<...>` instead of `<...>` to specify type arguments
    = help: or use `(...)` if you meant to specify fn arguments
 
 error[E0308]: mismatched types
@@ -37,6 +57,6 @@ LL |     false == 0 < 2;
    = note: expected type `bool`
               found type `{integer}`
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/proc-macro/expand-with-a-macro.rs b/src/test/ui/proc-macro/expand-with-a-macro.rs
index 690a76ef3e0..418178d0f0e 100644
--- a/src/test/ui/proc-macro/expand-with-a-macro.rs
+++ b/src/test/ui/proc-macro/expand-with-a-macro.rs
@@ -1,7 +1,7 @@
 // run-pass
 // aux-build:expand-with-a-macro.rs
 
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![deny(warnings)]
 
diff --git a/src/test/ui/reachable-unnameable-items.rs b/src/test/ui/reachable-unnameable-items.rs
index 26c51efea1e..f1e53a0d8b4 100644
--- a/src/test/ui/reachable-unnameable-items.rs
+++ b/src/test/ui/reachable-unnameable-items.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // aux-build:reachable-unnameable-items.rs
 
 extern crate reachable_unnameable_items;
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
index c8e8b9dcfc6..39825c4f9a9 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-in-test.rs
@@ -1,8 +1,6 @@
 // compile-flags: --test
 // run-pass
 
-// ignore-emscripten compiled with panic=abort by default
-
 #![feature(test)]
 
 extern crate test;
diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs
new file mode 100644
index 00000000000..1a187d04251
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/auxiliary/types.rs
@@ -0,0 +1,31 @@
+#![feature(non_exhaustive)]
+
+#[non_exhaustive]
+#[repr(C)]
+pub enum NonExhaustiveEnum {
+    Unit,
+    Tuple(u32),
+    Struct { field: u32 }
+}
+
+#[non_exhaustive]
+#[repr(C)]
+pub struct NormalStruct {
+    pub first_field: u16,
+    pub second_field: u16,
+}
+
+#[non_exhaustive]
+#[repr(C)]
+pub struct UnitStruct;
+
+#[non_exhaustive]
+#[repr(C)]
+pub struct TupleStruct (pub u16, pub u16);
+
+#[repr(C)]
+pub enum NonExhaustiveVariants {
+    #[non_exhaustive] Unit,
+    #[non_exhaustive] Tuple(u32),
+    #[non_exhaustive] Struct { field: u32 }
+}
diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs
new file mode 100644
index 00000000000..900b9333f76
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.rs
@@ -0,0 +1,24 @@
+// aux-build:types.rs
+#![deny(improper_ctypes)]
+
+extern crate types;
+
+// This test checks that non-exhaustive types with `#[repr(C)]` from an extern crate are considered
+// improper.
+
+use types::{NonExhaustiveEnum, NormalStruct, UnitStruct, TupleStruct, NonExhaustiveVariants};
+
+extern {
+    pub fn non_exhaustive_enum(_: NonExhaustiveEnum);
+    //~^ ERROR `extern` block uses type `types::NonExhaustiveEnum`, which is not FFI-safe
+    pub fn non_exhaustive_normal_struct(_: NormalStruct);
+    //~^ ERROR `extern` block uses type `types::NormalStruct`, which is not FFI-safe
+    pub fn non_exhaustive_unit_struct(_: UnitStruct);
+    //~^ ERROR `extern` block uses type `types::UnitStruct`, which is not FFI-safe
+    pub fn non_exhaustive_tuple_struct(_: TupleStruct);
+    //~^ ERROR `extern` block uses type `types::TupleStruct`, which is not FFI-safe
+    pub fn non_exhaustive_variant(_: NonExhaustiveVariants);
+    //~^ ERROR `extern` block uses type `types::NonExhaustiveVariants`, which is not FFI-safe
+}
+
+fn main() { }
diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr
new file mode 100644
index 00000000000..7fbf1157e56
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr
@@ -0,0 +1,47 @@
+error: `extern` block uses type `types::NonExhaustiveEnum`, which is not FFI-safe
+  --> $DIR/extern_crate_improper.rs:12:35
+   |
+LL |     pub fn non_exhaustive_enum(_: NonExhaustiveEnum);
+   |                                   ^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+note: lint level defined here
+  --> $DIR/extern_crate_improper.rs:2:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
+   = note: this enum is non-exhaustive
+
+error: `extern` block uses type `types::NormalStruct`, which is not FFI-safe
+  --> $DIR/extern_crate_improper.rs:14:44
+   |
+LL |     pub fn non_exhaustive_normal_struct(_: NormalStruct);
+   |                                            ^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: this struct is non-exhaustive
+
+error: `extern` block uses type `types::UnitStruct`, which is not FFI-safe
+  --> $DIR/extern_crate_improper.rs:16:42
+   |
+LL |     pub fn non_exhaustive_unit_struct(_: UnitStruct);
+   |                                          ^^^^^^^^^^ not FFI-safe
+   |
+   = note: this struct is non-exhaustive
+
+error: `extern` block uses type `types::TupleStruct`, which is not FFI-safe
+  --> $DIR/extern_crate_improper.rs:18:43
+   |
+LL |     pub fn non_exhaustive_tuple_struct(_: TupleStruct);
+   |                                           ^^^^^^^^^^^ not FFI-safe
+   |
+   = note: this struct is non-exhaustive
+
+error: `extern` block uses type `types::NonExhaustiveVariants`, which is not FFI-safe
+  --> $DIR/extern_crate_improper.rs:20:38
+   |
+LL |     pub fn non_exhaustive_variant(_: NonExhaustiveVariants);
+   |                                      ^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: this enum has non-exhaustive variants
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs
new file mode 100644
index 00000000000..3f38e3cd8e5
--- /dev/null
+++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/same_crate_proper.rs
@@ -0,0 +1,46 @@
+// check-pass
+#![feature(non_exhaustive)]
+#![deny(improper_ctypes)]
+
+// This test checks that non-exhaustive types with `#[repr(C)]` are considered proper within
+// the defining crate.
+
+#[non_exhaustive]
+#[repr(C)]
+pub enum NonExhaustiveEnum {
+    Unit,
+    Tuple(u32),
+    Struct { field: u32 }
+}
+
+#[non_exhaustive]
+#[repr(C)]
+pub struct NormalStruct {
+    pub first_field: u16,
+    pub second_field: u16,
+}
+
+#[non_exhaustive]
+#[repr(C)]
+pub struct UnitStruct;
+
+#[non_exhaustive]
+#[repr(C)]
+pub struct TupleStruct (pub u16, pub u16);
+
+#[repr(C)]
+pub enum NonExhaustiveVariants {
+    #[non_exhaustive] Unit,
+    #[non_exhaustive] Tuple(u32),
+    #[non_exhaustive] Struct { field: u32 }
+}
+
+extern {
+    // Unit structs aren't tested here because they will trigger `improper_ctypes` anyway.
+    pub fn non_exhaustive_enum(_: NonExhaustiveEnum);
+    pub fn non_exhaustive_normal_struct(_: NormalStruct);
+    pub fn non_exhaustive_tuple_struct(_: TupleStruct);
+    pub fn non_exhaustive_variant(_: NonExhaustiveVariants);
+}
+
+fn main() { }
diff --git a/src/test/ui/rfcs/rfc1857-drop-order.rs b/src/test/ui/rfcs/rfc1857-drop-order.rs
index b10b6ec11b5..7923aa7c0e2 100644
--- a/src/test/ui/rfcs/rfc1857-drop-order.rs
+++ b/src/test/ui/rfcs/rfc1857-drop-order.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 
 #![allow(dead_code, unreachable_code)]
 
diff --git a/src/test/ui/sepcomp/sepcomp-lib-lto.rs b/src/test/ui/sepcomp/sepcomp-lib-lto.rs
index 51a572899f8..164ae79c254 100644
--- a/src/test/ui/sepcomp/sepcomp-lib-lto.rs
+++ b/src/test/ui/sepcomp/sepcomp-lib-lto.rs
@@ -4,7 +4,6 @@
 
 // aux-build:sepcomp_lib.rs
 // compile-flags: -C lto -g
-// ignore-asmjs wasm2js does not support source maps yet
 // no-prefer-dynamic
 
 extern crate sepcomp_lib;
diff --git a/src/test/ui/test-attrs/test-allow-fail-attr.rs b/src/test/ui/test-attrs/test-allow-fail-attr.rs
index 55b743ab7c7..1a478460efc 100644
--- a/src/test/ui/test-attrs/test-allow-fail-attr.rs
+++ b/src/test/ui/test-attrs/test-allow-fail-attr.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: --test
 #![feature(allow_fail)]
 
diff --git a/src/test/ui/test-attrs/test-should-fail-good-message.rs b/src/test/ui/test-attrs/test-should-fail-good-message.rs
index 2284953fbbe..9fa759f9eb4 100644
--- a/src/test/ui/test-attrs/test-should-fail-good-message.rs
+++ b/src/test/ui/test-attrs/test-should-fail-good-message.rs
@@ -1,5 +1,5 @@
 // run-pass
-// ignore-emscripten compiled with panic=abort by default
+// ignore-wasm32-bare compiled with panic=abort by default
 // compile-flags: --test
 #[test]
 #[should_panic(expected = "foo")]
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs
index 5d1e00d2d35..f86499e2e3f 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs
+++ b/src/test/ui/unboxed-closures/unboxed-closures-unique-type-id.rs
@@ -10,7 +10,6 @@
 // This is a regression test for issue #17021.
 //
 // compile-flags: -g
-// ignore-asmjs wasm2js does not support source maps yet
 
 use std::ptr;
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 03094885065..df56448dd22 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -141,10 +141,7 @@ impl EarlyProps {
                 if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
                     props.ignore = Ignore::Ignore;
                 }
-                // FIXME: Re-enable run-fail once panics are handled correctly
-                if config.target.contains("emscripten") && config.mode == common::RunFail {
-                    props.ignore = Ignore::Ignore;
-                }
+
             }
 
             if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb) &&
diff --git a/triagebot.toml b/triagebot.toml
index f3509897bdf..d87c5b64c21 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -3,7 +3,8 @@ allow-unauthenticated = [
     "C-*", "A-*", "E-*", "NLL-*", "O-*", "S-*", "T-*", "WG-*", "F-*",
     "requires-nightly",
     # I-* without I-nominated
-    "I-compilemem", "I-compiletime", "I-crash", "I-hang", "I-ICE", "I-slow",
+    "I-*", "!I-nominated",
+    "AsyncAwait-OnDeck",
 ]
 
 [assign]