about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock20
-rw-r--r--config.toml.example4
-rw-r--r--src/bootstrap/bin/rustc.rs21
-rw-r--r--src/bootstrap/builder.rs87
-rw-r--r--src/bootstrap/cc_detect.rs2
-rw-r--r--src/bootstrap/check.rs1
-rw-r--r--src/bootstrap/compile.rs38
-rw-r--r--src/bootstrap/mk/Makefile.in9
-rw-r--r--src/bootstrap/sanity.rs4
-rw-r--r--src/ci/azure-pipelines/auto.yml8
-rw-r--r--src/ci/azure-pipelines/steps/run.yml2
-rw-r--r--src/ci/docker/scripts/musl-toolchain.sh26
-rw-r--r--src/ci/docker/scripts/musl.sh26
-rw-r--r--src/doc/unstable-book/src/language-features/or-patterns.md36
-rw-r--r--src/liballoc/boxed.rs135
-rw-r--r--src/liballoc/collections/mod.rs31
-rw-r--r--src/liballoc/collections/vec_deque.rs16
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/macros.rs2
-rw-r--r--src/liballoc/raw_vec.rs32
-rw-r--r--src/liballoc/rc.rs186
-rw-r--r--src/liballoc/string.rs14
-rw-r--r--src/liballoc/sync.rs186
-rw-r--r--src/liballoc/tests/string.rs14
-rw-r--r--src/liballoc/tests/vec.rs18
-rw-r--r--src/liballoc/tests/vec_deque.rs14
-rw-r--r--src/liballoc/vec.rs14
-rw-r--r--src/libcore/clone.rs2
-rw-r--r--src/libcore/cmp.rs8
-rw-r--r--src/libcore/default.rs2
-rw-r--r--src/libcore/fmt/builders.rs13
-rw-r--r--src/libcore/fmt/mod.rs2
-rw-r--r--src/libcore/hash/mod.rs2
-rw-r--r--src/libcore/intrinsics.rs22
-rw-r--r--src/libcore/iter/adapters/chain.rs23
-rw-r--r--src/libcore/iter/adapters/flatten.rs8
-rw-r--r--src/libcore/iter/adapters/mod.rs30
-rw-r--r--src/libcore/iter/traits/double_ended.rs2
-rw-r--r--src/libcore/macros.rs39
-rw-r--r--src/libcore/marker.rs2
-rw-r--r--src/libcore/num/mod.rs48
-rw-r--r--src/libcore/prelude/v1.rs1
-rw-r--r--src/libcore/ptr/unique.rs8
-rw-r--r--src/libcore/tests/iter.rs28
-rw-r--r--src/libproc_macro/bridge/client.rs8
-rw-r--r--src/librustc/cfg/construct.rs5
-rw-r--r--src/librustc/hir/def_id.rs26
-rw-r--r--src/librustc/hir/intravisit.rs1
-rw-r--r--src/librustc/hir/lowering.rs18
-rw-r--r--src/librustc/hir/lowering/expr.rs15
-rw-r--r--src/librustc/hir/lowering/item.rs5
-rw-r--r--src/librustc/hir/map/def_collector.rs2
-rw-r--r--src/librustc/hir/map/definitions.rs19
-rw-r--r--src/librustc/hir/mod.rs16
-rw-r--r--src/librustc/hir/print.rs5
-rw-r--r--src/librustc/ich/hcx.rs4
-rw-r--r--src/librustc/ich/impls_syntax.rs5
-rw-r--r--src/librustc/lint/internal.rs35
-rw-r--r--src/librustc/lint/mod.rs19
-rw-r--r--src/librustc/middle/cstore.rs3
-rw-r--r--src/librustc/middle/mem_categorization.rs6
-rw-r--r--src/librustc/mir/interpret/allocation.rs2
-rw-r--r--src/librustc/mir/mod.rs5
-rw-r--r--src/librustc/mir/tcx.rs2
-rw-r--r--src/librustc/mir/visit.rs2
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/traits/error_reporting.rs8
-rw-r--r--src/librustc/traits/project.rs2
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs80
-rw-r--r--src/librustc_codegen_llvm/asm.rs7
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs8
-rw-r--r--src/librustc_codegen_ssa/back/write.rs5
-rw-r--r--src/librustc_codegen_ssa/mir/analyze.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/statement.rs7
-rw-r--r--src/librustc_codegen_ssa/traits/asm.rs2
-rw-r--r--src/librustc_codegen_utils/Cargo.toml2
-rw-r--r--src/librustc_codegen_utils/symbol_names/v0.rs12
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_errors/lib.rs5
-rw-r--r--src/librustc_lexer/src/lib.rs2
-rw-r--r--src/librustc_lexer/src/unescape.rs36
-rw-r--r--src/librustc_lexer/src/unescape/tests.rs11
-rw-r--r--src/librustc_lint/builtin.rs162
-rw-r--r--src/librustc_lint/unused.rs5
-rw-r--r--src/librustc_llvm/build.rs11
-rw-r--r--src/librustc_metadata/creader.rs89
-rw-r--r--src/librustc_metadata/cstore.rs19
-rw-r--r--src/librustc_metadata/cstore_impl.rs11
-rw-r--r--src/librustc_metadata/decoder.rs200
-rw-r--r--src/librustc_metadata/encoder.rs39
-rw-r--r--src/librustc_metadata/locator.rs4
-rw-r--r--src/librustc_metadata/schema.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs44
-rw-r--r--src/librustc_mir/build/expr/as_constant.rs2
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs4
-rw-r--r--src/librustc_mir/build/expr/into.rs2
-rw-r--r--src/librustc_mir/build/matches/mod.rs5
-rw-r--r--src/librustc_mir/build/matches/simplify.rs8
-rw-r--r--src/librustc_mir/build/matches/test.rs28
-rw-r--r--src/librustc_mir/build/misc.rs5
-rw-r--r--src/librustc_mir/const_eval.rs5
-rw-r--r--src/librustc_mir/hair/cx/expr.rs2
-rw-r--r--src/librustc_mir/hair/cx/mod.rs4
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs26
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs69
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs16
-rw-r--r--src/librustc_mir/interpret/machine.rs4
-rw-r--r--src/librustc_mir/interpret/memory.rs2
-rw-r--r--src/librustc_mir/interpret/operand.rs17
-rw-r--r--src/librustc_mir/interpret/operator.rs123
-rw-r--r--src/librustc_mir/interpret/place.rs2
-rw-r--r--src/librustc_mir/interpret/step.rs3
-rw-r--r--src/librustc_mir/interpret/terminator.rs9
-rw-r--r--src/librustc_mir/shim.rs3
-rw-r--r--src/librustc_mir/transform/const_prop.rs38
-rw-r--r--src/librustc_mir/transform/elaborate_drops.rs1
-rw-r--r--src/librustc_mir/transform/generator.rs1
-rw-r--r--src/librustc_mir/transform/inline.rs2
-rw-r--r--src/librustc_mir/transform/instcombine.rs3
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs10
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs6
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs2
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs1
-rw-r--r--src/librustc_mir/util/pretty.rs3
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs202
-rw-r--r--src/librustc_resolve/diagnostics.rs63
-rw-r--r--src/librustc_resolve/error_codes.rs16
-rw-r--r--src/librustc_resolve/late.rs61
-rw-r--r--src/librustc_resolve/late/diagnostics.rs17
-rw-r--r--src/librustc_resolve/lib.rs178
-rw-r--r--src/librustc_resolve/macros.rs161
-rw-r--r--src/librustc_resolve/resolve_imports.rs40
-rw-r--r--src/librustc_save_analysis/lib.rs2
-rw-r--r--src/librustc_target/spec/aarch64_wrs_vxworks.rs5
-rw-r--r--src/librustc_target/spec/arm_wrs_vxworks_sf.rs25
-rw-r--r--src/librustc_target/spec/armv7_wrs_vxworks.rs31
-rw-r--r--src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs (renamed from src/librustc_target/spec/arm_wrs_vxworks.rs)8
-rw-r--r--src/librustc_target/spec/i586_wrs_vxworks.rs8
-rw-r--r--src/librustc_target/spec/i686_wrs_vxworks.rs2
-rw-r--r--src/librustc_target/spec/i686_wrs_vxworks_gnu.rs23
-rw-r--r--src/librustc_target/spec/mod.rs6
-rw-r--r--src/librustc_target/spec/powerpc64_wrs_vxworks.rs3
-rw-r--r--src/librustc_target/spec/powerpc64_wrs_vxworks_gnusf.rs26
-rw-r--r--src/librustc_target/spec/powerpc_wrs_vxworks.rs1
-rw-r--r--src/librustc_target/spec/powerpc_wrs_vxworks_gnusf.rs26
-rw-r--r--src/librustc_target/spec/powerpc_wrs_vxworks_gnuspesf.rs27
-rw-r--r--src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs1
-rw-r--r--src/librustc_target/spec/sparc64_unknown_openbsd.rs22
-rw-r--r--src/librustc_target/spec/vxworks_base.rs27
-rw-r--r--src/librustc_target/spec/x86_64_wrs_vxworks.rs1
-rw-r--r--src/librustc_typeck/check/_match.rs8
-rw-r--r--src/librustc_typeck/check/demand.rs10
-rw-r--r--src/librustc_typeck/check/expr.rs269
-rw-r--r--src/librustc_typeck/check/intrinsic.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs38
-rw-r--r--src/librustc_typeck/error_codes.rs17
-rw-r--r--src/librustdoc/clean/mod.rs5
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs3
-rw-r--r--src/libstd/Cargo.toml2
-rw-r--r--src/libstd/collections/hash/map.rs17
-rw-r--r--src/libstd/collections/hash/set.rs4
-rw-r--r--src/libstd/collections/mod.rs2
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/macros.rs20
-rw-r--r--src/libstd/prelude/v1.rs1
-rw-r--r--src/libsyntax/ast.rs15
-rw-r--r--src/libsyntax/attr/mod.rs4
-rw-r--r--src/libsyntax/diagnostics/plugin.rs2
-rw-r--r--src/libsyntax/ext/base.rs44
-rw-r--r--src/libsyntax/ext/build.rs2
-rw-r--r--src/libsyntax/ext/expand.rs77
-rw-r--r--src/libsyntax/ext/placeholders.rs7
-rw-r--r--src/libsyntax/ext/proc_macro_server.rs6
-rw-r--r--src/libsyntax/feature_gate.rs45
-rw-r--r--src/libsyntax/mut_visit.rs7
-rw-r--r--src/libsyntax/parse/lexer/mod.rs85
-rw-r--r--src/libsyntax/parse/lexer/tests.rs36
-rw-r--r--src/libsyntax/parse/lexer/unicode_chars.rs7
-rw-r--r--src/libsyntax/parse/mod.rs9
-rw-r--r--src/libsyntax/parse/parser.rs3
-rw-r--r--src/libsyntax/parse/parser/expr.rs3
-rw-r--r--src/libsyntax/parse/parser/module.rs2
-rw-r--r--src/libsyntax/parse/parser/pat.rs41
-rw-r--r--src/libsyntax/parse/tests.rs4
-rw-r--r--src/libsyntax/print/pprust.rs42
-rw-r--r--src/libsyntax/source_map.rs37
-rw-r--r--src/libsyntax/source_map/tests.rs11
-rw-r--r--src/libsyntax/tests.rs4
-rw-r--r--src/libsyntax/tokenstream/tests.rs4
-rw-r--r--src/libsyntax/visit.rs7
-rw-r--r--src/libsyntax_ext/asm.rs3
-rw-r--r--src/libsyntax_ext/deriving/clone.rs4
-rw-r--r--src/libsyntax_ext/deriving/cmp/eq.rs2
-rw-r--r--src/libsyntax_ext/deriving/cmp/ord.rs59
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_eq.rs2
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_ord.rs15
-rw-r--r--src/libsyntax_ext/deriving/debug.rs8
-rw-r--r--src/libsyntax_ext/deriving/decodable.rs6
-rw-r--r--src/libsyntax_ext/deriving/encodable.rs21
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs15
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs4
-rw-r--r--src/libsyntax_ext/deriving/hash.rs2
-rw-r--r--src/libsyntax_ext/deriving/mod.rs27
-rw-r--r--src/libsyntax_ext/env.rs4
-rw-r--r--src/libsyntax_ext/global_allocator.rs10
-rw-r--r--src/libsyntax_ext/global_asm.rs7
-rw-r--r--src/libsyntax_ext/lib.rs3
-rw-r--r--src/libsyntax_ext/plugin_macro_defs.rs6
-rw-r--r--src/libsyntax_ext/proc_macro_harness.rs9
-rw-r--r--src/libsyntax_ext/source_util.rs37
-rw-r--r--src/libsyntax_ext/standard_library_imports.rs12
-rw-r--r--src/libsyntax_ext/test.rs4
-rw-r--r--src/libsyntax_ext/test_harness.rs13
-rw-r--r--src/libsyntax_pos/edition.rs5
-rw-r--r--src/libsyntax_pos/hygiene.rs172
-rw-r--r--src/libsyntax_pos/lib.rs164
-rw-r--r--src/libsyntax_pos/symbol.rs37
-rw-r--r--src/libsyntax_pos/tests.rs20
-rw-r--r--src/libunwind/Cargo.toml4
-rw-r--r--src/libunwind/build.rs22
-rw-r--r--src/test/pretty/stmt_expr_attributes.rs2
-rw-r--r--src/test/run-make-fulldeps/reproducible-build-2/Makefile12
-rw-r--r--src/test/ui/.gitattributes1
-rw-r--r--src/test/ui/abi/abi-sysv64-arg-passing.rs (renamed from src/test/ui/abi-sysv64-arg-passing.rs)0
-rw-r--r--src/test/ui/abi/abi-sysv64-register-usage.rs (renamed from src/test/ui/abi-sysv64-register-usage.rs)0
-rw-r--r--src/test/ui/abi/abort-on-c-abi.rs (renamed from src/test/ui/abort-on-c-abi.rs)0
-rw-r--r--src/test/ui/abi/anon-extern-mod.rs (renamed from src/test/ui/anon-extern-mod.rs)0
-rw-r--r--src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs (renamed from src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs)0
-rw-r--r--src/test/ui/abi/auxiliary/foreign_lib.rs (renamed from src/test/ui/auxiliary/foreign_lib.rs)0
-rw-r--r--src/test/ui/abi/c-stack-as-value.rs (renamed from src/test/ui/c-stack-as-value.rs)0
-rw-r--r--src/test/ui/abi/cabi-int-widening.rs (renamed from src/test/ui/cabi-int-widening.rs)0
-rw-r--r--src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs (renamed from src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs)0
-rw-r--r--src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs (renamed from src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs)0
-rw-r--r--src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs (renamed from src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs)0
-rw-r--r--src/test/ui/abi/duplicated-external-mods.rs (renamed from src/test/ui/duplicated-external-mods.rs)0
-rw-r--r--src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs (renamed from src/test/ui/extern/auxiliary/extern-crosscrate-source.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-call-deep.rs (renamed from src/test/ui/extern/extern-call-deep.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-call-deep2.rs (renamed from src/test/ui/extern/extern-call-deep2.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-call-direct.rs (renamed from src/test/ui/extern/extern-call-direct.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-call-indirect.rs (renamed from src/test/ui/extern/extern-call-indirect.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-call-scrub.rs (renamed from src/test/ui/extern/extern-call-scrub.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-crosscrate.rs (renamed from src/test/ui/extern/extern-crosscrate.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-TwoU16s.rs (renamed from src/test/ui/extern/extern-pass-TwoU16s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-TwoU32s.rs (renamed from src/test/ui/extern/extern-pass-TwoU32s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-TwoU64s.rs (renamed from src/test/ui/extern/extern-pass-TwoU64s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-TwoU8s.rs (renamed from src/test/ui/extern/extern-pass-TwoU8s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-char.rs (renamed from src/test/ui/extern/extern-pass-char.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-double.rs (renamed from src/test/ui/extern/extern-pass-double.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-empty.rs (renamed from src/test/ui/extern/extern-pass-empty.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-u32.rs (renamed from src/test/ui/extern/extern-pass-u32.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-pass-u64.rs (renamed from src/test/ui/extern/extern-pass-u64.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-return-TwoU16s.rs (renamed from src/test/ui/extern/extern-return-TwoU16s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-return-TwoU32s.rs (renamed from src/test/ui/extern/extern-return-TwoU32s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-return-TwoU64s.rs (renamed from src/test/ui/extern/extern-return-TwoU64s.rs)0
-rw-r--r--src/test/ui/abi/extern/extern-return-TwoU8s.rs (renamed from src/test/ui/extern/extern-return-TwoU8s.rs)0
-rw-r--r--src/test/ui/abi/foreign/auxiliary/foreign_lib.rs (renamed from src/test/ui/foreign/auxiliary/foreign_lib.rs)0
-rw-r--r--src/test/ui/abi/foreign/foreign-call-no-runtime.rs (renamed from src/test/ui/foreign/foreign-call-no-runtime.rs)0
-rw-r--r--src/test/ui/abi/foreign/foreign-dupe.rs (renamed from src/test/ui/foreign/foreign-dupe.rs)0
-rw-r--r--src/test/ui/abi/foreign/foreign-fn-with-byval.rs (renamed from src/test/ui/foreign/foreign-fn-with-byval.rs)0
-rw-r--r--src/test/ui/abi/foreign/foreign-no-abi.rs (renamed from src/test/ui/foreign/foreign-no-abi.rs)0
-rw-r--r--src/test/ui/abi/invoke-external-foreign.rs (renamed from src/test/ui/invoke-external-foreign.rs)0
-rw-r--r--src/test/ui/abi/lib-defaults.rs (renamed from src/test/ui/lib-defaults.rs)0
-rw-r--r--src/test/ui/abi/macros/macros-in-extern.rs (renamed from src/test/ui/macros/macros-in-extern.rs)0
-rw-r--r--src/test/ui/abi/macros/macros-in-extern.stderr (renamed from src/test/ui/macros/macros-in-extern.stderr)0
-rw-r--r--src/test/ui/abi/mir/mir_codegen_calls_variadic.rs (renamed from src/test/ui/mir/mir_codegen_calls_variadic.rs)0
-rw-r--r--src/test/ui/abi/numbers-arithmetic/i128-ffi.rs (renamed from src/test/ui/numbers-arithmetic/i128-ffi.rs)0
-rw-r--r--src/test/ui/abi/proc-macro/auxiliary/test-macros.rs112
-rw-r--r--src/test/ui/abi/proc-macro/macros-in-extern.rs (renamed from src/test/ui/proc-macro/macros-in-extern.rs)0
-rw-r--r--src/test/ui/abi/proc-macro/macros-in-extern.stderr (renamed from src/test/ui/proc-macro/macros-in-extern.stderr)0
-rw-r--r--src/test/ui/abi/segfault-no-out-of-stack.rs (renamed from src/test/ui/segfault-no-out-of-stack.rs)0
-rw-r--r--src/test/ui/abi/stack-probes-lto.rs (renamed from src/test/ui/stack-probes-lto.rs)0
-rw-r--r--src/test/ui/abi/stack-probes.rs (renamed from src/test/ui/stack-probes.rs)0
-rw-r--r--src/test/ui/abi/statics/static-mut-foreign.rs (renamed from src/test/ui/statics/static-mut-foreign.rs)0
-rw-r--r--src/test/ui/abi/struct-enums/struct-return.rs (renamed from src/test/ui/structs-enums/struct-return.rs)0
-rw-r--r--src/test/ui/abi/union/union-c-interop.rs (renamed from src/test/ui/union/union-c-interop.rs)0
-rw-r--r--src/test/ui/abi/variadic-ffi.rs (renamed from src/test/ui/variadic-ffi.rs)0
-rw-r--r--src/test/ui/associated-type/associated-type-projection-from-supertrait.rs8
-rw-r--r--src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr8
-rw-r--r--src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs6
-rw-r--r--src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr8
-rw-r--r--src/test/ui/associated-types/associated-types-ref-from-struct.rs4
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.nll.stderr2
-rw-r--r--src/test/ui/async-await/suggest-switching-edition-on-await.rs45
-rw-r--r--src/test/ui/async-await/suggest-switching-edition-on-await.stderr43
-rw-r--r--src/test/ui/consts/const-eval/ub-nonnull.rs2
-rw-r--r--src/test/ui/consts/const-eval/ub-ref.rs2
-rw-r--r--src/test/ui/consts/const-eval/ub-upvars.rs2
-rw-r--r--src/test/ui/derives/derive-hygiene.rs121
-rw-r--r--src/test/ui/dropck/dropck_trait_cycle_checked.stderr10
-rw-r--r--src/test/ui/duplicate/duplicate-type-parameter.stderr14
-rw-r--r--src/test/ui/error-codes/E0194.rs2
-rw-r--r--src/test/ui/error-codes/E0194.stderr8
-rw-r--r--src/test/ui/error-codes/E0403.stderr2
-rw-r--r--src/test/ui/feature-gate/feature-gate-or_patterns.rs9
-rw-r--r--src/test/ui/feature-gate/feature-gate-or_patterns.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-generators.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-generators.stderr20
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr12
-rw-r--r--src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs2
-rw-r--r--src/test/ui/hrtb/hrtb-conflate-regions.rs1
-rw-r--r--src/test/ui/hrtb/hrtb-conflate-regions.stderr2
-rw-r--r--src/test/ui/hygiene/auxiliary/codegen-attrs.rs10
-rw-r--r--src/test/ui/hygiene/cross-crate-codegen-attrs.rs12
-rw-r--r--src/test/ui/hygiene/no_implicit_prelude.stderr16
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.rs2
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.stderr6
-rw-r--r--src/test/ui/impl-trait/bound-normalization-pass.rs4
-rw-r--r--src/test/ui/imports/local-modularized-tricky-fail-1.stderr38
-rw-r--r--src/test/ui/imports/shadow_builtin_macros.stderr28
-rw-r--r--src/test/ui/include-macros/data.bin2
-rw-r--r--src/test/ui/include-macros/normalization.rs12
-rw-r--r--src/test/ui/issues/issue-12028.rs2
-rw-r--r--src/test/ui/issues/issue-12028.stderr2
-rw-r--r--src/test/ui/issues/issue-16739.rs4
-rw-r--r--src/test/ui/issues/issue-49074.stderr12
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.rs31
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.stderr158
-rw-r--r--src/test/ui/macros/same-sequence-span.stderr10
-rw-r--r--src/test/ui/macros/trace-macro.stderr2
-rw-r--r--src/test/ui/methods/method-projection.rs9
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.rs5
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.stderr6
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.rs3
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.stderr6
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.rs2
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.stderr4
-rw-r--r--src/test/ui/proc-macro/auxiliary/gen-macro-rules.rs12
-rw-r--r--src/test/ui/proc-macro/gen-macro-rules.rs13
-rw-r--r--src/test/ui/proc-macro/generate-mod.stderr10
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.stderr5
-rw-r--r--src/test/ui/proc-macro/lints_in_proc_macros.stderr5
-rw-r--r--src/test/ui/proc-macro/macro-namespace-reserved-2.stderr24
-rw-r--r--src/test/ui/proc-macro/multispan.stderr14
-rw-r--r--src/test/ui/proc-macro/subspan.stderr16
-rw-r--r--src/test/ui/proc-macro/three-equals.stderr2
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr20
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr4
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-hrtb.rs7
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr2
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr10
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr2
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container-wc.rs4
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container.nll.stderr8
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container.rs4
-rw-r--r--src/test/ui/regions/regions-outlives-projection-container.stderr40
-rw-r--r--src/test/ui/reserved/reserved-attr-on-macro.stderr12
-rw-r--r--src/test/ui/rfc1598-generic-associated-types/shadowing.rs16
-rw-r--r--src/test/ui/rfc1598-generic-associated-types/shadowing.stderr21
-rw-r--r--src/test/ui/rust-unstable-column-gated.rs4
-rw-r--r--src/test/ui/rust-unstable-column-gated.stderr11
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr4
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.nll.stderr12
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.nll.stderr12
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.nll.stderr10
-rw-r--r--src/test/ui/self/elision/ref-self-async.nll.stderr14
-rw-r--r--src/test/ui/self/elision/ref-struct-async.nll.stderr10
-rw-r--r--src/test/ui/shadowed/shadowed-type-parameter.rs6
-rw-r--r--src/test/ui/shadowed/shadowed-type-parameter.stderr30
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-no-default.rs8
-rw-r--r--src/test/ui/specialization/defaultimpl/specialization-no-default.stderr10
-rw-r--r--src/test/ui/specialization/specialization-no-default.rs8
-rw-r--r--src/test/ui/specialization/specialization-no-default.stderr10
-rw-r--r--src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs3
-rw-r--r--src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr11
-rw-r--r--src/test/ui/symbol-names/impl1.rs6
-rw-r--r--src/test/ui/symbol-names/impl1.v0.stderr6
-rw-r--r--src/test/ui/symbol-names/issue-60925.legacy.stderr4
-rw-r--r--src/test/ui/symbol-names/issue-60925.rs4
-rw-r--r--src/test/ui/traits/traits-conditional-model-fn.rs6
-rw-r--r--src/tools/compiletest/src/runtest.rs6
m---------src/tools/miri16
m---------src/tools/rls0
378 files changed, 3754 insertions, 2753 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ab6731e4d43..c784246ba39 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -106,7 +106,7 @@ dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -1138,19 +1138,12 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.4.0"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-alloc 1.0.0",
  "rustc-std-workspace-core 1.0.0",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
  "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2736,7 +2729,7 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.15"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2894,7 +2887,7 @@ dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "punycode 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
- "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "rustc_metadata 0.0.0",
  "rustc_target 0.0.0",
@@ -3534,7 +3527,7 @@ dependencies = [
  "core 0.0.0",
  "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "hashbrown 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
@@ -4450,7 +4443,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454"
 "checksum h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "a539b63339fbbb00e081e84b6e11bd1d9634a82d91da2984a18ac74a8823f392"
 "checksum handlebars 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "df044dd42cdb7e32f28557b661406fc0f2494be75199779998810dbc35030e0d"
-"checksum hashbrown 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9529213c67695ca2d146e6f263b7b72df8fa973368beadf767e8ed80c03f2f36"
 "checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
 "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
 "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
@@ -4600,7 +4592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-ap-serialize 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61673783f2089e01033ffa82d1988f55175402071b31253a358292e1624d4602"
 "checksum rustc-ap-syntax 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28f3dd1346d5b0269c07a4a78855e309a298ab569c9c1302d4d4f57f8eee4e84"
 "checksum rustc-ap-syntax_pos 546.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "45e67b526dbda3a0c7dab91c8947d43685e7697f52686a4949da3c179cd7c979"
-"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af"
+"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
 "checksum rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2e07e19601f21c59aad953c2632172ba70cb27e685771514ea66e4062b3363"
 "checksum rustc-rayon-core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79d38ca7cbc22fa59f09d8534ea4b27f67b0facf0cbe274433aceea227a02543"
diff --git a/config.toml.example b/config.toml.example
index cb9f388a8e4..a3ec4f2044c 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -141,10 +141,10 @@
 # library and facade crates.
 #compiler-docs = false
 
-# Indicate whether submodules are managed and updated automatically.
+# Indicate whether git submodules are managed and updated automatically.
 #submodules = true
 
-# Update submodules only when the checked out commit in the submodules differs
+# Update git submodules only when the checked out commit in the submodules differs
 # from what is committed in the main rustc repo.
 #fast-submodules = true
 
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 9c01de8aa82..ce92ce02696 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -37,7 +37,7 @@ fn main() {
             let mut new = None;
             if let Some(current_as_str) = args[i].to_str() {
                 if (&*args[i - 1] == "-C" && current_as_str.starts_with("metadata")) ||
-                   current_as_str.starts_with("-Cmetadata") {
+                    current_as_str.starts_with("-Cmetadata") {
                     new = Some(format!("{}-{}", current_as_str, s));
                 }
             }
@@ -89,7 +89,7 @@ fn main() {
     if let Some(crate_name) = crate_name {
         if let Some(target) = env::var_os("RUSTC_TIME") {
             if target == "all" ||
-               target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name)
+                target.into_string().unwrap().split(",").any(|c| c.trim() == crate_name)
             {
                 cmd.arg("-Ztime");
             }
@@ -102,8 +102,13 @@ fn main() {
     // FIXME: the fact that core here is excluded is due to core_arch from our stdarch submodule
     // being broken on the beta compiler with bootstrap passed, so this is a temporary workaround
     // (we've just snapped, so there are no cfg(bootstrap) related annotations in core).
-    if stage == "0" && crate_name != Some("core") {
-        cmd.arg("--cfg").arg("bootstrap");
+    if stage == "0" {
+        if crate_name != Some("core") {
+            cmd.arg("--cfg").arg("bootstrap");
+        } else {
+            // NOTE(eddyb) see FIXME above, except now we need annotations again in core.
+            cmd.arg("--cfg").arg("boostrap_stdarch_ignore_this");
+        }
     }
 
     // Print backtrace in case of ICE
@@ -276,10 +281,6 @@ fn main() {
                 cmd.arg("-C").arg("target-feature=-crt-static");
             }
         }
-
-        if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
-            cmd.arg("--remap-path-prefix").arg(&map);
-        }
     } else {
         // Override linker if necessary.
         if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
@@ -296,6 +297,10 @@ fn main() {
         }
     }
 
+    if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
+        cmd.arg("--remap-path-prefix").arg(&map);
+    }
+
     // Force all crates compiled by this compiler to (a) be unstable and (b)
     // allow the `rustc_private` feature to link to other unstable crates
     // also in the sysroot. We also do this for host crates, since those
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 8dad5f2ef46..f0054c36c0c 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -754,76 +754,20 @@ impl<'a> Builder<'a> {
         let mut cargo = Command::new(&self.initial_cargo);
         let out_dir = self.stage_out(compiler, mode);
 
-        // command specific path, we call clear_if_dirty with this
-        let mut my_out = match cmd {
-            "build" => self.cargo_out(compiler, mode, target),
-
-            // This is the intended out directory for crate documentation.
-            "doc" | "rustdoc" =>  self.crate_doc_out(target),
-
-            _ => self.stage_out(compiler, mode),
-        };
-
-        // This is for the original compiler, but if we're forced to use stage 1, then
-        // std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since
-        // we copy the libs forward.
-        let cmp = self.compiler_for(compiler.stage, compiler.host, target);
-
-        let libstd_stamp = match cmd {
-            "check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target),
-            _ => compile::libstd_stamp(self, cmp, target),
-        };
-
-        let libtest_stamp = match cmd {
-            "check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target),
-            _ => compile::libtest_stamp(self, cmp, target),
-        };
-
-        let librustc_stamp = match cmd {
-            "check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target),
-            _ => compile::librustc_stamp(self, cmp, target),
-        };
+        // Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
+        // so we need to explicitly clear out if they've been updated.
+        for backend in self.codegen_backends(compiler) {
+            self.clear_if_dirty(&out_dir, &backend);
+        }
 
         if cmd == "doc" || cmd == "rustdoc" {
-            if mode == Mode::Rustc || mode == Mode::ToolRustc || mode == Mode::Codegen {
+            let my_out = match mode {
                 // This is the intended out directory for compiler documentation.
-                my_out = self.compiler_doc_out(target);
-            }
+                Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target),
+                _ => self.crate_doc_out(target),
+            };
             let rustdoc = self.rustdoc(compiler);
             self.clear_if_dirty(&my_out, &rustdoc);
-        } else if cmd != "test" {
-            match mode {
-                Mode::Std => {
-                    self.clear_if_dirty(&my_out, &self.rustc(compiler));
-                    for backend in self.codegen_backends(compiler) {
-                        self.clear_if_dirty(&my_out, &backend);
-                    }
-                },
-                Mode::Test => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                },
-                Mode::Rustc => {
-                    self.clear_if_dirty(&my_out, &self.rustc(compiler));
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                    self.clear_if_dirty(&my_out, &libtest_stamp);
-                },
-                Mode::Codegen => {
-                    self.clear_if_dirty(&my_out, &librustc_stamp);
-                },
-                Mode::ToolBootstrap => { },
-                Mode::ToolStd => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                },
-                Mode::ToolTest => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                    self.clear_if_dirty(&my_out, &libtest_stamp);
-                },
-                Mode::ToolRustc => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                    self.clear_if_dirty(&my_out, &libtest_stamp);
-                    self.clear_if_dirty(&my_out, &librustc_stamp);
-                },
-            }
         }
 
         cargo
@@ -861,6 +805,19 @@ impl<'a> Builder<'a> {
             },
         }
 
+        // This tells Cargo (and in turn, rustc) to output more complete
+        // dependency information.  Most importantly for rustbuild, this
+        // includes sysroot artifacts, like libstd, which means that we don't
+        // need to track those in rustbuild (an error prone process!). This
+        // feature is currently unstable as there may be some bugs and such, but
+        // it represents a big improvement in rustbuild's reliability on
+        // rebuilds, so we're using it here.
+        //
+        // For some additional context, see #63470 (the PR originally adding
+        // this), as well as #63012 which is the tracking issue for this
+        // feature on the rustc side.
+        cargo.arg("-Zbinary-dep-depinfo");
+
         cargo.arg("-j").arg(self.jobs().to_string());
         // Remove make-related flags to ensure Cargo can correctly set things up
         cargo.env_remove("MAKEFLAGS");
diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs
index c58a98bac36..a4cb81d3d1b 100644
--- a/src/bootstrap/cc_detect.rs
+++ b/src/bootstrap/cc_detect.rs
@@ -46,7 +46,7 @@ fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
     } else if target.contains("openbsd") {
         Some(PathBuf::from("ar"))
     } else if target.contains("vxworks") {
-        Some(PathBuf::from("vx-ar"))
+        Some(PathBuf::from("wr-ar"))
     } else {
         let parent = cc.parent().unwrap();
         let file = cc.file_name().unwrap().to_str().unwrap();
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 11b082ac3f6..6e6fea6b831 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -245,7 +245,6 @@ impl Step for Rustdoc {
         let libdir = builder.sysroot_libdir(compiler, target);
         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
         add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
-        builder.cargo(compiler, Mode::ToolRustc, target, "clean");
     }
 }
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 4b4b072cc1c..96987d08159 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio, exit};
 use std::str;
 
-use build_helper::{output, mtime, t, up_to_date};
+use build_helper::{output, t, up_to_date};
 use filetime::FileTime;
 use serde::Deserialize;
 use serde_json;
@@ -274,8 +274,6 @@ impl Step for StdLink {
             // for reason why the sanitizers are not built in stage0.
             copy_apple_sanitizer_dylibs(builder, &builder.native_dir(target), "osx", &libdir);
         }
-
-        builder.cargo(target_compiler, Mode::ToolStd, target, "clean");
     }
 }
 
@@ -480,8 +478,6 @@ impl Step for TestLink {
             &builder.sysroot_libdir(target_compiler, compiler.host),
             &libtest_stamp(builder, compiler, target)
         );
-
-        builder.cargo(target_compiler, Mode::ToolTest, target, "clean");
     }
 }
 
@@ -639,7 +635,6 @@ impl Step for RustcLink {
             &builder.sysroot_libdir(target_compiler, compiler.host),
             &librustc_stamp(builder, compiler, target)
         );
-        builder.cargo(target_compiler, Mode::ToolRustc, target, "clean");
     }
 }
 
@@ -795,6 +790,9 @@ pub fn build_codegen_backend(builder: &Builder<'_>,
             if builder.config.llvm_use_libcxx {
                 cargo.env("LLVM_USE_LIBCXX", "1");
             }
+            if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
+                cargo.env("LLVM_NDEBUG", "1");
+            }
         }
         _ => panic!("unknown backend: {}", backend),
     }
@@ -1202,41 +1200,13 @@ pub fn run_cargo(builder: &Builder<'_>,
         deps.push((path_to_add.into(), false));
     }
 
-    // Now we want to update the contents of the stamp file, if necessary. First
-    // we read off the previous contents along with its mtime. If our new
-    // contents (the list of files to copy) is different or if any dep's mtime
-    // is newer then we rewrite the stamp file.
     deps.sort();
-    let stamp_contents = fs::read(stamp);
-    let stamp_mtime = mtime(&stamp);
     let mut new_contents = Vec::new();
-    let mut max = None;
-    let mut max_path = None;
     for (dep, proc_macro) in deps.iter() {
-        let mtime = mtime(dep);
-        if Some(mtime) > max {
-            max = Some(mtime);
-            max_path = Some(dep.clone());
-        }
         new_contents.extend(if *proc_macro { b"h" } else { b"t" });
         new_contents.extend(dep.to_str().unwrap().as_bytes());
         new_contents.extend(b"\0");
     }
-    let max = max.unwrap();
-    let max_path = max_path.unwrap();
-    let contents_equal = stamp_contents
-        .map(|contents| contents == new_contents)
-        .unwrap_or_default();
-    if contents_equal && max <= stamp_mtime {
-        builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
-                stamp, max, stamp_mtime));
-        return deps.into_iter().map(|(d, _)| d).collect()
-    }
-    if max > stamp_mtime {
-        builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path));
-    } else {
-        builder.verbose(&format!("updating {:?} as deps changed", stamp));
-    }
     t!(fs::write(&stamp, &new_contents));
     deps.into_iter().map(|(d, _)| d).collect()
 }
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 73d6fe532c8..e0a1f46078d 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -81,5 +81,14 @@ ci-subset-1:
 ci-subset-2:
 	$(Q)$(BOOTSTRAP) test $(TESTS_IN_2)
 
+TESTS_IN_MINGW_2 := \
+	src/test/ui \
+	src/test/compile-fail
+
+ci-mingw-subset-1:
+	$(Q)$(BOOTSTRAP) test $(TESTS_IN_MINGW_2:%=--exclude %)
+ci-mingw-subset-2:
+	$(Q)$(BOOTSTRAP) test $(TESTS_IN_MINGW_2)
+
 
 .PHONY: dist
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 4e3930c8da7..bffe748f37c 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -202,10 +202,6 @@ pub fn check(build: &mut Build) {
                         panic!("couldn't find libc.a in musl dir: {}",
                                root.join("lib").display());
                     }
-                    if fs::metadata(root.join("lib/libunwind.a")).is_err() {
-                        panic!("couldn't find libunwind.a in musl dir: {}",
-                               root.join("lib").display());
-                    }
                 }
                 None => {
                     panic!("when targeting MUSL either the rust.musl-root \
diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 06fa3bd9f43..77c9cda58b8 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -272,7 +272,7 @@ jobs:
       i686-mingw-1:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-        SCRIPT: make ci-subset-1
+        SCRIPT: make ci-mingw-subset-1
         MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
         MINGW_DIR: mingw32
@@ -282,13 +282,13 @@ jobs:
       i686-mingw-2:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
-        SCRIPT: make ci-subset-2
+        SCRIPT: make ci-mingw-subset-2
         MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
         MINGW_DIR: mingw32
       x86_64-mingw-1:
         MSYS_BITS: 64
-        SCRIPT: make ci-subset-1
+        SCRIPT: make ci-mingw-subset-1
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
         MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
@@ -298,7 +298,7 @@ jobs:
         NO_LLVM_ASSERTIONS: 1
       x86_64-mingw-2:
         MSYS_BITS: 64
-        SCRIPT: make ci-subset-2
+        SCRIPT: make ci-mingw-subset-2
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
         MINGW_URL: https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc
         MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
index ca32888b74c..ac6b344a45e 100644
--- a/src/ci/azure-pipelines/steps/run.yml
+++ b/src/ci/azure-pipelines/steps/run.yml
@@ -199,7 +199,7 @@ steps:
 # Upload CPU usage statistics that we've been gathering this whole time. Always
 # execute this step in case we want to inspect failed builds, but don't let
 # errors here ever fail the build since this is just informational.
-- bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$SYSTEM_JOBNAME.csv
+- bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$CI_JOB_NAME.csv
   env:
     AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
   condition: variables['AWS_SECRET_ACCESS_KEY']
diff --git a/src/ci/docker/scripts/musl-toolchain.sh b/src/ci/docker/scripts/musl-toolchain.sh
index 55899fa6c3e..74ba2f0eadb 100644
--- a/src/ci/docker/scripts/musl-toolchain.sh
+++ b/src/ci/docker/scripts/musl-toolchain.sh
@@ -54,29 +54,3 @@ if [ "$REPLACE_CC" = "1" ]; then
         ln -s $TARGET-g++ /usr/local/bin/$exec
     done
 fi
-
-export CC=$TARGET-gcc
-export CXX=$TARGET-g++
-
-LLVM=70
-
-# may have been downloaded in a previous run
-if [ ! -d libunwind-release_$LLVM ]; then
-  curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
-  curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
-fi
-
-# fixme(mati865): Replace it with https://github.com/rust-lang/rust/pull/59089
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_$LLVM \
-          -DLLVM_PATH=/build/llvm-release_$LLVM \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=$CC \
-          -DCMAKE_CXX_COMPILER=$CXX \
-          -DCMAKE_C_FLAGS="$CFLAGS" \
-          -DCMAKE_CXX_FLAGS="$CXXFLAGS"
-
-hide_output make -j$(nproc)
-cp lib/libunwind.a $OUTPUT/$TARGET/lib
-cd - && rm -rf libunwind-build
diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh
index c2cf77d56cb..d847c407aba 100644
--- a/src/ci/docker/scripts/musl.sh
+++ b/src/ci/docker/scripts/musl.sh
@@ -20,6 +20,8 @@ exit 1
 TAG=$1
 shift
 
+# Ancient binutils versions don't understand debug symbols produced by more recent tools.
+# Apparently applying `-fPIC` everywhere allows them to link successfully.
 export CFLAGS="-fPIC $CFLAGS"
 
 MUSL=musl-1.1.22
@@ -38,27 +40,3 @@ else
 fi
 hide_output make install
 hide_output make clean
-
-cd ..
-
-LLVM=70
-
-# may have been downloaded in a previous run
-if [ ! -d libunwind-release_$LLVM ]; then
-  curl -L https://github.com/llvm-mirror/llvm/archive/release_$LLVM.tar.gz | tar xzf -
-  curl -L https://github.com/llvm-mirror/libunwind/archive/release_$LLVM.tar.gz | tar xzf -
-fi
-
-mkdir libunwind-build
-cd libunwind-build
-cmake ../libunwind-release_$LLVM \
-          -DLLVM_PATH=/build/llvm-release_$LLVM \
-          -DLIBUNWIND_ENABLE_SHARED=0 \
-          -DCMAKE_C_COMPILER=$CC \
-          -DCMAKE_CXX_COMPILER=$CXX \
-          -DCMAKE_C_FLAGS="$CFLAGS" \
-          -DCMAKE_CXX_FLAGS="$CXXFLAGS"
-
-hide_output make -j$(nproc)
-cp lib/libunwind.a /musl-$TAG/lib
-cd ../ && rm -rf libunwind-build
diff --git a/src/doc/unstable-book/src/language-features/or-patterns.md b/src/doc/unstable-book/src/language-features/or-patterns.md
new file mode 100644
index 00000000000..8ebacb44d37
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/or-patterns.md
@@ -0,0 +1,36 @@
+# `or_patterns`
+
+The tracking issue for this feature is: [#54883]
+
+[#54883]: https://github.com/rust-lang/rust/issues/54883
+
+------------------------
+
+The `or_pattern` language feature allows `|` to be arbitrarily nested within
+a pattern, for example, `Some(A(0) | B(1 | 2))` becomes a valid pattern.
+
+## Examples
+
+```rust,ignore
+#![feature(or_patterns)]
+
+pub enum Foo {
+    Bar,
+    Baz,
+    Quux,
+}
+
+pub fn example(maybe_foo: Option<Foo>) {
+    match maybe_foo {
+        Some(Foo::Bar | Foo::Baz) => {
+            println!("The value contained `Bar` or `Baz`");
+        }
+        Some(_) => {
+            println!("The value did not contain `Bar` or `Baz`");
+        }
+        None => {
+            println!("The value was `None`");
+        }
+    }
+}
+```
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index c92db517cad..c61e3183409 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -91,8 +91,10 @@ use core::ops::{
     CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Receiver, Generator, GeneratorState
 };
 use core::ptr::{self, NonNull, Unique};
+use core::slice;
 use core::task::{Context, Poll};
 
+use crate::alloc::{self, Global, Alloc};
 use crate::vec::Vec;
 use crate::raw_vec::RawVec;
 use crate::str::from_boxed_utf8_unchecked;
@@ -121,6 +123,34 @@ impl<T> Box<T> {
         box x
     }
 
+    /// Constructs a new box with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut five = Box::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     five.as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
+        let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
+        let ptr = unsafe {
+            Global.alloc(layout)
+                .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+        };
+        Box(ptr.cast().into())
+    }
+
     /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
     /// `x` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]
@@ -130,6 +160,111 @@ impl<T> Box<T> {
     }
 }
 
+impl<T> Box<[T]> {
+    /// Constructs a new boxed slice with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut values = Box::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     values[0].as_mut_ptr().write(1);
+    ///     values[1].as_mut_ptr().write(2);
+    ///     values[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
+        let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
+        let ptr = unsafe { alloc::alloc(layout) };
+        let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
+        let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
+        Box(Unique::from(slice))
+    }
+}
+
+impl<T> Box<mem::MaybeUninit<T>> {
+    /// Converts to `Box<T>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut five = Box::<u32>::new_uninit();
+    ///
+    /// let five: Box<u32> = unsafe {
+    ///     // Deferred initialization:
+    ///     five.as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Box<T> {
+        Box(Box::into_unique(self).cast())
+    }
+}
+
+impl<T> Box<[mem::MaybeUninit<T>]> {
+    /// Converts to `Box<[T]>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the values
+    /// really are in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    ///
+    /// let mut values = Box::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     values[0].as_mut_ptr().write(1);
+    ///     values[1].as_mut_ptr().write(2);
+    ///     values[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Box<[T]> {
+        Box(Unique::new_unchecked(Box::into_raw(self) as _))
+    }
+}
+
 impl<T: ?Sized> Box<T> {
     /// Constructs a box from a raw pointer.
     ///
diff --git a/src/liballoc/collections/mod.rs b/src/liballoc/collections/mod.rs
index 5a33ddc14f0..f1f22fe48c5 100644
--- a/src/liballoc/collections/mod.rs
+++ b/src/liballoc/collections/mod.rs
@@ -41,32 +41,35 @@ pub use linked_list::LinkedList;
 #[doc(no_inline)]
 pub use vec_deque::VecDeque;
 
-use crate::alloc::{AllocErr, LayoutErr};
+use crate::alloc::{Layout, LayoutErr};
 
-/// Augments `AllocErr` with a CapacityOverflow variant.
+/// The error type for `try_reserve` methods.
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-pub enum CollectionAllocErr {
+pub enum TryReserveError {
     /// Error due to the computed capacity exceeding the collection's maximum
     /// (usually `isize::MAX` bytes).
     CapacityOverflow,
-    /// Error due to the allocator (see the `AllocErr` type's docs).
-    AllocErr,
-}
 
-#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-impl From<AllocErr> for CollectionAllocErr {
-    #[inline]
-    fn from(AllocErr: AllocErr) -> Self {
-        CollectionAllocErr::AllocErr
-    }
+    /// The memory allocator returned an error
+    AllocError {
+        /// The layout of allocation request that failed
+        layout: Layout,
+
+        #[doc(hidden)]
+        #[unstable(feature = "container_error_extra", issue = "0", reason = "\
+            Enable exposing the allocator’s custom error value \
+            if an associated type is added in the future: \
+            https://github.com/rust-lang/wg-allocators/issues/23")]
+        non_exhaustive: (),
+    },
 }
 
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-impl From<LayoutErr> for CollectionAllocErr {
+impl From<LayoutErr> for TryReserveError {
     #[inline]
     fn from(_: LayoutErr) -> Self {
-        CollectionAllocErr::CapacityOverflow
+        TryReserveError::CapacityOverflow
     }
 }
 
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 9240346ace9..2fc87413367 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -18,7 +18,7 @@ use core::ptr::{self, NonNull};
 use core::slice;
 use core::hash::{Hash, Hasher};
 
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::raw_vec::RawVec;
 use crate::vec::Vec;
 
@@ -576,10 +576,10 @@ impl<T> VecDeque<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     /// use std::collections::VecDeque;
     ///
-    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, TryReserveError> {
     ///     let mut output = VecDeque::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -595,7 +595,7 @@ impl<T> VecDeque<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>  {
+    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>  {
         self.try_reserve(additional)
     }
 
@@ -614,10 +614,10 @@ impl<T> VecDeque<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     /// use std::collections::VecDeque;
     ///
-    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<VecDeque<u32>, TryReserveError> {
     ///     let mut output = VecDeque::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -633,12 +633,12 @@ impl<T> VecDeque<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         let old_cap = self.cap();
         let used_cap = self.len() + 1;
         let new_cap = used_cap.checked_add(additional)
             .and_then(|needed_cap| needed_cap.checked_next_power_of_two())
-            .ok_or(CollectionAllocErr::CapacityOverflow)?;
+            .ok_or(TryReserveError::CapacityOverflow)?;
 
         if new_cap > old_cap {
             self.buf.try_reserve_exact(used_cap, new_cap - used_cap)?;
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 7421beddd95..4a48945adc3 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -87,6 +87,7 @@
 #![feature(const_in_array_repeat_expressions)]
 #![feature(dispatch_from_dyn)]
 #![feature(core_intrinsics)]
+#![feature(container_error_extra)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index 250c419c531..0b5e186d4c7 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -98,5 +98,5 @@ macro_rules! vec {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! format {
-    ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
+    ($($arg:tt)*) => ($crate::fmt::format(::core::format_args!($($arg)*)))
 }
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 0abab45e920..bc8a38f6b3a 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -7,8 +7,8 @@ use core::ops::Drop;
 use core::ptr::{self, NonNull, Unique};
 use core::slice;
 
-use crate::alloc::{Alloc, Layout, Global, handle_alloc_error};
-use crate::collections::CollectionAllocErr::{self, *};
+use crate::alloc::{Alloc, Layout, Global, AllocErr, handle_alloc_error};
+use crate::collections::TryReserveError::{self, *};
 use crate::boxed::Box;
 
 #[cfg(test)]
@@ -385,7 +385,7 @@ impl<T, A: Alloc> RawVec<T, A> {
 
     /// The same as `reserve_exact`, but returns on errors instead of panicking or aborting.
     pub fn try_reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize)
-           -> Result<(), CollectionAllocErr> {
+           -> Result<(), TryReserveError> {
 
         self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Exact)
     }
@@ -413,7 +413,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
         match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) {
             Err(CapacityOverflow) => capacity_overflow(),
-            Err(AllocErr) => unreachable!(),
+            Err(AllocError { .. }) => unreachable!(),
             Ok(()) => { /* yay */ }
          }
      }
@@ -422,7 +422,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     /// needed_extra_capacity` elements. This logic is used in amortized reserve methods.
     /// Returns `(new_capacity, new_alloc_size)`.
     fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize)
-        -> Result<usize, CollectionAllocErr> {
+        -> Result<usize, TryReserveError> {
 
         // Nothing we can really do about these checks :(
         let required_cap = used_capacity.checked_add(needed_extra_capacity)
@@ -435,7 +435,7 @@ impl<T, A: Alloc> RawVec<T, A> {
 
     /// The same as `reserve`, but returns on errors instead of panicking or aborting.
     pub fn try_reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize)
-        -> Result<(), CollectionAllocErr> {
+        -> Result<(), TryReserveError> {
         self.reserve_internal(used_capacity, needed_extra_capacity, Fallible, Amortized)
     }
 
@@ -494,7 +494,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
         match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Amortized) {
             Err(CapacityOverflow) => capacity_overflow(),
-            Err(AllocErr) => unreachable!(),
+            Err(AllocError { .. }) => unreachable!(),
             Ok(()) => { /* yay */ }
         }
     }
@@ -640,10 +640,8 @@ impl<T, A: Alloc> RawVec<T, A> {
         needed_extra_capacity: usize,
         fallibility: Fallibility,
         strategy: ReserveStrategy,
-    ) -> Result<(), CollectionAllocErr> {
+    ) -> Result<(), TryReserveError> {
         unsafe {
-            use crate::alloc::AllocErr;
-
             // NOTE: we don't early branch on ZSTs here because we want this
             // to actually catch "asking for more than usize::MAX" in that case.
             // If we make it past the first branch then we are guaranteed to
@@ -672,12 +670,16 @@ impl<T, A: Alloc> RawVec<T, A> {
                 None => self.a.alloc(new_layout),
             };
 
-            match (&res, fallibility) {
+            let ptr = match (res, fallibility) {
                 (Err(AllocErr), Infallible) => handle_alloc_error(new_layout),
-                _ => {}
-            }
+                (Err(AllocErr), Fallible) => return Err(TryReserveError::AllocError {
+                    layout: new_layout,
+                    non_exhaustive: (),
+                }),
+                (Ok(ptr), _) => ptr,
+            };
 
-            self.ptr = res?.cast().into();
+            self.ptr = ptr.cast().into();
             self.cap = new_cap;
 
             Ok(())
@@ -737,7 +739,7 @@ unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
 // all 4GB in user-space. e.g., PAE or x32
 
 #[inline]
-fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> {
+fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
     if mem::size_of::<usize>() < 8 && alloc_size > core::isize::MAX as usize {
         Err(CapacityOverflow)
     } else {
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 0c406a92029..2b222caf13f 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -327,6 +327,37 @@ impl<T> Rc<T> {
         }))
     }
 
+    /// Constructs a new `Rc` with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut five = Rc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit() -> Rc<mem::MaybeUninit<T>> {
+        unsafe {
+            Rc::from_ptr(Rc::allocate_for_layout(
+                Layout::new::<T>(),
+                |mem| mem as *mut RcBox<mem::MaybeUninit<T>>,
+            ))
+        }
+    }
+
     /// Constructs a new `Pin<Rc<T>>`. If `T` does not implement `Unpin`, then
     /// `value` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]
@@ -377,6 +408,118 @@ impl<T> Rc<T> {
     }
 }
 
+impl<T> Rc<[T]> {
+    /// Constructs a new reference-counted slice with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit<T>]> {
+        unsafe {
+            Rc::from_ptr(Rc::allocate_for_slice(len))
+        }
+    }
+}
+
+impl<T> Rc<mem::MaybeUninit<T>> {
+    /// Converts to `Rc<T>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut five = Rc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Rc<T> {
+        Rc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+    }
+}
+
+impl<T> Rc<[mem::MaybeUninit<T>]> {
+    /// Converts to `Rc<[T]>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut values = Rc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Rc<[T]> {
+        Rc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
+    }
+}
+
 impl<T: ?Sized> Rc<T> {
     /// Consumes the `Rc`, returning the wrapped pointer.
     ///
@@ -560,13 +703,46 @@ impl<T: ?Sized> Rc<T> {
     pub fn get_mut(this: &mut Self) -> Option<&mut T> {
         if Rc::is_unique(this) {
             unsafe {
-                Some(&mut this.ptr.as_mut().value)
+                Some(Rc::get_mut_unchecked(this))
             }
         } else {
             None
         }
     }
 
+    /// Returns a mutable reference to the inner value,
+    /// without any check.
+    ///
+    /// See also [`get_mut`], which is safe and does appropriate checks.
+    ///
+    /// [`get_mut`]: struct.Rc.html#method.get_mut
+    ///
+    /// # Safety
+    ///
+    /// Any other `Rc` or [`Weak`] pointers to the same value must not be dereferenced
+    /// for the duration of the returned borrow.
+    /// This is trivially the case if no such pointers exist,
+    /// for example immediately after `Rc::new`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::rc::Rc;
+    ///
+    /// let mut x = Rc::new(String::new());
+    /// unsafe {
+    ///     Rc::get_mut_unchecked(&mut x).push_str("foo")
+    /// }
+    /// assert_eq!(*x, "foo");
+    /// ```
+    #[inline]
+    #[unstable(feature = "get_mut_unchecked", issue = "63292")]
+    pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
+        &mut this.ptr.as_mut().value
+    }
+
     #[inline]
     #[stable(feature = "ptr_eq", since = "1.17.0")]
     /// Returns `true` if the two `Rc`s point to the same value (not
@@ -704,11 +880,11 @@ impl Rc<dyn Any> {
 
 impl<T: ?Sized> Rc<T> {
     /// Allocates an `RcBox<T>` with sufficient space for
-    /// an unsized value where the value has the layout provided.
+    /// a possibly-unsized value where the value has the layout provided.
     ///
     /// The function `mem_to_rcbox` is called with the data pointer
     /// and must return back a (potentially fat)-pointer for the `RcBox<T>`.
-    unsafe fn allocate_for_unsized(
+    unsafe fn allocate_for_layout(
         value_layout: Layout,
         mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>
     ) -> *mut RcBox<T> {
@@ -737,7 +913,7 @@ impl<T: ?Sized> Rc<T> {
     /// Allocates an `RcBox<T>` with sufficient space for an unsized value
     unsafe fn allocate_for_ptr(ptr: *const T) -> *mut RcBox<T> {
         // Allocate for the `RcBox<T>` using the given value.
-        Self::allocate_for_unsized(
+        Self::allocate_for_layout(
             Layout::for_value(&*ptr),
             |mem| set_data_ptr(ptr as *mut T, mem) as *mut RcBox<T>,
         )
@@ -768,7 +944,7 @@ impl<T: ?Sized> Rc<T> {
 impl<T> Rc<[T]> {
     /// Allocates an `RcBox<[T]>` with the given length.
     unsafe fn allocate_for_slice(len: usize) -> *mut RcBox<[T]> {
-        Self::allocate_for_unsized(
+        Self::allocate_for_layout(
             Layout::array::<T>(len).unwrap(),
             |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut RcBox<[T]>,
         )
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index eca726cd410..b65f191836e 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -56,7 +56,7 @@ use core::ptr;
 use core::str::{pattern::Pattern, lossy};
 
 use crate::borrow::{Cow, ToOwned};
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::boxed::Box;
 use crate::str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
 use crate::vec::Vec;
@@ -937,9 +937,9 @@ impl String {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
+    /// fn process_data(data: &str) -> Result<String, TryReserveError> {
     ///     let mut output = String::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -953,7 +953,7 @@ impl String {
     /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.vec.try_reserve(additional)
     }
 
@@ -975,9 +975,9 @@ impl String {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
+    /// fn process_data(data: &str) -> Result<String, TryReserveError> {
     ///     let mut output = String::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -991,7 +991,7 @@ impl String {
     /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>  {
+    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>  {
         self.vec.try_reserve_exact(additional)
     }
 
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 7d3b2656a7b..341172136e2 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -311,6 +311,37 @@ impl<T> Arc<T> {
         Self::from_inner(Box::into_raw_non_null(x))
     }
 
+    /// Constructs a new `Arc` with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut five = Arc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
+        unsafe {
+            Arc::from_ptr(Arc::allocate_for_layout(
+                Layout::new::<T>(),
+                |mem| mem as *mut ArcInner<mem::MaybeUninit<T>>,
+            ))
+        }
+    }
+
     /// Constructs a new `Pin<Arc<T>>`. If `T` does not implement `Unpin`, then
     /// `data` will be pinned in memory and unable to be moved.
     #[stable(feature = "pin", since = "1.33.0")]
@@ -361,6 +392,118 @@ impl<T> Arc<T> {
     }
 }
 
+impl<T> Arc<[T]> {
+    /// Constructs a new reference-counted slice with uninitialized contents.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
+        unsafe {
+            Arc::from_ptr(Arc::allocate_for_slice(len))
+        }
+    }
+}
+
+impl<T> Arc<mem::MaybeUninit<T>> {
+    /// Converts to `Arc<T>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut five = Arc::<u32>::new_uninit();
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Arc<T> {
+        Arc::from_inner(mem::ManuallyDrop::new(self).ptr.cast())
+    }
+}
+
+impl<T> Arc<[mem::MaybeUninit<T>]> {
+    /// Converts to `Arc<[T]>`.
+    ///
+    /// # Safety
+    ///
+    /// As with [`MaybeUninit::assume_init`],
+    /// it is up to the caller to guarantee that the value
+    /// really is in an initialized state.
+    /// Calling this when the content is not yet fully initialized
+    /// causes immediate undefined behavior.
+    ///
+    /// [`MaybeUninit::assume_init`]: ../../std/mem/union.MaybeUninit.html#method.assume_init
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(new_uninit)]
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut values = Arc::<[u32]>::new_uninit_slice(3);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     Arc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(1);
+    ///     Arc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(2);
+    ///     Arc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
+    pub unsafe fn assume_init(self) -> Arc<[T]> {
+        Arc::from_ptr(mem::ManuallyDrop::new(self).ptr.as_ptr() as _)
+    }
+}
+
 impl<T: ?Sized> Arc<T> {
     /// Consumes the `Arc`, returning the wrapped pointer.
     ///
@@ -593,11 +736,11 @@ impl<T: ?Sized> Arc<T> {
 
 impl<T: ?Sized> Arc<T> {
     /// Allocates an `ArcInner<T>` with sufficient space for
-    /// an unsized value where the value has the layout provided.
+    /// a possibly-unsized value where the value has the layout provided.
     ///
     /// The function `mem_to_arcinner` is called with the data pointer
     /// and must return back a (potentially fat)-pointer for the `ArcInner<T>`.
-    unsafe fn allocate_for_unsized(
+    unsafe fn allocate_for_layout(
         value_layout: Layout,
         mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>
     ) -> *mut ArcInner<T> {
@@ -625,7 +768,7 @@ impl<T: ?Sized> Arc<T> {
     /// Allocates an `ArcInner<T>` with sufficient space for an unsized value.
     unsafe fn allocate_for_ptr(ptr: *const T) -> *mut ArcInner<T> {
         // Allocate for the `ArcInner<T>` using the given value.
-        Self::allocate_for_unsized(
+        Self::allocate_for_layout(
             Layout::for_value(&*ptr),
             |mem| set_data_ptr(ptr as *mut T, mem) as *mut ArcInner<T>,
         )
@@ -656,7 +799,7 @@ impl<T: ?Sized> Arc<T> {
 impl<T> Arc<[T]> {
     /// Allocates an `ArcInner<[T]>` with the given length.
     unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> {
-        Self::allocate_for_unsized(
+        Self::allocate_for_layout(
             Layout::array::<T>(len).unwrap(),
             |mem| ptr::slice_from_raw_parts_mut(mem as *mut T, len) as *mut ArcInner<[T]>,
         )
@@ -945,13 +1088,46 @@ impl<T: ?Sized> Arc<T> {
             // the Arc itself to be `mut`, so we're returning the only possible
             // reference to the inner data.
             unsafe {
-                Some(&mut this.ptr.as_mut().data)
+                Some(Arc::get_mut_unchecked(this))
             }
         } else {
             None
         }
     }
 
+    /// Returns a mutable reference to the inner value,
+    /// without any check.
+    ///
+    /// See also [`get_mut`], which is safe and does appropriate checks.
+    ///
+    /// [`get_mut`]: struct.Arc.html#method.get_mut
+    ///
+    /// # Safety
+    ///
+    /// Any other `Arc` or [`Weak`] pointers to the same value must not be dereferenced
+    /// for the duration of the returned borrow.
+    /// This is trivially the case if no such pointers exist,
+    /// for example immediately after `Arc::new`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(get_mut_unchecked)]
+    ///
+    /// use std::sync::Arc;
+    ///
+    /// let mut x = Arc::new(String::new());
+    /// unsafe {
+    ///     Arc::get_mut_unchecked(&mut x).push_str("foo")
+    /// }
+    /// assert_eq!(*x, "foo");
+    /// ```
+    #[inline]
+    #[unstable(feature = "get_mut_unchecked", issue = "63292")]
+    pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
+        &mut this.ptr.as_mut().data
+    }
+
     /// Determine whether this is the unique reference (including weak refs) to
     /// the underlying data.
     ///
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index 765210e5aa6..55edf56345b 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -1,5 +1,5 @@
 use std::borrow::Cow;
-use std::collections::CollectionAllocErr::*;
+use std::collections::TryReserveError::*;
 use std::mem::size_of;
 use std::{usize, isize};
 
@@ -566,11 +566,11 @@ fn test_try_reserve() {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
             // Check isize::MAX + 1 is an OOM
-            if let Err(AllocErr) = empty_string.try_reserve(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
             // Check usize::MAX is an OOM
-            if let Err(AllocErr) = empty_string.try_reserve(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -590,7 +590,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should always overflow in the add-to-len
@@ -629,10 +629,10 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
-            if let Err(AllocErr) = empty_string.try_reserve_exact(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
-            if let Err(AllocErr) = empty_string.try_reserve_exact(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_string.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -651,7 +651,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 6e8ffe18522..29a22aa0315 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -2,7 +2,7 @@ use std::borrow::Cow;
 use std::mem::size_of;
 use std::{usize, isize};
 use std::vec::{Drain, IntoIter};
-use std::collections::CollectionAllocErr::*;
+use std::collections::TryReserveError::*;
 
 struct DropCounter<'a> {
     count: &'a mut u32,
@@ -1121,11 +1121,11 @@ fn test_try_reserve() {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
             // Check isize::MAX + 1 is an OOM
-            if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
             // Check usize::MAX is an OOM
-            if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -1145,7 +1145,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should always overflow in the add-to-len
@@ -1168,7 +1168,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should fail in the mul-by-size
@@ -1209,10 +1209,10 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an overflow!") }
         } else {
-            if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP + 1) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
 
-            if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_USIZE) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_USIZE) {
             } else { panic!("usize::MAX should trigger an OOM!") }
         }
     }
@@ -1231,7 +1231,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
@@ -1252,7 +1252,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 1bbcca97b3c..d49b553fc02 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -1,6 +1,6 @@
 use std::fmt::Debug;
 use std::collections::{VecDeque, vec_deque::Drain};
-use std::collections::CollectionAllocErr::*;
+use std::collections::TryReserveError::*;
 use std::mem::size_of;
 use std::{usize, isize};
 
@@ -1168,7 +1168,7 @@ fn test_try_reserve() {
             // VecDeque starts with capacity 7, always adds 1 to the capacity
             // and also rounds the number to next power of 2 so this is the
             // furthest we can go without triggering CapacityOverflow
-            if let Err(AllocErr) = empty_bytes.try_reserve(MAX_CAP) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_CAP) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
     }
@@ -1188,7 +1188,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should always overflow in the add-to-len
@@ -1211,7 +1211,7 @@ fn test_try_reserve() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         // Should fail in the mul-by-size
@@ -1256,7 +1256,7 @@ fn test_try_reserve_exact() {
             // VecDeque starts with capacity 7, always adds 1 to the capacity
             // and also rounds the number to next power of 2 so this is the
             // furthest we can go without triggering CapacityOverflow
-            if let Err(AllocErr) = empty_bytes.try_reserve_exact(MAX_CAP) {
+            if let Err(AllocError { .. }) = empty_bytes.try_reserve_exact(MAX_CAP) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
     }
@@ -1275,7 +1275,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
+            if let Err(AllocError { .. }) = ten_bytes.try_reserve_exact(MAX_CAP - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) {
@@ -1296,7 +1296,7 @@ fn test_try_reserve_exact() {
             if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an overflow!"); }
         } else {
-            if let Err(AllocErr) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
+            if let Err(AllocError { .. }) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) {
             } else { panic!("isize::MAX + 1 should trigger an OOM!") }
         }
         if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) {
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index dac04e4e624..d2798955c46 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -70,7 +70,7 @@ use core::ptr::{self, NonNull};
 use core::slice::{self, SliceIndex};
 
 use crate::borrow::{ToOwned, Cow};
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::boxed::Box;
 use crate::raw_vec::RawVec;
 
@@ -498,9 +498,9 @@ impl<T> Vec<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
     ///     let mut output = Vec::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -516,7 +516,7 @@ impl<T> Vec<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.buf.try_reserve(self.len, additional)
     }
 
@@ -538,9 +538,9 @@ impl<T> Vec<T> {
     ///
     /// ```
     /// #![feature(try_reserve)]
-    /// use std::collections::CollectionAllocErr;
+    /// use std::collections::TryReserveError;
     ///
-    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, CollectionAllocErr> {
+    /// fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
     ///     let mut output = Vec::new();
     ///
     ///     // Pre-reserve the memory, exiting if we can't
@@ -556,7 +556,7 @@ impl<T> Vec<T> {
     /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?");
     /// ```
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr>  {
+    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError>  {
         self.buf.try_reserve_exact(self.len, additional)
     }
 
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index ec22a7ccfe4..ec70d396e96 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -135,7 +135,7 @@ pub trait Clone : Sized {
 
 /// Derive macro generating an impl of the trait `Clone`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
 pub macro Clone($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index b802216036b..cb9feb074dd 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -202,7 +202,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
 
 /// Derive macro generating an impl of the trait `PartialEq`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro PartialEq($item:item) { /* compiler built-in */ }
@@ -265,7 +265,7 @@ pub trait Eq: PartialEq<Self> {
 
 /// Derive macro generating an impl of the trait `Eq`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics, derive_eq)]
 pub macro Eq($item:item) { /* compiler built-in */ }
@@ -616,7 +616,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
 
 /// Derive macro generating an impl of the trait `Ord`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro Ord($item:item) { /* compiler built-in */ }
@@ -865,7 +865,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
 
 /// Derive macro generating an impl of the trait `PartialOrd`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro PartialOrd($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index 9b1616ccce4..66acc5165fc 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -117,7 +117,7 @@ pub trait Default: Sized {
 
 /// Derive macro generating an impl of the trait `Default`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics)]
 pub macro Default($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index cb4e32622ff..15ce2277fa0 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -98,7 +98,7 @@ pub struct DebugStruct<'a, 'b: 'a> {
     has_fields: bool,
 }
 
-pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
+pub(super) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
                                 name: &str)
                                 -> DebugStruct<'a, 'b> {
     let result = fmt.write_str(name);
@@ -251,7 +251,10 @@ pub struct DebugTuple<'a, 'b: 'a> {
     empty_name: bool,
 }
 
-pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugTuple<'a, 'b> {
+pub(super) fn debug_tuple_new<'a, 'b>(
+    fmt: &'a mut fmt::Formatter<'b>,
+    name: &str,
+) -> DebugTuple<'a, 'b> {
     let result = fmt.write_str(name);
     DebugTuple {
         fmt,
@@ -418,7 +421,7 @@ pub struct DebugSet<'a, 'b: 'a> {
     inner: DebugInner<'a, 'b>,
 }
 
-pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
+pub(super) fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
     let result = fmt.write_str("{");
     DebugSet {
         inner: DebugInner {
@@ -555,7 +558,7 @@ pub struct DebugList<'a, 'b: 'a> {
     inner: DebugInner<'a, 'b>,
 }
 
-pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
+pub(super) fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
     let result = fmt.write_str("[");
     DebugList {
         inner: DebugInner {
@@ -697,7 +700,7 @@ pub struct DebugMap<'a, 'b: 'a> {
     state: PadAdapterState,
 }
 
-pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
+pub(super) fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
     let result = fmt.write_str("{");
     DebugMap {
         fmt,
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index d5fae9e7401..bd31d25dd03 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -549,7 +549,7 @@ pub trait Debug {
 pub(crate) mod macros {
     /// Derive macro generating an impl of the trait `Debug`.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro Debug($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index b3971191123..bf3daa32840 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -202,7 +202,7 @@ pub trait Hash {
 pub(crate) mod macros {
     /// Derive macro generating an impl of the trait `Hash`.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro Hash($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index ceaa870d2b3..d145f2212f9 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1293,18 +1293,40 @@ extern "rust-intrinsic" {
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_add` method. For example,
     /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
+    #[cfg(boostrap_stdarch_ignore_this)]
     pub fn overflowing_add<T>(a: T, b: T) -> T;
     /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_sub` method. For example,
     /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
+    #[cfg(boostrap_stdarch_ignore_this)]
     pub fn overflowing_sub<T>(a: T, b: T) -> T;
     /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_mul` method. For example,
     /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
+    #[cfg(boostrap_stdarch_ignore_this)]
     pub fn overflowing_mul<T>(a: T, b: T) -> T;
 
+    /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `wrapping_add` method. For example,
+    /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
+    #[cfg(not(boostrap_stdarch_ignore_this))]
+    pub fn wrapping_add<T>(a: T, b: T) -> T;
+    /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `wrapping_sub` method. For example,
+    /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
+    #[cfg(not(boostrap_stdarch_ignore_this))]
+    pub fn wrapping_sub<T>(a: T, b: T) -> T;
+    /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
+    /// The stabilized versions of this intrinsic are available on the integer
+    /// primitives via the `wrapping_mul` method. For example,
+    /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
+    #[cfg(not(boostrap_stdarch_ignore_this))]
+    pub fn wrapping_mul<T>(a: T, b: T) -> T;
+
     /// Computes `a + b`, while saturating at numeric bounds.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `saturating_add` method. For example,
diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs
index 76239ebc0ab..0b9f7f6b609 100644
--- a/src/libcore/iter/adapters/chain.rs
+++ b/src/libcore/iter/adapters/chain.rs
@@ -207,6 +207,29 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
         }
     }
 
+    #[inline]
+    fn nth_back(&mut self, mut n: usize) -> Option<A::Item> {
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                for x in self.b.by_ref().rev() {
+                    if n == 0 {
+                        return Some(x)
+                    }
+                    n -= 1;
+                }
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Front;
+                }
+            }
+            ChainState::Front => {}
+        }
+        if let ChainState::Front = self.state {
+            self.a.nth_back(n)
+        } else {
+            None
+        }
+    }
+
     fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
         Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
     {
diff --git a/src/libcore/iter/adapters/flatten.rs b/src/libcore/iter/adapters/flatten.rs
index e3c85656116..a45173f614d 100644
--- a/src/libcore/iter/adapters/flatten.rs
+++ b/src/libcore/iter/adapters/flatten.rs
@@ -72,8 +72,7 @@ impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
 where
     F: FnMut(I::Item) -> U,
-    U: IntoIterator,
-    U::IntoIter: DoubleEndedIterator,
+    U: IntoIterator<IntoIter: DoubleEndedIterator>,
 {
     #[inline]
     fn next_back(&mut self) -> Option<U::Item> { self.inner.next_back() }
@@ -107,10 +106,7 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
 /// [`Iterator`]: trait.Iterator.html
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 #[stable(feature = "iterator_flatten", since = "1.29.0")]
-pub struct Flatten<I: Iterator>
-where
-    I::Item: IntoIterator,
-{
+pub struct Flatten<I: Iterator<Item: IntoIterator>> {
     inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
 }
 
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 58e0a70cefb..a63434abd6c 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -405,6 +405,36 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
             _ => (usize::MAX, None)
         }
     }
+
+    #[inline]
+    fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+    where
+        F: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        // fully iterate the current iterator. this is necessary because
+        // `self.iter` may be empty even when `self.orig` isn't
+        acc = self.iter.try_fold(acc, &mut f)?;
+        self.iter = self.orig.clone();
+
+        // complete a full cycle, keeping track of whether the cycled
+        // iterator is empty or not. we need to return early in case
+        // of an empty iterator to prevent an infinite loop
+        let mut is_empty = true;
+        acc = self.iter.try_fold(acc, |acc, x| {
+            is_empty = false;
+            f(acc, x)
+        })?;
+
+        if is_empty {
+            return Try::from_ok(acc);
+        }
+
+        loop {
+            self.iter = self.orig.clone();
+            acc = self.iter.try_fold(acc, &mut f)?;
+        }
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
diff --git a/src/libcore/iter/traits/double_ended.rs b/src/libcore/iter/traits/double_ended.rs
index 8e5bc9b664c..006b243ca42 100644
--- a/src/libcore/iter/traits/double_ended.rs
+++ b/src/libcore/iter/traits/double_ended.rs
@@ -69,7 +69,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// Returns the `n`th element from the end of the iterator.
     ///
     /// This is essentially the reversed version of [`nth`]. Although like most indexing
-    /// operations, the count starts from zero, so `nth_back(0)` returns the first value fro
+    /// operations, the count starts from zero, so `nth_back(0)` returns the first value from
     /// the end, `nth_back(1)` the second, and so on.
     ///
     /// Note that all elements between the end and the returned element will be
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index bbed9516716..6c88a766a2f 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -2,21 +2,21 @@
 ///
 /// For details, see `std::macros`.
 #[macro_export]
-#[allow_internal_unstable(core_panic, __rust_unstable_column)]
+#[allow_internal_unstable(core_panic)]
 #[stable(feature = "core", since = "1.6.0")]
 macro_rules! panic {
     () => (
         $crate::panic!("explicit panic")
     );
     ($msg:expr) => ({
-        $crate::panicking::panic(&($msg, file!(), line!(), __rust_unstable_column!()))
+        $crate::panicking::panic(&($msg, $crate::file!(), $crate::line!(), $crate::column!()))
     });
     ($msg:expr,) => (
         $crate::panic!($msg)
     );
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::panicking::panic_fmt(format_args!($fmt, $($arg)+),
-                                     &(file!(), line!(), __rust_unstable_column!()))
+        $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+),
+                                     &($crate::file!(), $crate::line!(), $crate::column!()))
     });
 }
 
@@ -70,7 +70,7 @@ macro_rules! assert_eq {
                     panic!(r#"assertion failed: `(left == right)`
   left: `{:?}`,
  right: `{:?}`: {}"#, &*left_val, &*right_val,
-                           format_args!($($arg)+))
+                           $crate::format_args!($($arg)+))
                 }
             }
         }
@@ -127,7 +127,7 @@ macro_rules! assert_ne {
                     panic!(r#"assertion failed: `(left != right)`
   left: `{:?}`,
  right: `{:?}`: {}"#, &*left_val, &*right_val,
-                           format_args!($($arg)+))
+                           $crate::format_args!($($arg)+))
                 }
             }
         }
@@ -181,7 +181,7 @@ macro_rules! assert_ne {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert!($($arg)*); })
 }
 
 /// Asserts that two expressions are equal to each other.
@@ -208,7 +208,7 @@ macro_rules! debug_assert {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert_eq {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_eq!($($arg)*); })
 }
 
 /// Asserts that two expressions are not equal to each other.
@@ -235,7 +235,7 @@ macro_rules! debug_assert_eq {
 #[macro_export]
 #[stable(feature = "assert_ne", since = "1.13.0")]
 macro_rules! debug_assert_ne {
-    ($($arg:tt)*) => (if cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
+    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
 }
 
 /// Unwraps a result or propagates its error.
@@ -386,7 +386,7 @@ macro_rules! r#try {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! write {
-    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
+    ($dst:expr, $($arg:tt)*) => ($dst.write_fmt($crate::format_args!($($arg)*)))
 }
 
 /// Write formatted data into a buffer, with a newline appended.
@@ -446,7 +446,7 @@ macro_rules! writeln {
         $crate::writeln!($dst)
     );
     ($dst:expr, $($arg:tt)*) => (
-        $dst.write_fmt(format_args_nl!($($arg)*))
+        $dst.write_fmt($crate::format_args_nl!($($arg)*))
     );
 }
 
@@ -515,7 +515,7 @@ macro_rules! unreachable {
         $crate::unreachable!($msg)
     });
     ($fmt:expr, $($arg:tt)*) => ({
-        panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+        panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
     });
 }
 
@@ -573,7 +573,7 @@ macro_rules! unreachable {
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! unimplemented {
     () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)+)));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
 }
 
 /// Indicates unfinished code.
@@ -632,7 +632,7 @@ macro_rules! unimplemented {
 #[unstable(feature = "todo_macro", issue = "59277")]
 macro_rules! todo {
     () => (panic!("not yet implemented"));
-    ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)+)));
+    ($($arg:tt)+) => (panic!("not yet implemented: {}", $crate::format_args!($($arg)+)));
 }
 
 /// Definitions of built-in macros.
@@ -927,13 +927,6 @@ pub(crate) mod builtin {
     #[macro_export]
     macro_rules! column { () => { /* compiler built-in */ } }
 
-    /// Same as `column`, but less likely to be shadowed.
-    #[unstable(feature = "__rust_unstable_column", issue = "0",
-               reason = "internal implementation detail of the `panic` macro")]
-    #[rustc_builtin_macro]
-    #[macro_export]
-    macro_rules! __rust_unstable_column { () => { /* compiler built-in */ } }
-
     /// Expands to the file name in which it was invoked.
     ///
     /// With [`line!`] and [`column!`], these macros provide debugging information for
@@ -1270,14 +1263,14 @@ pub(crate) mod builtin {
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
     pub macro RustcDecodable($item:item) { /* compiler built-in */ }
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
+    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro RustcEncodable($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 3befd421b01..89af2528c05 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -290,7 +290,7 @@ pub trait Copy : Clone {
 
 /// Derive macro generating an impl of the trait `Copy`.
 #[rustc_builtin_macro]
-#[rustc_macro_transparency = "semitransparent"]
+#[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[allow_internal_unstable(core_intrinsics, derive_clone_copy)]
 pub macro Copy($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 67e30e7ffcb..b46e06f8d8a 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1112,7 +1112,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_add(self, rhs: Self) -> Self {
-                intrinsics::overflowing_add(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_add(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_add(self, rhs)
+                }
             }
         }
 
@@ -1135,7 +1141,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_sub(self, rhs: Self) -> Self {
-                intrinsics::overflowing_sub(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_sub(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_sub(self, rhs)
+                }
             }
         }
 
@@ -1157,7 +1169,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_mul(self, rhs: Self) -> Self {
-                intrinsics::overflowing_mul(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_mul(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_mul(self, rhs)
+                }
             }
         }
 
@@ -3031,7 +3049,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_add(self, rhs: Self) -> Self {
-                intrinsics::overflowing_add(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_add(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_add(self, rhs)
+                }
             }
         }
 
@@ -3053,7 +3077,13 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_sub(self, rhs: Self) -> Self {
-                intrinsics::overflowing_sub(self, rhs)
+                #[cfg(boostrap_stdarch_ignore_this)] {
+                    intrinsics::overflowing_sub(self, rhs)
+                }
+
+                #[cfg(not(boostrap_stdarch_ignore_this))] {
+                    intrinsics::wrapping_sub(self, rhs)
+                }
             }
         }
 
@@ -3076,7 +3106,13 @@ $EndFeature, "
                           without modifying the original"]
         #[inline]
         pub const fn wrapping_mul(self, rhs: Self) -> Self {
-            intrinsics::overflowing_mul(self, rhs)
+            #[cfg(boostrap_stdarch_ignore_this)] {
+                intrinsics::overflowing_mul(self, rhs)
+            }
+
+            #[cfg(not(boostrap_stdarch_ignore_this))] {
+                intrinsics::wrapping_mul(self, rhs)
+            }
         }
 
         doc_comment! {
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index 76240379040..7cc279a9ef2 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -56,7 +56,6 @@ pub use crate::hash::macros::Hash;
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(no_inline)]
 pub use crate::{
-    __rust_unstable_column,
     asm,
     assert,
     cfg,
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index f0d011fe6b2..3521dd79979 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -122,6 +122,14 @@ impl<T: ?Sized> Unique<T> {
     pub unsafe fn as_mut(&mut self) -> &mut T {
         &mut *self.as_ptr()
     }
+
+    /// Casts to a pointer of another type.
+    #[inline]
+    pub const fn cast<U>(self) -> Unique<U> {
+        unsafe {
+            Unique::new_unchecked(self.as_ptr() as *mut U)
+        }
+    }
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 3615fab7915..a1a27e1d538 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -104,6 +104,22 @@ fn test_iterator_chain_nth() {
 }
 
 #[test]
+fn test_iterator_chain_nth_back() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let zs = [];
+    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
+    for (i, x) in expected.iter().rev().enumerate() {
+        assert_eq!(Some(x), xs.iter().chain(&ys).nth_back(i));
+    }
+    assert_eq!(zs.iter().chain(&xs).nth_back(0), Some(&5));
+
+    let mut it = xs.iter().chain(&zs);
+    assert_eq!(it.nth_back(5), Some(&0));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
 fn test_iterator_chain_last() {
     let xs = [0, 1, 2, 3, 4, 5];
     let ys = [30, 40, 50, 60];
@@ -1136,6 +1152,18 @@ fn test_cycle() {
     assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0);
 
     assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4);
+
+    assert_eq!((0..10).cycle().take(5).sum::<i32>(), 10);
+    assert_eq!((0..10).cycle().take(15).sum::<i32>(), 55);
+    assert_eq!((0..10).cycle().take(25).sum::<i32>(), 100);
+
+    let mut iter = (0..10).cycle();
+    iter.nth(14);
+    assert_eq!(iter.take(8).sum::<i32>(), 38);
+
+    let mut iter = (0..10).cycle();
+    iter.nth(9);
+    assert_eq!(iter.take(3).sum::<i32>(), 3);
 }
 
 #[test]
diff --git a/src/libproc_macro/bridge/client.rs b/src/libproc_macro/bridge/client.rs
index 6052b4a4d43..5c543165bc2 100644
--- a/src/libproc_macro/bridge/client.rs
+++ b/src/libproc_macro/bridge/client.rs
@@ -468,6 +468,14 @@ pub enum ProcMacro {
 }
 
 impl ProcMacro {
+    pub fn name(&self) -> &'static str {
+        match self {
+            ProcMacro::CustomDerive { trait_name, .. } => trait_name,
+            ProcMacro::Attr { name, .. } => name,
+            ProcMacro::Bang { name, ..} => name
+        }
+    }
+
     pub const fn custom_derive(
         trait_name: &'static str,
         attributes: &'static [&'static str],
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index 7ada56cfa76..0dad2dda837 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -140,6 +140,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 self.add_ast_node(pat.hir_id.local_id, &[pats_exit])
             }
 
+            PatKind::Or(ref pats) => {
+                let branches: Vec<_> = pats.iter().map(|p| self.pat(p, pred)).collect();
+                self.add_ast_node(pat.hir_id.local_id, &branches)
+            }
+
             PatKind::Slice(ref pre, ref vec, ref post) => {
                 let pre_exit = self.pats_all(pre.iter(), pred);
                 let vec_exit = self.pats_all(vec.iter(), pre_exit);
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index c0a661908a6..c91ad7858d0 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -1,5 +1,4 @@
 use crate::ty::{self, TyCtxt};
-use crate::hir::map::definitions::FIRST_FREE_DEF_INDEX;
 use rustc_data_structures::indexed_vec::Idx;
 use std::fmt;
 use std::u32;
@@ -102,31 +101,6 @@ newtype_index! {
     }
 }
 
-impl DefIndex {
-    // Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
-    // function maps the index of the macro within the crate (which is also the
-    // index of the macro in the CrateMetadata::proc_macros array) to the
-    // corresponding DefIndex.
-    pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
-        // DefIndex for proc macros start from FIRST_FREE_DEF_INDEX,
-        // because the first FIRST_FREE_DEF_INDEX indexes are reserved
-        // for internal use.
-        let def_index = DefIndex::from(
-            proc_macro_index.checked_add(FIRST_FREE_DEF_INDEX)
-                .expect("integer overflow adding `proc_macro_index`"));
-        assert!(def_index != CRATE_DEF_INDEX);
-        def_index
-    }
-
-    // This function is the reverse of from_proc_macro_index() above.
-    pub fn to_proc_macro_index(self: DefIndex) -> usize {
-        self.index().checked_sub(FIRST_FREE_DEF_INDEX)
-            .unwrap_or_else(|| {
-                bug!("using local index {:?} as proc-macro index", self)
-            })
-    }
-}
-
 impl rustc_serialize::UseSpecializedEncodable for DefIndex {}
 impl rustc_serialize::UseSpecializedDecodable for DefIndex {}
 
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 99fe9f1682f..2c6373bdfa4 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -709,6 +709,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
                 visitor.visit_pat(&field.pat)
             }
         }
+        PatKind::Or(ref pats) => walk_list!(visitor, visit_pat, pats),
         PatKind::Tuple(ref tuple_elements, _) => {
             walk_list!(visitor, visit_pat, tuple_elements);
         }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 9e5d6378c40..d2ea485b5db 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -67,7 +67,7 @@ use syntax::errors;
 use syntax::ext::base::SpecialDerives;
 use syntax::ext::hygiene::ExpnId;
 use syntax::print::pprust;
-use syntax::source_map::{respan, ExpnInfo, ExpnKind, DesugaringKind, Spanned};
+use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
 use syntax::symbol::{kw, sym, Symbol};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::parse::token::{self, Token};
@@ -704,10 +704,9 @@ impl<'a> LoweringContext<'a> {
         span: Span,
         allow_internal_unstable: Option<Lrc<[Symbol]>>,
     ) -> Span {
-        span.fresh_expansion(ExpnId::root(), ExpnInfo {
-            def_site: span,
+        span.fresh_expansion(ExpnData {
             allow_internal_unstable,
-            ..ExpnInfo::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
+            ..ExpnData::default(ExpnKind::Desugaring(reason), span, self.sess.edition())
         })
     }
 
@@ -1224,7 +1223,7 @@ impl<'a> LoweringContext<'a> {
                     P(hir::Path {
                         res,
                         segments: hir_vec![hir::PathSegment::from_ident(
-                            Ident::with_empty_ctxt(kw::SelfUpper)
+                            Ident::with_dummy_span(kw::SelfUpper)
                         )],
                         span: t.span,
                     }),
@@ -1558,7 +1557,7 @@ impl<'a> LoweringContext<'a> {
 
                     let (name, kind) = match name {
                         hir::LifetimeName::Underscore => (
-                            hir::ParamName::Plain(Ident::with_empty_ctxt(kw::UnderscoreLifetime)),
+                            hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)),
                             hir::LifetimeParamKind::Elided,
                         ),
                         hir::LifetimeName::Param(param_name) => (
@@ -2002,7 +2001,7 @@ impl<'a> LoweringContext<'a> {
                         bindings: hir_vec![
                             hir::TypeBinding {
                                 hir_id: this.next_id(),
-                                ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
+                                ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                                 kind: hir::TypeBindingKind::Equality {
                                     ty: output
                                         .as_ref()
@@ -2394,7 +2393,7 @@ impl<'a> LoweringContext<'a> {
         let future_params = P(hir::GenericArgs {
             args: hir_vec![],
             bindings: hir_vec![hir::TypeBinding {
-                ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
+                ident: Ident::with_dummy_span(FN_OUTPUT_NAME),
                 kind: hir::TypeBindingKind::Equality {
                     ty: output_ty,
                 },
@@ -2670,6 +2669,9 @@ impl<'a> LoweringContext<'a> {
                 let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
                 hir::PatKind::TupleStruct(qpath, pats, ddpos)
             }
+            PatKind::Or(ref pats) => {
+                hir::PatKind::Or(pats.iter().map(|x| self.lower_pat(x)).collect())
+            }
             PatKind::Path(ref qself, ref path) => {
                 let qpath = self.lower_qpath(
                     p.id,
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index e3a5400942d..ff0c44a2387 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -552,7 +552,7 @@ impl LoweringContext<'_> {
 
         // let mut pinned = <expr>;
         let expr = P(self.lower_expr(expr));
-        let pinned_ident = Ident::with_empty_ctxt(sym::pinned);
+        let pinned_ident = Ident::with_dummy_span(sym::pinned);
         let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
             span,
             pinned_ident,
@@ -593,7 +593,7 @@ impl LoweringContext<'_> {
         let loop_node_id = self.sess.next_node_id();
         let loop_hir_id = self.lower_node_id(loop_node_id);
         let ready_arm = {
-            let x_ident = Ident::with_empty_ctxt(sym::result);
+            let x_ident = Ident::with_dummy_span(sym::result);
             let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
             let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
             let ready_pat = self.pat_std_enum(
@@ -984,7 +984,6 @@ impl LoweringContext<'_> {
             volatile: asm.volatile,
             alignstack: asm.alignstack,
             dialect: asm.dialect,
-            ctxt: asm.ctxt,
         };
 
         let outputs = asm.outputs
@@ -1070,9 +1069,9 @@ impl LoweringContext<'_> {
         );
         head.span = desugared_span;
 
-        let iter = Ident::with_empty_ctxt(sym::iter);
+        let iter = Ident::with_dummy_span(sym::iter);
 
-        let next_ident = Ident::with_empty_ctxt(sym::__next);
+        let next_ident = Ident::with_dummy_span(sym::__next);
         let (next_pat, next_pat_hid) = self.pat_ident_binding_mode(
             desugared_span,
             next_ident,
@@ -1081,7 +1080,7 @@ impl LoweringContext<'_> {
 
         // `::std::option::Option::Some(val) => __next = val`
         let pat_arm = {
-            let val_ident = Ident::with_empty_ctxt(sym::val);
+            let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
             let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
             let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
@@ -1247,7 +1246,7 @@ impl LoweringContext<'_> {
 
         // `Ok(val) => #[allow(unreachable_code)] val,`
         let ok_arm = {
-            let val_ident = Ident::with_empty_ctxt(sym::val);
+            let val_ident = Ident::with_dummy_span(sym::val);
             let (val_pat, val_pat_nid) = self.pat_ident(span, val_ident);
             let val_expr = P(self.expr_ident_with_attrs(
                 span,
@@ -1263,7 +1262,7 @@ impl LoweringContext<'_> {
         // `Err(err) => #[allow(unreachable_code)]
         //              return Try::from_error(From::from(err)),`
         let err_arm = {
-            let err_ident = Ident::with_empty_ctxt(sym::err);
+            let err_ident = Ident::with_dummy_span(sym::err);
             let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
             let from_expr = {
                 let from_path = &[sym::convert, sym::From, sym::from];
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 51a0c4184f9..4f9a9ed5673 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -750,10 +750,7 @@ impl LoweringContext<'_> {
     }
 
     fn lower_global_asm(&mut self, ga: &GlobalAsm) -> P<hir::GlobalAsm> {
-        P(hir::GlobalAsm {
-            asm: ga.asm,
-            ctxt: ga.ctxt,
-        })
+        P(hir::GlobalAsm { asm: ga.asm })
     }
 
     fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index df9bd3a35a6..d725afa4052 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -74,7 +74,7 @@ impl<'a> DefCollector<'a> {
         })
     }
 
-    fn visit_macro_invoc(&mut self, id: NodeId) {
+    pub fn visit_macro_invoc(&mut self, id: NodeId) {
         self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
     }
 }
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 8ee8c6d0e89..6dc3c7038f5 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -411,10 +411,6 @@ impl Definitions {
     }
 
     /// Adds a root definition (no parent) and a few other reserved definitions.
-    ///
-    /// After the initial definitions are created the first `FIRST_FREE_DEF_INDEX` indexes
-    /// are taken, so the "user" indexes will be allocated starting with `FIRST_FREE_DEF_INDEX`
-    /// in ascending order.
     pub fn create_root_def(&mut self,
                            crate_name: &str,
                            crate_disambiguator: CrateDisambiguator)
@@ -589,19 +585,6 @@ impl DefPathData {
     }
 }
 
-/// Evaluates to the number of tokens passed to it.
-///
-/// Logarithmic counting: every one or two recursive expansions, the number of
-/// tokens to count is divided by two, instead of being reduced by one.
-/// Therefore, the recursion depth is the binary logarithm of the number of
-/// tokens to count, and the expanded tree is likewise very small.
-macro_rules! count {
-    ()                     => (0usize);
-    ($one:tt)              => (1usize);
-    ($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
-    ($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
-}
-
 // We define the GlobalMetaDataKind enum with this macro because we want to
 // make sure that we exhaustively iterate over all variants when registering
 // the corresponding DefIndices in the DefTable.
@@ -614,8 +597,6 @@ macro_rules! define_global_metadata_kind {
             $($variant),*
         }
 
-        pub const FIRST_FREE_DEF_INDEX: usize = 1 + count!($($variant)*);
-
         impl GlobalMetaDataKind {
             fn allocate_def_indices(definitions: &mut Definitions) {
                 $({
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 7c2f9907217..b469b7016be 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -23,7 +23,6 @@ use rustc_target::spec::abi::Abi;
 use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
 use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
 use syntax::attr::{InlineAttr, OptimizeAttr};
-use syntax::ext::hygiene::SyntaxContext;
 use syntax::symbol::{Symbol, kw};
 use syntax::tokenstream::TokenStream;
 use syntax::util::parser::ExprPrecedence;
@@ -202,7 +201,7 @@ impl ParamName {
         match *self {
             ParamName::Plain(ident) => ident,
             ParamName::Fresh(_) |
-            ParamName::Error => Ident::with_empty_ctxt(kw::UnderscoreLifetime),
+            ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime),
         }
     }
 
@@ -237,8 +236,8 @@ impl LifetimeName {
     pub fn ident(&self) -> Ident {
         match *self {
             LifetimeName::Implicit | LifetimeName::Error => Ident::invalid(),
-            LifetimeName::Underscore => Ident::with_empty_ctxt(kw::UnderscoreLifetime),
-            LifetimeName::Static => Ident::with_empty_ctxt(kw::StaticLifetime),
+            LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
+            LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
             LifetimeName::Param(param_name) => param_name.ident(),
         }
     }
@@ -882,6 +881,7 @@ impl Pat {
             PatKind::TupleStruct(_, ref s, _) | PatKind::Tuple(ref s, _) => {
                 s.iter().all(|p| p.walk_(it))
             }
+            PatKind::Or(ref pats) => pats.iter().all(|p| p.walk_(it)),
             PatKind::Box(ref s) | PatKind::Ref(ref s, _) => {
                 s.walk_(it)
             }
@@ -976,6 +976,10 @@ pub enum PatKind {
     /// `0 <= position <= subpats.len()`
     TupleStruct(QPath, HirVec<P<Pat>>, Option<usize>),
 
+    /// An or-pattern `A | B | C`.
+    /// Invariant: `pats.len() >= 2`.
+    Or(HirVec<P<Pat>>),
+
     /// A path pattern for an unit struct/variant or a (maybe-associated) constant.
     Path(QPath),
 
@@ -2004,8 +2008,6 @@ pub struct InlineAsm {
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
-    #[stable_hasher(ignore)] // This is used for error reporting
-    pub ctxt: SyntaxContext,
 }
 
 /// Represents an argument in a function header.
@@ -2184,8 +2186,6 @@ pub struct ForeignMod {
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GlobalAsm {
     pub asm: Symbol,
-    #[stable_hasher(ignore)] // This is used for error reporting
-    pub ctxt: SyntaxContext,
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index caf8220bbf4..632a13f9183 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1457,7 +1457,7 @@ impl<'a> State<'a> {
     }
 
     pub fn print_name(&mut self, name: ast::Name) {
-        self.print_ident(ast::Ident::with_empty_ctxt(name))
+        self.print_ident(ast::Ident::with_dummy_span(name))
     }
 
     pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) {
@@ -1687,6 +1687,9 @@ impl<'a> State<'a> {
                 self.s.space();
                 self.s.word("}");
             }
+            PatKind::Or(ref pats) => {
+                self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(&p));
+            }
             PatKind::Tuple(ref elts, ddpos) => {
                 self.popen();
                 if let Some(ddpos) = ddpos {
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index ae7d82c2020..e77faea1e4c 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -350,7 +350,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
         let line_col_len = col | line | len;
         std_hash::Hash::hash(&line_col_len, hasher);
 
-        if span.ctxt == SyntaxContext::empty() {
+        if span.ctxt == SyntaxContext::root() {
             TAG_NO_EXPANSION.hash_stable(hcx, hasher);
         } else {
             TAG_EXPANSION.hash_stable(hcx, hasher);
@@ -370,7 +370,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
                 }
 
                 let mut hasher = StableHasher::new();
-                expn_id.expn_info().hash_stable(hcx, &mut hasher);
+                expn_id.expn_data().hash_stable(hcx, &mut hasher);
                 let sub_hash: Fingerprint = hasher.finish();
                 let sub_hash = sub_hash.to_smaller_hash();
                 cache.borrow_mut().insert(expn_id, sub_hash);
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 5cc8324b316..7003f71c8ba 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -397,9 +397,10 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::Transparency {
     Opaque,
 });
 
-impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnInfo {
-    call_site,
+impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
     kind,
+    parent -> _,
+    call_site,
     def_site,
     default_transparency,
     allow_internal_unstable,
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index dea1cc6601b..be73b305e2c 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -9,7 +9,6 @@ use errors::Applicability;
 use rustc_data_structures::fx::FxHashMap;
 use syntax::ast::{Ident, Item, ItemKind};
 use syntax::symbol::{sym, Symbol};
-use syntax_pos::ExpnInfo;
 
 declare_tool_lint! {
     pub rustc::DEFAULT_HASH_TYPES,
@@ -108,7 +107,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
                             .help("try using `Ty` instead")
                             .emit();
                         } else {
-                            if ty.span.ctxt().outer_expn_info().is_some() {
+                            if ty.span.from_expansion() {
                                 return;
                             }
                             if let Some(t) = is_ty_or_ty_ctxt(cx, ty) {
@@ -228,30 +227,20 @@ impl EarlyLintPass for LintPassImpl {
         if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.node {
             if let Some(last) = lint_pass.path.segments.last() {
                 if last.ident.name == sym::LintPass {
-                    match &lint_pass.path.span.ctxt().outer_expn_info() {
-                        Some(info) if is_lint_pass_expansion(info) => {}
-                        _ => {
-                            cx.struct_span_lint(
-                                LINT_PASS_IMPL_WITHOUT_MACRO,
-                                lint_pass.path.span,
-                                "implementing `LintPass` by hand",
-                            )
-                            .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
-                            .emit();
-                        }
+                    let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
+                    let call_site = expn_data.call_site;
+                    if expn_data.kind.descr() != sym::impl_lint_pass &&
+                       call_site.ctxt().outer_expn_data().kind.descr() != sym::declare_lint_pass {
+                        cx.struct_span_lint(
+                            LINT_PASS_IMPL_WITHOUT_MACRO,
+                            lint_pass.path.span,
+                            "implementing `LintPass` by hand",
+                        )
+                        .help("try using `declare_lint_pass!` or `impl_lint_pass!` instead")
+                        .emit();
                     }
                 }
             }
         }
     }
 }
-
-fn is_lint_pass_expansion(expn_info: &ExpnInfo) -> bool {
-    if expn_info.kind.descr() == sym::impl_lint_pass {
-        true
-    } else if let Some(info) = expn_info.call_site.ctxt().outer_expn_info() {
-        info.kind.descr() == sym::declare_lint_pass
-    } else {
-        false
-    }
-}
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 8cb5b1e26d9..2b58627cdea 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -885,21 +885,16 @@ pub fn provide(providers: &mut Providers<'_>) {
 /// This is used to test whether a lint should not even begin to figure out whether it should
 /// be reported on the current node.
 pub fn in_external_macro(sess: &Session, span: Span) -> bool {
-    let info = match span.ctxt().outer_expn_info() {
-        Some(info) => info,
-        // no ExpnInfo means this span doesn't come from a macro
-        None => return false,
-    };
-
-    match info.kind {
+    let expn_data = span.ctxt().outer_expn_data();
+    match expn_data.kind {
         ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
         ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
-            if info.def_site.is_dummy() {
+            if expn_data.def_site.is_dummy() {
                 // dummy span for the def_site means it's an external macro
                 return true;
             }
-            match sess.source_map().span_to_snippet(info.def_site) {
+            match sess.source_map().span_to_snippet(expn_data.def_site) {
                 Ok(code) => !code.starts_with("macro_rules"),
                 // no snippet = external macro or compiler-builtin expansion
                 Err(_) => true,
@@ -911,10 +906,8 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
 
 /// Returns whether `span` originates in a derive macro's expansion
 pub fn in_derive_expansion(span: Span) -> bool {
-    if let Some(info) = span.ctxt().outer_expn_info() {
-        if let ExpnKind::Macro(MacroKind::Derive, _) = info.kind {
-            return true;
-        }
+    if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_data().kind {
+        return true;
     }
     false
 }
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index d37b2367ae7..de84fcd7160 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -178,8 +178,7 @@ pub trait MetadataLoader {
                           -> Result<MetadataRef, String>;
 }
 
-/// A store of Rust crates, through with their metadata
-/// can be accessed.
+/// A store of Rust crates, through which their metadata can be accessed.
 ///
 /// Note that this trait should probably not be expanding today. All new
 /// functionality should be driven through queries instead!
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index a55803e255b..73ca981bbe8 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -1290,6 +1290,12 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 }
             }
 
+            PatKind::Or(ref pats) => {
+                for pat in pats {
+                    self.cat_pattern_(cmt.clone(), &pat, op)?;
+                }
+            }
+
             PatKind::Binding(.., Some(ref subpat)) => {
                 self.cat_pattern_(cmt, &subpat, op)?;
             }
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index ce04cca96e0..84b4cd91456 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -306,7 +306,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
     ///
     /// zsts can't be read out of two reasons:
     /// * byteorder cannot work with zero element buffers
-    /// * in oder to obtain a `Pointer` we need to check for ZSTness anyway due to integer pointers
+    /// * in order to obtain a `Pointer` we need to check for ZSTness anyway due to integer pointers
     ///   being valid for ZSTs
     ///
     /// It is the caller's responsibility to check bounds and alignment beforehand.
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 1e2ec08301c..11701a66377 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2197,7 +2197,6 @@ impl<'tcx> Operand<'tcx> {
         let ty = tcx.type_of(def_id).subst(tcx, substs);
         Operand::Constant(box Constant {
             span,
-            ty,
             user_ty: None,
             literal: ty::Const::zero_sized(tcx, ty),
         })
@@ -2476,7 +2475,6 @@ impl<'tcx> Debug for Rvalue<'tcx> {
 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Constant<'tcx> {
     pub span: Span,
-    pub ty: Ty<'tcx>,
 
     /// Optional user-given type: for something like
     /// `collect::<Vec<_>>`, this would be present and would
@@ -3385,12 +3383,11 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Constant {
             span: self.span.clone(),
-            ty: self.ty.fold_with(folder),
             user_ty: self.user_ty.fold_with(folder),
             literal: self.literal.fold_with(folder),
         }
     }
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.ty.visit_with(visitor) || self.literal.visit_with(visitor)
+        self.literal.visit_with(visitor)
     }
 }
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index f8889380b2a..e9f7636ba85 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -252,7 +252,7 @@ impl<'tcx> Operand<'tcx> {
         match self {
             &Operand::Copy(ref l) |
             &Operand::Move(ref l) => l.ty(local_decls, tcx).ty,
-            &Operand::Constant(ref c) => c.ty,
+            &Operand::Constant(ref c) => c.literal.ty,
         }
     }
 }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index ee4ecb6762c..2d16e7bcc83 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -782,13 +782,11 @@ macro_rules! make_mir_visitor {
                               location: Location) {
                 let Constant {
                     span,
-                    ty,
                     user_ty,
                     literal,
                 } = constant;
 
                 self.visit_span(span);
-                self.visit_ty(ty, TyContext::Location(location));
                 drop(user_ty); // no visit method for this
                 self.visit_const(literal, location);
             }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 3536b2aa8ff..8e3b910e0da 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -395,7 +395,7 @@ top_level_options!(
         output_types: OutputTypes [TRACKED],
         search_paths: Vec<SearchPath> [UNTRACKED],
         libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
-        maybe_sysroot: Option<PathBuf> [TRACKED],
+        maybe_sysroot: Option<PathBuf> [UNTRACKED],
 
         target_triple: TargetTriple [TRACKED],
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 83bd5c56040..ba92e851141 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -36,7 +36,7 @@ use errors::{Applicability, DiagnosticBuilder};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::sym;
-use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnKind};
+use syntax_pos::{DUMMY_SP, Span, ExpnKind};
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn report_fulfillment_errors(&self,
@@ -61,9 +61,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             // We want to ignore desugarings here: spans are equivalent even
             // if one is the result of a desugaring and the other is not.
             let mut span = error.obligation.cause.span;
-            if let Some(ExpnInfo { kind: ExpnKind::Desugaring(_), def_site, .. })
-                    = span.ctxt().outer_expn_info() {
-                span = def_site;
+            let expn_data = span.ctxt().outer_expn_data();
+            if let ExpnKind::Desugaring(_) = expn_data.kind {
+                span = expn_data.call_site;
             }
 
             error_map.entry(span).or_default().push(
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 38263f26a59..72df45df923 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1417,7 +1417,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
                 projection_ty: ty::ProjectionTy::from_ref_and_name(
                     tcx,
                     trait_ref,
-                    Ident::with_empty_ctxt(FN_OUTPUT_NAME),
+                    Ident::with_dummy_span(FN_OUTPUT_NAME),
                 ),
                 ty: ret_type
             }
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 00871a1cbf2..8bf01970eb5 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -23,16 +23,16 @@ use std::mem;
 use syntax::ast::NodeId;
 use syntax::source_map::{SourceMap, StableSourceFileId};
 use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
-use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnInfo};
+use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData};
 
 const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
 
 const TAG_CLEAR_CROSS_CRATE_CLEAR: u8 = 0;
 const TAG_CLEAR_CROSS_CRATE_SET: u8 = 1;
 
-const TAG_NO_EXPANSION_INFO: u8 = 0;
-const TAG_EXPANSION_INFO_SHORTHAND: u8 = 1;
-const TAG_EXPANSION_INFO_INLINE: u8 = 2;
+const TAG_NO_EXPN_DATA: u8 = 0;
+const TAG_EXPN_DATA_SHORTHAND: u8 = 1;
+const TAG_EXPN_DATA_INLINE: u8 = 2;
 
 const TAG_VALID_SPAN: u8 = 0;
 const TAG_INVALID_SPAN: u8 = 1;
@@ -58,7 +58,7 @@ pub struct OnDiskCache<'sess> {
 
     // These two fields caches that are populated lazily during decoding.
     file_index_to_file: Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
-    synthetic_expansion_infos: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+    synthetic_syntax_contexts: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
 
     // A map from dep-node to the position of the cached query result in
     // `serialized_data`.
@@ -135,7 +135,7 @@ impl<'sess> OnDiskCache<'sess> {
             current_diagnostics: Default::default(),
             query_result_index: footer.query_result_index.into_iter().collect(),
             prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(),
-            synthetic_expansion_infos: Default::default(),
+            synthetic_syntax_contexts: Default::default(),
             alloc_decoding_state: AllocDecodingState::new(footer.interpret_alloc_index),
         }
     }
@@ -151,7 +151,7 @@ impl<'sess> OnDiskCache<'sess> {
             current_diagnostics: Default::default(),
             query_result_index: Default::default(),
             prev_diagnostics_index: Default::default(),
-            synthetic_expansion_infos: Default::default(),
+            synthetic_syntax_contexts: Default::default(),
             alloc_decoding_state: AllocDecodingState::new(Vec::new()),
         }
     }
@@ -185,7 +185,7 @@ impl<'sess> OnDiskCache<'sess> {
                 encoder,
                 type_shorthands: Default::default(),
                 predicate_shorthands: Default::default(),
-                expn_info_shorthands: Default::default(),
+                expn_data_shorthands: Default::default(),
                 interpret_allocs: Default::default(),
                 interpret_allocs_inverse: Vec::new(),
                 source_map: CachingSourceMapView::new(tcx.sess.source_map()),
@@ -383,7 +383,7 @@ impl<'sess> OnDiskCache<'sess> {
             cnum_map: self.cnum_map.get(),
             file_index_to_file: &self.file_index_to_file,
             file_index_to_stable_id: &self.file_index_to_stable_id,
-            synthetic_expansion_infos: &self.synthetic_expansion_infos,
+            synthetic_syntax_contexts: &self.synthetic_syntax_contexts,
             alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
         };
 
@@ -440,7 +440,7 @@ struct CacheDecoder<'a, 'tcx> {
     opaque: opaque::Decoder<'a>,
     source_map: &'a SourceMap,
     cnum_map: &'a IndexVec<CrateNum, Option<CrateNum>>,
-    synthetic_expansion_infos: &'a Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
+    synthetic_syntax_contexts: &'a Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
     file_index_to_file: &'a Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
     file_index_to_stable_id: &'a FxHashMap<SourceFileIndex, StableSourceFileId>,
     alloc_decoding_session: AllocDecodingSession<'a>,
@@ -586,37 +586,37 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
         let lo = file_lo.lines[line_lo - 1] + col_lo;
         let hi = lo + len;
 
-        let expn_info_tag = u8::decode(self)?;
+        let expn_data_tag = u8::decode(self)?;
 
-        // FIXME(mw): This method does not restore `InternalExpnData::parent` or
+        // FIXME(mw): This method does not restore `ExpnData::parent` or
         // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things
         // don't seem to be used after HIR lowering, so everything should be fine
         // as long as incremental compilation does not kick in before that.
-        let location = || Span::new(lo, hi, SyntaxContext::empty());
-        let recover_from_expn_info = |this: &Self, expn_info, pos| {
-            let span = location().fresh_expansion(ExpnId::root(), expn_info);
-            this.synthetic_expansion_infos.borrow_mut().insert(pos, span.ctxt());
+        let location = || Span::with_root_ctxt(lo, hi);
+        let recover_from_expn_data = |this: &Self, expn_data, pos| {
+            let span = location().fresh_expansion(expn_data);
+            this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
             span
         };
-        Ok(match expn_info_tag {
-            TAG_NO_EXPANSION_INFO => {
+        Ok(match expn_data_tag {
+            TAG_NO_EXPN_DATA => {
                 location()
             }
-            TAG_EXPANSION_INFO_INLINE => {
-                let expn_info = Decodable::decode(self)?;
-                recover_from_expn_info(
-                    self, expn_info, AbsoluteBytePos::new(self.opaque.position())
+            TAG_EXPN_DATA_INLINE => {
+                let expn_data = Decodable::decode(self)?;
+                recover_from_expn_data(
+                    self, expn_data, AbsoluteBytePos::new(self.opaque.position())
                 )
             }
-            TAG_EXPANSION_INFO_SHORTHAND => {
+            TAG_EXPN_DATA_SHORTHAND => {
                 let pos = AbsoluteBytePos::decode(self)?;
-                let cached_ctxt = self.synthetic_expansion_infos.borrow().get(&pos).cloned();
+                let cached_ctxt = self.synthetic_syntax_contexts.borrow().get(&pos).cloned();
                 if let Some(ctxt) = cached_ctxt {
                     Span::new(lo, hi, ctxt)
                 } else {
-                    let expn_info =
-                        self.with_position(pos.to_usize(), |this| ExpnInfo::decode(this))?;
-                    recover_from_expn_info(self, expn_info, pos)
+                    let expn_data =
+                        self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?;
+                    recover_from_expn_data(self, expn_data, pos)
                 }
             }
             _ => {
@@ -725,7 +725,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
     encoder: &'a mut E,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
     predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
-    expn_info_shorthands: FxHashMap<ExpnId, AbsoluteBytePos>,
+    expn_data_shorthands: FxHashMap<ExpnId, AbsoluteBytePos>,
     interpret_allocs: FxHashMap<interpret::AllocId, usize>,
     interpret_allocs_inverse: Vec<interpret::AllocId>,
     source_map: CachingSourceMapView<'tcx>,
@@ -816,22 +816,18 @@ where
         col_lo.encode(self)?;
         len.encode(self)?;
 
-        if span_data.ctxt == SyntaxContext::empty() {
-            TAG_NO_EXPANSION_INFO.encode(self)
+        if span_data.ctxt == SyntaxContext::root() {
+            TAG_NO_EXPN_DATA.encode(self)
         } else {
-            let (expn_id, expn_info) = span_data.ctxt.outer_expn_with_info();
-            if let Some(expn_info) = expn_info {
-                if let Some(pos) = self.expn_info_shorthands.get(&expn_id).cloned() {
-                    TAG_EXPANSION_INFO_SHORTHAND.encode(self)?;
-                    pos.encode(self)
-                } else {
-                    TAG_EXPANSION_INFO_INLINE.encode(self)?;
-                    let pos = AbsoluteBytePos::new(self.position());
-                    self.expn_info_shorthands.insert(expn_id, pos);
-                    expn_info.encode(self)
-                }
+            let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data();
+            if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
+                TAG_EXPN_DATA_SHORTHAND.encode(self)?;
+                pos.encode(self)
             } else {
-                TAG_NO_EXPANSION_INFO.encode(self)
+                TAG_EXPN_DATA_INLINE.encode(self)?;
+                let pos = AbsoluteBytePos::new(self.position());
+                self.expn_data_shorthands.insert(expn_id, pos);
+                expn_data.encode(self)
             }
         }
     }
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs
index 9763d523a2a..b68ee2cb44d 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/src/librustc_codegen_llvm/asm.rs
@@ -6,9 +6,9 @@ use crate::value::Value;
 
 use rustc::hir;
 use rustc_codegen_ssa::traits::*;
-
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::mir::operand::OperandValue;
+use syntax_pos::Span;
 
 use std::ffi::{CStr, CString};
 use libc::{c_uint, c_char};
@@ -19,7 +19,8 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         &mut self,
         ia: &hir::InlineAsm,
         outputs: Vec<PlaceRef<'tcx, &'ll Value>>,
-        mut inputs: Vec<&'ll Value>
+        mut inputs: Vec<&'ll Value>,
+        span: Span,
     ) -> bool {
         let mut ext_constraints = vec![];
         let mut output_types = vec![];
@@ -102,7 +103,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
             let kind = llvm::LLVMGetMDKindIDInContext(self.llcx,
                 key.as_ptr() as *const c_char, key.len() as c_uint);
 
-            let val: &'ll Value = self.const_i32(ia.ctxt.outer_expn().as_u32() as i32);
+            let val: &'ll Value = self.const_i32(span.ctxt().outer_expn().as_u32() as i32);
 
             llvm::LLVMSetMetadata(r, kind,
                 llvm::LLVMMDNodeInContext(self.llcx, &val, 1));
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index a9b8962f45b..9483ffca448 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -328,7 +328,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
             },
             "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
             "bitreverse" | "add_with_overflow" | "sub_with_overflow" |
-            "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
+            "mul_with_overflow" | "wrapping_add" | "wrapping_sub" | "wrapping_mul" |
             "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" |
             "unchecked_add" | "unchecked_sub" | "unchecked_mul" | "exact_div" |
             "rotate_left" | "rotate_right" | "saturating_add" | "saturating_sub" => {
@@ -398,9 +398,9 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
 
                                 return;
                             },
-                            "overflowing_add" => self.add(args[0].immediate(), args[1].immediate()),
-                            "overflowing_sub" => self.sub(args[0].immediate(), args[1].immediate()),
-                            "overflowing_mul" => self.mul(args[0].immediate(), args[1].immediate()),
+                            "wrapping_add" => self.add(args[0].immediate(), args[1].immediate()),
+                            "wrapping_sub" => self.sub(args[0].immediate(), args[1].immediate()),
+                            "wrapping_mul" => self.mul(args[0].immediate(), args[1].immediate()),
                             "exact_div" =>
                                 if signed {
                                     self.exactsdiv(args[0].immediate(), args[1].immediate())
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index c9e4663fdbd..eec09842623 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -1775,10 +1775,7 @@ impl SharedEmitterMain {
                     }
                 }
                 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => {
-                    match ExpnId::from_u32(cookie).expn_info() {
-                        Some(ei) => sess.span_err(ei.call_site, &msg),
-                        None     => sess.err(&msg),
-                    }
+                    sess.span_err(ExpnId::from_u32(cookie).expn_data().call_site, &msg)
                 }
                 Ok(SharedEmitterMessage::AbortIfErrors) => {
                     sess.abort_if_errors();
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index cc0c733c224..e63f1b91dd7 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -221,7 +221,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
             mir::TerminatorKind::Call {
                 func: mir::Operand::Constant(ref c),
                 ref args, ..
-            } => match c.ty.sty {
+            } => match c.literal.ty.sty {
                 ty::FnDef(did, _) => Some((did, args)),
                 _ => None,
             },
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index ce98979cc0c..dbce5ce4896 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -651,7 +651,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             let (llval, ty) = self.simd_shuffle_indices(
                                 &bx,
                                 constant.span,
-                                constant.ty,
+                                constant.literal.ty,
                                 c,
                             );
                             return OperandRef {
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index e7517d69991..32bcdebc1c4 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -8,7 +8,7 @@ use crate::base;
 use crate::debuginfo::{self, VariableAccess, VariableKind, FunctionDebugContext};
 use crate::traits::*;
 
-use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
+use syntax_pos::{DUMMY_SP, BytePos, Span};
 use syntax::symbol::kw;
 
 use std::iter;
@@ -120,7 +120,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         // In order to have a good line stepping behavior in debugger, we overwrite debug
         // locations of macro expansions with that of the outermost expansion site
         // (unless the crate is being compiled with `-Z debug-macros`).
-        if source_info.span.ctxt() == NO_EXPANSION ||
+        if !source_info.span.from_expansion() ||
            self.cx.sess().opts.debugging_opts.debug_macros {
             let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo());
             (scope, source_info.span)
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 5e5804b7265..254b73da442 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -466,7 +466,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             mir::Operand::Constant(ref constant) => {
-                let ty = self.monomorphize(&constant.ty);
                 self.eval_mir_constant(constant)
                     .map(|c| OperandRef::from_const(bx, c))
                     .unwrap_or_else(|err| {
@@ -481,6 +480,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         // the above error (or silence it under some conditions) will not cause UB
                         bx.abort();
                         // We've errored, so we don't have to produce working code.
+                        let ty = self.monomorphize(&constant.literal.ty);
                         let layout = bx.cx().layout_of(ty);
                         bx.load_operand(PlaceRef::new_sized(
                             bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 3717be4b417..3617f3afaae 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -89,7 +89,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 });
 
                 if input_vals.len() == asm.inputs.len() {
-                    let res = bx.codegen_inline_asm(&asm.asm, outputs, input_vals);
+                    let res = bx.codegen_inline_asm(
+                        &asm.asm,
+                        outputs,
+                        input_vals,
+                        statement.source_info.span,
+                    );
                     if !res {
                         span_err!(bx.sess(), statement.source_info.span, E0668,
                                   "malformed inline assembly");
diff --git a/src/librustc_codegen_ssa/traits/asm.rs b/src/librustc_codegen_ssa/traits/asm.rs
index fd3c868bbc5..c9e1ed86e97 100644
--- a/src/librustc_codegen_ssa/traits/asm.rs
+++ b/src/librustc_codegen_ssa/traits/asm.rs
@@ -1,6 +1,7 @@
 use super::BackendTypes;
 use crate::mir::place::PlaceRef;
 use rustc::hir::{GlobalAsm, InlineAsm};
+use syntax_pos::Span;
 
 pub trait AsmBuilderMethods<'tcx>: BackendTypes {
     /// Take an inline assembly expression and splat it out via LLVM
@@ -9,6 +10,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
         ia: &InlineAsm,
         outputs: Vec<PlaceRef<'tcx, Self::Value>>,
         inputs: Vec<Self::Value>,
+        span: Span,
     ) -> bool;
 }
 
diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml
index d93589ea84b..89b50c5dacc 100644
--- a/src/librustc_codegen_utils/Cargo.toml
+++ b/src/librustc_codegen_utils/Cargo.toml
@@ -13,7 +13,7 @@ test = false
 flate2 = "1.0"
 log = "0.4"
 punycode = "0.4.0"
-rustc-demangle = "0.1.15"
+rustc-demangle = "0.1.16"
 
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs
index 47601da8b7b..8d6a1d757e0 100644
--- a/src/librustc_codegen_utils/symbol_names/v0.rs
+++ b/src/librustc_codegen_utils/symbol_names/v0.rs
@@ -198,10 +198,14 @@ impl SymbolMangler<'tcx> {
 
         let lifetimes = regions.into_iter().map(|br| {
             match br {
-                ty::BrAnon(i) => i + 1,
+                ty::BrAnon(i) => {
+                    // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
+                    assert_ne!(i, 0);
+                    i - 1
+                },
                 _ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value),
             }
-        }).max().unwrap_or(0);
+        }).max().map_or(0, |max| max + 1);
 
         self.push_opt_integer_62("G", lifetimes as u64);
         lifetime_depths.end += lifetimes;
@@ -297,6 +301,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
             // Late-bound lifetimes use indices starting at 1,
             // see `BinderLevel` for more details.
             ty::ReLateBound(debruijn, ty::BrAnon(i)) => {
+                // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
+                assert_ne!(i, 0);
+                let i = i - 1;
+
                 let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
                 let depth = binder.lifetime_depths.start + i;
 
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index e9d85a53d1e..fdd0773b73a 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -678,7 +678,7 @@ impl RustcDefaultCalls {
 
                     let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
                         let gated_cfg = GatedCfg::gate(&ast::MetaItem {
-                            path: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
+                            path: ast::Path::from_ident(ast::Ident::with_dummy_span(name)),
                             node: ast::MetaItemKind::Word,
                             span: DUMMY_SP,
                         });
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index f3e524152ff..4018a667bf2 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -43,8 +43,7 @@ use syntax_pos::{BytePos,
                  SourceFile,
                  FileName,
                  MultiSpan,
-                 Span,
-                 NO_EXPANSION};
+                 Span};
 
 /// Indicates the confidence in the correctness of a suggestion.
 ///
@@ -189,7 +188,7 @@ impl CodeSuggestion {
             // Find the bounding span.
             let lo = substitution.parts.iter().map(|part| part.span.lo()).min().unwrap();
             let hi = substitution.parts.iter().map(|part| part.span.hi()).min().unwrap();
-            let bounding_span = Span::new(lo, hi, NO_EXPANSION);
+            let bounding_span = Span::with_root_ctxt(lo, hi);
             let lines = cm.span_to_lines(bounding_span).unwrap();
             assert!(!lines.lines.is_empty());
 
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index c02abe6b89f..afef307a0ed 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -352,7 +352,6 @@ impl Cursor<'_> {
         loop {
             match self.nth_char(0) {
                 '\n' => break,
-                '\r' if self.nth_char(1) == '\n' => break,
                 EOF_CHAR if self.is_eof() => break,
                 _ => {
                     self.bump();
@@ -525,7 +524,6 @@ impl Cursor<'_> {
             match self.nth_char(0) {
                 '/' if !first => break,
                 '\n' if self.nth_char(1) != '\'' => break,
-                '\r' if self.nth_char(1) == '\n' => break,
                 EOF_CHAR if self.is_eof() => break,
                 '\'' => {
                     self.bump();
diff --git a/src/librustc_lexer/src/unescape.rs b/src/librustc_lexer/src/unescape.rs
index d8e00d4c7c5..c709b752608 100644
--- a/src/librustc_lexer/src/unescape.rs
+++ b/src/librustc_lexer/src/unescape.rs
@@ -128,11 +128,7 @@ fn scan_escape(first_char: char, chars: &mut Chars<'_>, mode: Mode) -> Result<ch
     if first_char != '\\' {
         return match first_char {
             '\t' | '\n' => Err(EscapeError::EscapeOnlyChar),
-            '\r' => Err(if chars.clone().next() == Some('\n') {
-                EscapeError::EscapeOnlyChar
-            } else {
-                EscapeError::BareCarriageReturn
-            }),
+            '\r' => Err(EscapeError::BareCarriageReturn),
             '\'' if mode.in_single_quotes() => Err(EscapeError::EscapeOnlyChar),
             '"' if mode.in_double_quotes() => Err(EscapeError::EscapeOnlyChar),
             _ => {
@@ -244,27 +240,15 @@ where
 
         let unescaped_char = match first_char {
             '\\' => {
-                let (second_char, third_char) = {
-                    let mut chars = chars.clone();
-                    (chars.next(), chars.next())
-                };
-                match (second_char, third_char) {
-                    (Some('\n'), _) | (Some('\r'), Some('\n')) => {
+                let second_char = chars.clone().next();
+                match second_char {
+                    Some('\n') => {
                         skip_ascii_whitespace(&mut chars);
                         continue;
                     }
                     _ => scan_escape(first_char, &mut chars, mode),
                 }
             }
-            '\r' => {
-                let second_char = chars.clone().next();
-                if second_char == Some('\n') {
-                    chars.next();
-                    Ok('\n')
-                } else {
-                    scan_escape(first_char, &mut chars, mode)
-                }
-            }
             '\n' => Ok('\n'),
             '\t' => Ok('\t'),
             _ => scan_escape(first_char, &mut chars, mode),
@@ -298,15 +282,11 @@ where
     while let Some(curr) = chars.next() {
         let start = initial_len - chars.as_str().len() - curr.len_utf8();
 
-        let result = match (curr, chars.clone().next()) {
-            ('\r', Some('\n')) => {
-                chars.next();
-                Ok('\n')
-            },
-            ('\r', _) => Err(EscapeError::BareCarriageReturnInRawString),
-            (c, _) if mode.is_bytes() && !c.is_ascii() =>
+        let result = match curr {
+            '\r' => Err(EscapeError::BareCarriageReturnInRawString),
+            c if mode.is_bytes() && !c.is_ascii() =>
                 Err(EscapeError::NonAsciiCharInByteString),
-            (c, _) => Ok(c),
+            c => Ok(c),
         };
         let end = initial_len - chars.as_str().len();
 
diff --git a/src/librustc_lexer/src/unescape/tests.rs b/src/librustc_lexer/src/unescape/tests.rs
index 496527eb265..e7b1ff6479d 100644
--- a/src/librustc_lexer/src/unescape/tests.rs
+++ b/src/librustc_lexer/src/unescape/tests.rs
@@ -11,7 +11,6 @@ fn test_unescape_char_bad() {
     check(r"\", EscapeError::LoneSlash);
 
     check("\n", EscapeError::EscapeOnlyChar);
-    check("\r\n", EscapeError::EscapeOnlyChar);
     check("\t", EscapeError::EscapeOnlyChar);
     check("'", EscapeError::EscapeOnlyChar);
     check("\r", EscapeError::BareCarriageReturn);
@@ -31,6 +30,7 @@ fn test_unescape_char_bad() {
     check(r"\v", EscapeError::InvalidEscape);
     check(r"\💩", EscapeError::InvalidEscape);
     check(r"\●", EscapeError::InvalidEscape);
+    check("\\\r", EscapeError::InvalidEscape);
 
     check(r"\x", EscapeError::TooShortHexEscape);
     check(r"\x0", EscapeError::TooShortHexEscape);
@@ -116,10 +116,9 @@ fn test_unescape_str_good() {
 
     check("foo", "foo");
     check("", "");
-    check(" \t\n\r\n", " \t\n\n");
+    check(" \t\n", " \t\n");
 
     check("hello \\\n     world", "hello world");
-    check("hello \\\r\n     world", "hello world");
     check("thread's", "thread's")
 }
 
@@ -134,7 +133,6 @@ fn test_unescape_byte_bad() {
     check(r"\", EscapeError::LoneSlash);
 
     check("\n", EscapeError::EscapeOnlyChar);
-    check("\r\n", EscapeError::EscapeOnlyChar);
     check("\t", EscapeError::EscapeOnlyChar);
     check("'", EscapeError::EscapeOnlyChar);
     check("\r", EscapeError::BareCarriageReturn);
@@ -238,10 +236,9 @@ fn test_unescape_byte_str_good() {
 
     check("foo", b"foo");
     check("", b"");
-    check(" \t\n\r\n", b" \t\n\n");
+    check(" \t\n", b" \t\n");
 
     check("hello \\\n     world", b"hello world");
-    check("hello \\\r\n     world", b"hello world");
     check("thread's", b"thread's")
 }
 
@@ -253,7 +250,6 @@ fn test_unescape_raw_str() {
         assert_eq!(unescaped, expected);
     }
 
-    check("\r\n", &[(0..2, Ok('\n'))]);
     check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]);
     check("\rx", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString)), (1..2, Ok('x'))]);
 }
@@ -266,7 +262,6 @@ fn test_unescape_raw_byte_str() {
         assert_eq!(unescaped, expected);
     }
 
-    check("\r\n", &[(0..2, Ok(byte_from_char('\n')))]);
     check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]);
     check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByteString))]);
     check(
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 47b4e7c9487..ce7681c974a 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -42,7 +42,7 @@ use syntax::source_map::Spanned;
 use syntax::edition::Edition;
 use syntax::feature_gate::{self, AttributeGate, AttributeType};
 use syntax::feature_gate::{Stability, deprecated_attributes};
-use syntax_pos::{BytePos, Span, SyntaxContext};
+use syntax_pos::{BytePos, Span};
 use syntax::symbol::{Symbol, kw, sym};
 use syntax::errors::{Applicability, DiagnosticBuilder};
 use syntax::print::pprust::expr_to_string;
@@ -78,7 +78,7 @@ impl EarlyLintPass for WhileTrue {
         if let ast::ExprKind::While(cond, ..) = &e.node {
             if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node {
                 if let ast::LitKind::Bool(true) = lit.node {
-                    if lit.span.ctxt() == SyntaxContext::empty() {
+                    if !lit.span.from_expansion() {
                         let msg = "denote infinite loops with `loop { ... }`";
                         let condition_span = cx.sess.source_map().def_span(e.span);
                         cx.struct_span_lint(WHILE_TRUE, condition_span, msg)
@@ -167,7 +167,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns {
                 if fieldpat.is_shorthand {
                     continue;
                 }
-                if fieldpat.span.ctxt().outer_expn_info().is_some() {
+                if fieldpat.span.from_expansion() {
                     // Don't lint if this is a macro expansion: macro authors
                     // shouldn't have to worry about this kind of style issue
                     // (Issue #49588)
@@ -1012,7 +1012,7 @@ impl UnreachablePub {
         let mut applicability = Applicability::MachineApplicable;
         match vis.node {
             hir::VisibilityKind::Public if !cx.access_levels.is_reachable(id) => {
-                if span.ctxt().outer_expn_info().is_some() {
+                if span.from_expansion() {
                     applicability = Applicability::MaybeIncorrect;
                 }
                 let def_span = cx.tcx.sess.source_map().def_span(span);
@@ -1876,16 +1876,70 @@ declare_lint_pass!(InvalidValue => [INVALID_VALUE]);
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &hir::Expr) {
 
-        const ZEROED_PATH: &[Symbol] = &[sym::core, sym::mem, sym::zeroed];
-        const UININIT_PATH: &[Symbol] = &[sym::core, sym::mem, sym::uninitialized];
+        #[derive(Debug, Copy, Clone, PartialEq)]
+        enum InitKind { Zeroed, Uninit };
 
         /// Information about why a type cannot be initialized this way.
         /// Contains an error message and optionally a span to point at.
         type InitError = (String, Option<Span>);
 
+        /// Test if this constant is all-0.
+        fn is_zero(expr: &hir::Expr) -> bool {
+            use hir::ExprKind::*;
+            use syntax::ast::LitKind::*;
+            match &expr.node {
+                Lit(lit) =>
+                    if let Int(i, _) = lit.node {
+                        i == 0
+                    } else {
+                        false
+                    },
+                Tup(tup) =>
+                    tup.iter().all(is_zero),
+                _ =>
+                    false
+            }
+        }
+
+        /// Determine if this expression is a "dangerous initialization".
+        fn is_dangerous_init(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> Option<InitKind> {
+            const ZEROED_PATH: &[Symbol] = &[sym::core, sym::mem, sym::zeroed];
+            const UININIT_PATH: &[Symbol] = &[sym::core, sym::mem, sym::uninitialized];
+            // `transmute` is inside an anonymous module (the `extern` block?);
+            // `Invalid` represents the empty string and matches that.
+            const TRANSMUTE_PATH: &[Symbol] =
+                &[sym::core, sym::intrinsics, kw::Invalid, sym::transmute];
+
+            if let hir::ExprKind::Call(ref path_expr, ref args) = expr.node {
+                if let hir::ExprKind::Path(ref qpath) = path_expr.node {
+                    let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
+
+                    if cx.match_def_path(def_id, ZEROED_PATH) {
+                        return Some(InitKind::Zeroed);
+                    }
+                    if cx.match_def_path(def_id, UININIT_PATH) {
+                        return Some(InitKind::Uninit);
+                    }
+                    if cx.match_def_path(def_id, TRANSMUTE_PATH) {
+                        if is_zero(&args[0]) {
+                            return Some(InitKind::Zeroed);
+                        }
+                    }
+                    // FIXME: Also detect `MaybeUninit::zeroed().assume_init()` and
+                    // `MaybeUninit::uninit().assume_init()`.
+                }
+            }
+
+            None
+        }
+
         /// Return `Some` only if we are sure this type does *not*
         /// allow zero initialization.
-        fn ty_find_init_error<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<InitError> {
+        fn ty_find_init_error<'tcx>(
+            tcx: TyCtxt<'tcx>,
+            ty: Ty<'tcx>,
+            init: InitKind,
+        ) -> Option<InitError> {
             use rustc::ty::TyKind::*;
             match ty.sty {
                 // Primitive types that don't like 0 as a value.
@@ -1893,8 +1947,30 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                 Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)),
                 FnPtr(..) => Some((format!("Function pointers must be non-null"), None)),
                 Never => Some((format!("The never type (`!`) has no valid value"), None)),
-                // Recurse for some compound types.
+                // Primitive types with other constraints.
+                Bool if init == InitKind::Uninit =>
+                    Some((format!("Booleans must be `true` or `false`"), None)),
+                Char if init == InitKind::Uninit =>
+                    Some((format!("Characters must be a valid unicode codepoint"), None)),
+                // Recurse and checks for some compound types.
                 Adt(adt_def, substs) if !adt_def.is_union() => {
+                    // First check f this ADT has a layout attribute (like `NonNull` and friends).
+                    use std::ops::Bound;
+                    match tcx.layout_scalar_valid_range(adt_def.did) {
+                        // We exploit here that `layout_scalar_valid_range` will never
+                        // return `Bound::Excluded`.  (And we have tests checking that we
+                        // handle the attribute correctly.)
+                        (Bound::Included(lo), _) if lo > 0 =>
+                            return Some((format!("{} must be non-null", ty), None)),
+                        (Bound::Included(_), _) | (_, Bound::Included(_))
+                        if init == InitKind::Uninit =>
+                            return Some((
+                                format!("{} must be initialized inside its custom valid range", ty),
+                                None,
+                            )),
+                        _ => {}
+                    }
+                    // Now, recurse.
                     match adt_def.variants.len() {
                         0 => Some((format!("0-variant enums have no valid value"), None)),
                         1 => {
@@ -1905,6 +1981,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                                 ty_find_init_error(
                                     tcx,
                                     field.ty(tcx, substs),
+                                    init,
                                 ).map(|(mut msg, span)| if span.is_none() {
                                     // Point to this field, should be helpful for figuring
                                     // out where the source of the error is.
@@ -1918,57 +1995,48 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                                 })
                             })
                         }
+                        // Multi-variant enums are tricky: if all but one variant are
+                        // uninhabited, we might actually do layout like for a single-variant
+                        // enum, and then even leaving them uninitialized could be okay.
                         _ => None, // Conservative fallback for multi-variant enum.
                     }
                 }
                 Tuple(..) => {
                     // Proceed recursively, check all fields.
-                    ty.tuple_fields().find_map(|field| ty_find_init_error(tcx, field))
+                    ty.tuple_fields().find_map(|field| ty_find_init_error(tcx, field, init))
                 }
-                // FIXME: Would be nice to also warn for `NonNull`/`NonZero*`.
-                // FIXME: *Only for `mem::uninitialized`*, we could also warn for `bool`,
-                //        `char`, and any multivariant enum.
                 // Conservative fallback.
                 _ => None,
             }
         }
 
-        if let hir::ExprKind::Call(ref path_expr, ref _args) = expr.node {
-            if let hir::ExprKind::Path(ref qpath) = path_expr.node {
-                if let Some(def_id) = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id() {
-                    if cx.match_def_path(def_id, &ZEROED_PATH) ||
-                        cx.match_def_path(def_id, &UININIT_PATH)
-                    {
-                        // This conjures an instance of a type out of nothing,
-                        // using zeroed or uninitialized memory.
-                        // We are extremely conservative with what we warn about.
-                        let conjured_ty = cx.tables.expr_ty(expr);
-                        if let Some((msg, span)) = ty_find_init_error(cx.tcx, conjured_ty) {
-                            let mut err = cx.struct_span_lint(
-                                INVALID_VALUE,
-                                expr.span,
-                                &format!(
-                                    "the type `{}` does not permit {}",
-                                    conjured_ty,
-                                    if cx.match_def_path(def_id, &ZEROED_PATH) {
-                                        "zero-initialization"
-                                    } else {
-                                        "being left uninitialized"
-                                    }
-                                ),
-                            );
-                            err.span_label(expr.span,
-                                "this code causes undefined behavior when executed");
-                            err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
-                            if let Some(span) = span {
-                                err.span_note(span, &msg);
-                            } else {
-                                err.note(&msg);
-                            }
-                            err.emit();
-                        }
-                    }
+        if let Some(init) = is_dangerous_init(cx, expr) {
+            // This conjures an instance of a type out of nothing,
+            // using zeroed or uninitialized memory.
+            // We are extremely conservative with what we warn about.
+            let conjured_ty = cx.tables.expr_ty(expr);
+            if let Some((msg, span)) = ty_find_init_error(cx.tcx, conjured_ty, init) {
+                let mut err = cx.struct_span_lint(
+                    INVALID_VALUE,
+                    expr.span,
+                    &format!(
+                        "the type `{}` does not permit {}",
+                        conjured_ty,
+                        match init {
+                            InitKind::Zeroed => "zero-initialization",
+                            InitKind::Uninit => "being left uninitialized",
+                        },
+                    ),
+                );
+                err.span_label(expr.span,
+                    "this code causes undefined behavior when executed");
+                err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
+                if let Some(span) = span {
+                    err.span_note(span, &msg);
+                } else {
+                    err.note(&msg);
                 }
+                err.emit();
             }
         }
     }
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 6a3dfdbe316..90e46771396 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -517,9 +517,8 @@ impl EarlyLintPass for UnusedParens {
                 // trigger in situations that macro authors shouldn't have to care about, e.g.,
                 // when a parenthesized token tree matched in one macro expansion is matched as
                 // an expression in another and used as a fn/method argument (Issue #47775)
-                if e.span.ctxt().outer_expn_info()
-                    .map_or(false, |info| info.call_site.ctxt().outer_expn_info().is_some()) {
-                        return;
+                if e.span.ctxt().outer_expn_data().call_site.from_expansion() {
+                    return;
                 }
                 let msg = format!("{} argument", call_kind);
                 for arg in args_to_check {
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 16cdbb7dd4d..40ddd651642 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -151,6 +151,10 @@ fn main() {
         cfg.define("LLVM_RUSTLLVM", None);
     }
 
+    if env::var_os("LLVM_NDEBUG").is_some() {
+        cfg.define("NDEBUG", None);
+    }
+
     build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm"));
     cfg.file("../rustllvm/PassWrapper.cpp")
        .file("../rustllvm/RustWrapper.cpp")
@@ -250,8 +254,11 @@ fn main() {
     let llvm_use_libcxx = env::var_os("LLVM_USE_LIBCXX");
 
     let stdcppname = if target.contains("openbsd") {
-        // llvm-config on OpenBSD doesn't mention stdlib=libc++
-        "c++"
+        if target.contains("sparc64") {
+            "estdc++"
+        } else {
+            "c++"
+        }
     } else if target.contains("freebsd") {
         "c++"
     } else if target.contains("darwin") {
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index d5f1e715186..af41b6a4c85 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -2,8 +2,7 @@
 
 use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
 use crate::locator::{self, CratePaths};
-use crate::decoder::proc_macro_def_path_table;
-use crate::schema::CrateRoot;
+use crate::schema::{CrateRoot};
 use rustc_data_structures::sync::{Lrc, RwLock, Lock};
 
 use rustc::hir::def_id::CrateNum;
@@ -26,11 +25,11 @@ use std::{cmp, fs};
 use syntax::ast;
 use syntax::attr;
 use syntax::ext::allocator::{global_allocator_spans, AllocatorKind};
-use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
 use syntax::symbol::{Symbol, sym};
 use syntax::{span_err, span_fatal};
 use syntax_pos::{Span, DUMMY_SP};
 use log::{debug, info, log_enabled};
+use proc_macro::bridge::client::ProcMacro;
 
 pub struct Library {
     pub dylib: Option<(PathBuf, PathKind)>,
@@ -230,24 +229,13 @@ impl<'a> CrateLoader<'a> {
 
         let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
 
-        let proc_macros = crate_root.proc_macro_decls_static.map(|_| {
+        let raw_proc_macros =  crate_root.proc_macro_data.map(|_| {
             if self.sess.opts.debugging_opts.dual_proc_macros {
-                let host_lib = host_lib.unwrap();
-                self.load_derive_macros(
-                    &host_lib.metadata.get_root(),
-                    host_lib.dylib.map(|p| p.0),
-                    span
-                )
+                let host_lib = host_lib.as_ref().unwrap();
+                self.dlsym_proc_macros(host_lib.dylib.as_ref().map(|p| p.0.clone()),
+                                       &host_lib.metadata.get_root(), span)
             } else {
-                self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
-            }
-        });
-
-        let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
-            if let Some(proc_macros) = &proc_macros {
-                proc_macro_def_path_table(&crate_root, proc_macros)
-            } else {
-                crate_root.def_path_table.decode((&metadata, self.sess))
+                self.dlsym_proc_macros(dylib.clone().map(|p| p.0), &crate_root, span)
             }
         });
 
@@ -260,13 +248,16 @@ impl<'a> CrateLoader<'a> {
             .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
             .collect();
 
+        let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
+            crate_root.def_path_table.decode((&metadata, self.sess))
+        });
+
         let cmeta = cstore::CrateMetadata {
             name: crate_root.name,
             imported_name: ident,
             extern_crate: Lock::new(None),
             def_path_table: Lrc::new(def_path_table),
             trait_impls,
-            proc_macros,
             root: crate_root,
             blob: metadata,
             cnum_map,
@@ -280,7 +271,10 @@ impl<'a> CrateLoader<'a> {
                 rlib,
                 rmeta,
             },
-            private_dep
+            private_dep,
+            span,
+            host_lib,
+            raw_proc_macros
         };
 
         let cmeta = Lrc::new(cmeta);
@@ -389,7 +383,7 @@ impl<'a> CrateLoader<'a> {
         match result {
             (LoadResult::Previous(cnum), None) => {
                 let data = self.cstore.get_crate_data(cnum);
-                if data.root.proc_macro_decls_static.is_some() {
+                if data.root.proc_macro_data.is_some() {
                     dep_kind = DepKind::UnexportedMacrosOnly;
                 }
                 data.dep_kind.with_lock(|data_dep_kind| {
@@ -482,7 +476,7 @@ impl<'a> CrateLoader<'a> {
                           dep_kind: DepKind)
                           -> cstore::CrateNumMap {
         debug!("resolving deps of external crate");
-        if crate_root.proc_macro_decls_static.is_some() {
+        if crate_root.proc_macro_data.is_some() {
             return cstore::CrateNumMap::new();
         }
 
@@ -574,19 +568,13 @@ impl<'a> CrateLoader<'a> {
         }
     }
 
-    /// Loads custom derive macros.
-    ///
-    /// Note that this is intentionally similar to how we load plugins today,
-    /// but also intentionally separate. Plugins are likely always going to be
-    /// implemented as dynamic libraries, but we have a possible future where
-    /// custom derive (and other macro-1.1 style features) are implemented via
-    /// executables and custom IPC.
-    fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, span: Span)
-                          -> Vec<(ast::Name, Lrc<SyntaxExtension>)> {
-        use std::{env, mem};
+    fn dlsym_proc_macros(&self,
+                         dylib: Option<PathBuf>,
+                         root: &CrateRoot<'_>,
+                         span: Span
+    ) -> &'static [ProcMacro] {
+        use std::env;
         use crate::dynamic_lib::DynamicLibrary;
-        use proc_macro::bridge::client::ProcMacro;
-        use syntax::ext::proc_macro::{BangProcMacro, AttrProcMacro, ProcMacroDerive};
 
         let path = match dylib {
             Some(dylib) => dylib,
@@ -608,38 +596,11 @@ impl<'a> CrateLoader<'a> {
             *(sym as *const &[ProcMacro])
         };
 
-        let extensions = decls.iter().map(|&decl| {
-            let (name, kind, helper_attrs) = match decl {
-                ProcMacro::CustomDerive { trait_name, attributes, client } => {
-                    let helper_attrs =
-                        attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
-                    (
-                        trait_name,
-                        SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
-                            client, attrs: helper_attrs.clone()
-                        })),
-                        helper_attrs,
-                    )
-                }
-                ProcMacro::Attr { name, client } => (
-                    name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()
-                ),
-                ProcMacro::Bang { name, client } => (
-                    name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
-                )
-            };
-
-            (Symbol::intern(name), Lrc::new(SyntaxExtension {
-                helper_attrs,
-                ..SyntaxExtension::default(kind, root.edition)
-            }))
-        }).collect();
-
         // Intentionally leak the dynamic library. We can't ever unload it
         // since the library can make things that will live arbitrarily long.
-        mem::forget(lib);
+        std::mem::forget(lib);
 
-        extensions
+        decls
     }
 
     /// Look for a plugin registrar. Returns library path, crate
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 5d8fabc7e69..792922a1837 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -28,6 +28,9 @@ pub use crate::cstore_impl::{provide, provide_extern};
 pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
 
 pub use rustc_data_structures::sync::MetadataRef;
+use crate::creader::Library;
+use syntax_pos::Span;
+use proc_macro::bridge::client::ProcMacro;
 
 pub struct MetadataBlob(pub MetadataRef);
 
@@ -70,7 +73,7 @@ pub struct CrateMetadata {
     // whichever `TyCtxt` is being used to decode those values.
     pub root: schema::CrateRoot<'static>,
 
-    /// For each public item in this crate, we encode a key. When the
+    /// For each definition in this crate, we encode a key. When the
     /// crate is loaded, we read all the keys and put them in this
     /// hashmap, which gives the reverse mapping. This allows us to
     /// quickly retrace a `DefPath`, which is needed for incremental
@@ -82,11 +85,19 @@ pub struct CrateMetadata {
     pub dep_kind: Lock<DepKind>,
     pub source: CrateSource,
 
-    pub proc_macros: Option<Vec<(ast::Name, Lrc<SyntaxExtension>)>>,
-
     /// Whether or not this crate should be consider a private dependency
     /// for purposes of the 'exported_private_dependencies' lint
-    pub private_dep: bool
+    pub private_dep: bool,
+
+    pub host_lib: Option<Library>,
+    pub span: Span,
+
+    pub raw_proc_macros: Option<&'static [ProcMacro]>,
+}
+
+pub struct FullProcMacro {
+    pub name: ast::Name,
+    pub ext: Lrc<SyntaxExtension>
 }
 
 pub struct CStore {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index ee1175e798d..a66da32fa4d 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -35,7 +35,7 @@ use syntax::ext::proc_macro::BangProcMacro;
 use syntax::parse::source_file_to_stream;
 use syntax::parse::parser::emit_unclosed_delims;
 use syntax::symbol::{Symbol, sym};
-use syntax_pos::{Span, NO_EXPANSION, FileName};
+use syntax_pos::{Span, FileName};
 use rustc_data_structures::bit_set::BitSet;
 
 macro_rules! provide {
@@ -426,8 +426,8 @@ impl cstore::CStore {
 
     pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         let data = self.get_crate_data(id.krate);
-        if let Some(ref proc_macros) = data.proc_macros {
-            return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
+        if data.is_proc_macro_crate() {
+            return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext);
         } else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote {
             let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
             let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }));
@@ -439,11 +439,12 @@ impl cstore::CStore {
         }
 
         let def = data.get_macro(id.index);
-        let macro_full_name = data.def_path(id.index).to_string_friendly(|_| data.imported_name);
+        let macro_full_name = data.def_path(id.index)
+            .to_string_friendly(|_| data.imported_name);
         let source_name = FileName::Macros(macro_full_name);
 
         let source_file = sess.parse_sess.source_map().new_source_file(source_name, def.body);
-        let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION);
+        let local_span = Span::with_root_ctxt(source_file.start_pos, source_file.end_pos);
         let (body, mut errors) = source_file_to_stream(&sess.parse_sess, source_file, None);
         emit_unclosed_delims(&mut errors, &sess.diagnostic());
 
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 935187dd066..d29592a5d68 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1,16 +1,15 @@
 // Decoding metadata from a single crate's metadata
 
-use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
+use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro};
 use crate::schema::*;
 
 use rustc_data_structures::sync::{Lrc, ReadGuard};
-use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, Definitions};
+use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc::hir;
 use rustc::middle::cstore::LinkagePreference;
 use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
-use rustc::hir::map::definitions::DefPathTable;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc::middle::lang_items;
 use rustc::mir::{self, interpret};
@@ -30,10 +29,11 @@ use syntax::attr;
 use syntax::ast::{self, Ident};
 use syntax::source_map;
 use syntax::symbol::{Symbol, sym};
-use syntax::ext::base::{MacroKind, SyntaxExtension};
-use syntax::ext::hygiene::ExpnId;
-use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION};
+use syntax::ext::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension};
+use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, symbol::{InternedString}};
 use log::debug;
+use proc_macro::bridge::client::ProcMacro;
+use syntax::ext::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro};
 
 pub struct DecodeContext<'a, 'tcx> {
     opaque: opaque::Decoder<'a>,
@@ -138,7 +138,7 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> LazySeq<T> {
     pub fn decode<M: Metadata<'a, 'tcx>>(
         self,
         meta: M,
-    ) -> impl Iterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
+    ) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
         let mut dcx = meta.decoder(self.position);
         dcx.lazy_state = LazyState::NodeStart(self.position);
         (0..self.len).map(move |_| T::decode(&mut dcx).unwrap())
@@ -344,7 +344,15 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
         let hi = (hi + source_file.translated_source_file.start_pos)
                  - source_file.original_start_pos;
 
-        Ok(Span::new(lo, hi, NO_EXPANSION))
+        Ok(Span::with_root_ctxt(lo, hi))
+    }
+}
+
+impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
+    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
+        // FIXME(jseyfried): intercrate hygiene
+
+        Ok(Ident::with_dummy_span(Symbol::decode(self)?))
     }
 }
 
@@ -434,46 +442,16 @@ impl<'tcx> EntryKind<'tcx> {
     }
 }
 
-/// Creates the "fake" DefPathTable for a given proc macro crate.
-///
-/// The DefPathTable is as follows:
-///
-/// CRATE_ROOT (DefIndex 0:0)
-///  |- GlobalMetaDataKind data (DefIndex 1:0 .. DefIndex 1:N)
-///  |- proc macro #0 (DefIndex 1:N)
-///  |- proc macro #1 (DefIndex 1:N+1)
-///  \- ...
-crate fn proc_macro_def_path_table(crate_root: &CrateRoot<'_>,
-                                   proc_macros: &[(ast::Name, Lrc<SyntaxExtension>)])
-                                   -> DefPathTable
-{
-    let mut definitions = Definitions::default();
-
-    let name = crate_root.name.as_str();
-    let disambiguator = crate_root.disambiguator;
-    debug!("creating proc macro def path table for {:?}/{:?}", name, disambiguator);
-    let crate_root = definitions.create_root_def(&name, disambiguator);
-    for (index, (name, _)) in proc_macros.iter().enumerate() {
-        let def_index = definitions.create_def_with_parent(
-            crate_root,
-            ast::DUMMY_NODE_ID,
-            DefPathData::MacroNs(name.as_interned_str()),
-            ExpnId::root(),
-            DUMMY_SP);
-        debug!("definition for {:?} is {:?}", name, def_index);
-        assert_eq!(def_index, DefIndex::from_proc_macro_index(index));
-    }
-
-    definitions.def_path_table().clone()
-}
-
 impl<'a, 'tcx> CrateMetadata {
+    pub fn is_proc_macro_crate(&self) -> bool {
+        self.root.proc_macro_decls_static.is_some()
+    }
     fn is_proc_macro(&self, id: DefIndex) -> bool {
-        self.proc_macros.is_some() && id != CRATE_DEF_INDEX
+        self.is_proc_macro_crate() &&
+            self.root.proc_macro_data.unwrap().decode(self).find(|x| *x == id).is_some()
     }
 
     fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
-        assert!(!self.is_proc_macro(item_id));
         self.root.entries_index.lookup(self.blob.raw_bytes(), item_id)
     }
 
@@ -496,13 +474,24 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
+    fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
+        // DefIndex's in root.proc_macro_data have a one-to-one correspondence
+        // with items in 'raw_proc_macros'
+        let pos = self.root.proc_macro_data.unwrap().decode(self).position(|i| i == id).unwrap();
+        &self.raw_proc_macros.unwrap()[pos]
+    }
+
     pub fn item_name(&self, item_index: DefIndex) -> Symbol {
-        self.def_key(item_index)
-            .disambiguated_data
-            .data
-            .get_opt_name()
-            .expect("no name in item_name")
-            .as_symbol()
+        if !self.is_proc_macro(item_index) {
+            self.def_key(item_index)
+                .disambiguated_data
+                .data
+                .get_opt_name()
+                .expect("no name in item_name")
+                .as_symbol()
+        } else {
+            Symbol::intern(self.raw_proc_macro(item_index).name())
+        }
     }
 
     pub fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
@@ -510,15 +499,64 @@ impl<'a, 'tcx> CrateMetadata {
             self.entry(index).kind.def_kind()
         } else {
             Some(DefKind::Macro(
-                self.proc_macros.as_ref().unwrap()[index.to_proc_macro_index()].1.macro_kind()
+                macro_kind(self.raw_proc_macro(index))
             ))
         }
     }
 
     pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
-        match self.is_proc_macro(index) {
-            true => DUMMY_SP,
-            false => self.entry(index).span.decode((self, sess)),
+        self.entry(index).span.decode((self, sess))
+    }
+
+
+    pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro {
+        if sess.opts.debugging_opts.dual_proc_macros {
+            let host_lib = self.host_lib.as_ref().unwrap();
+            self.load_proc_macro(
+                &host_lib.metadata.get_root(),
+                id,
+                sess
+            )
+        } else {
+            self.load_proc_macro(&self.root, id, sess)
+        }
+    }
+
+    fn load_proc_macro(&self, root: &CrateRoot<'_>,
+                        id: DefIndex,
+                        sess: &Session)
+                        -> FullProcMacro {
+
+        let raw_macro = self.raw_proc_macro(id);
+        let (name, kind, helper_attrs) = match *raw_macro {
+            ProcMacro::CustomDerive { trait_name, attributes, client } => {
+                let helper_attrs =
+                    attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
+                (
+                    trait_name,
+                    SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
+                        client, attrs: helper_attrs.clone()
+                    })),
+                    helper_attrs,
+                )
+            }
+            ProcMacro::Attr { name, client } => (
+                name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()
+            ),
+            ProcMacro::Bang { name, client } => (
+                name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
+            )
+        };
+
+        let span = self.get_span(id, sess);
+
+        FullProcMacro {
+            name: Symbol::intern(name),
+            ext: Lrc::new(SyntaxExtension {
+                span,
+                helper_attrs,
+                ..SyntaxExtension::default(kind, root.edition)
+            })
         }
     }
 
@@ -569,7 +607,7 @@ impl<'a, 'tcx> CrateMetadata {
 
         ty::VariantDef::new(
             tcx,
-            Ident::with_empty_ctxt(self.item_name(index)),
+            Ident::with_dummy_span(self.item_name(index)),
             variant_did,
             ctor_did,
             data.discr,
@@ -577,7 +615,7 @@ impl<'a, 'tcx> CrateMetadata {
                 let f = self.entry(index);
                 ty::FieldDef {
                     did: self.local_def_id(index),
-                    ident: Ident::with_empty_ctxt(self.item_name(index)),
+                    ident: Ident::with_dummy_span(self.item_name(index)),
                     vis: f.visibility.decode(self)
                 }
             }).collect(),
@@ -715,7 +753,7 @@ impl<'a, 'tcx> CrateMetadata {
 
     /// Iterates over the language items in the given crate.
     pub fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
-        if self.proc_macros.is_some() {
+        if self.is_proc_macro_crate() {
             // Proc macro crates do not export any lang-items to the target.
             &[]
         } else {
@@ -730,18 +768,18 @@ impl<'a, 'tcx> CrateMetadata {
     pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
         where F: FnMut(def::Export<hir::HirId>)
     {
-        if let Some(ref proc_macros) = self.proc_macros {
+        if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) {
             /* If we are loading as a proc macro, we want to return the view of this crate
-             * as a proc macro crate, not as a Rust crate. See `proc_macro_def_path_table`
-             * for the DefPathTable we are corresponding to.
+             * as a proc macro crate.
              */
             if id == CRATE_DEF_INDEX {
-                for (id, &(name, ref ext)) in proc_macros.iter().enumerate() {
+                for def_index in proc_macros_ids {
+                    let raw_macro = self.raw_proc_macro(def_index);
                     let res = Res::Def(
-                        DefKind::Macro(ext.macro_kind()),
-                        self.local_def_id(DefIndex::from_proc_macro_index(id)),
+                        DefKind::Macro(macro_kind(raw_macro)),
+                        self.local_def_id(def_index),
                     );
-                    let ident = Ident::with_empty_ctxt(name);
+                    let ident = Ident::from_str(raw_macro.name());
                     callback(def::Export {
                         ident: ident,
                         res: res,
@@ -783,7 +821,7 @@ impl<'a, 'tcx> CrateMetadata {
                             if let Some(kind) = self.def_kind(child_index) {
                                 callback(def::Export {
                                     res: Res::Def(kind, self.local_def_id(child_index)),
-                                    ident: Ident::with_empty_ctxt(self.item_name(child_index)),
+                                    ident: Ident::with_dummy_span(self.item_name(child_index)),
                                     vis: self.get_visibility(child_index),
                                     span: self.entry(child_index).span.decode((self, sess)),
                                 });
@@ -952,11 +990,8 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
-        if self.is_proc_macro(node_id) {
-            return Lrc::new([]);
-        }
 
+    pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
         // The attributes for a tuple struct/variant are attached to the definition, not the ctor;
         // we assume that someone passing in a tuple struct ctor is actually wanting to
         // look at the definition
@@ -1014,7 +1049,7 @@ impl<'a, 'tcx> CrateMetadata {
         tcx: TyCtxt<'tcx>,
         filter: Option<DefId>,
     ) -> &'tcx [DefId] {
-        if self.proc_macros.is_some() {
+        if self.is_proc_macro_crate() {
             // proc-macro crates export no trait impls.
             return &[]
         }
@@ -1058,7 +1093,7 @@ impl<'a, 'tcx> CrateMetadata {
 
 
     pub fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
-        if self.proc_macros.is_some() {
+        if self.is_proc_macro_crate() {
             // Proc macro crates do not have any *target* native libraries.
             vec![]
         } else {
@@ -1067,7 +1102,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     pub fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
-        if self.proc_macros.is_some() {
+        if self.is_proc_macro_crate() {
             // Proc macro crates do not have any *target* foreign modules.
             &[]
         } else {
@@ -1090,7 +1125,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     pub fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
-        if self.proc_macros.is_some() {
+        if self.is_proc_macro_crate() {
             // Proc macro crates do not depend on any target weak lang-items.
             &[]
         } else {
@@ -1114,7 +1149,7 @@ impl<'a, 'tcx> CrateMetadata {
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
-        if self.proc_macros.is_some() {
+        if self.is_proc_macro_crate() {
             // If this crate is a custom derive crate, then we're not even going to
             // link those in so we skip those crates.
             vec![]
@@ -1183,13 +1218,18 @@ impl<'a, 'tcx> CrateMetadata {
 
     #[inline]
     pub fn def_key(&self, index: DefIndex) -> DefKey {
-        self.def_path_table.def_key(index)
+        let mut key = self.def_path_table.def_key(index);
+        if self.is_proc_macro(index) {
+            let name = self.raw_proc_macro(index).name();
+            key.disambiguated_data.data = DefPathData::MacroNs(InternedString::intern(name));
+        }
+        key
     }
 
     // Returns the path leading to the thing with this `id`.
     pub fn def_path(&self, id: DefIndex) -> DefPath {
         debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
-        DefPath::make(self.cnum, id, |parent| self.def_path_table.def_key(parent))
+        DefPath::make(self.cnum, id, |parent| self.def_key(parent))
     }
 
     #[inline]
@@ -1302,3 +1342,13 @@ impl<'a, 'tcx> CrateMetadata {
         self.source_map_import_info.borrow()
     }
 }
+
+// Cannot be implemented on 'ProcMacro', as libproc_macro
+// does not depend on libsyntax
+fn macro_kind(raw: &ProcMacro) -> MacroKind {
+    match raw {
+        ProcMacro::CustomDerive { .. } => MacroKind::Derive,
+        ProcMacro::Attr { .. } => MacroKind::Attr,
+        ProcMacro::Bang { .. } => MacroKind::Bang
+    }
+}
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index fb675d7d841..6058ae99cf4 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -30,8 +30,9 @@ use rustc_data_structures::sync::Lrc;
 use std::u32;
 use syntax::ast;
 use syntax::attr;
+use syntax::ext::proc_macro::is_proc_macro_attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::{kw, sym};
+use syntax::symbol::{kw, sym, Ident};
 use syntax_pos::{self, FileName, SourceFile, Span};
 use log::{debug, trace};
 
@@ -173,6 +174,13 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> {
     }
 }
 
+impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
+    fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
+        // FIXME(jseyfried): intercrate hygiene
+        ident.name.encode(self)
+    }
+}
+
 impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
     #[inline]
     fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
@@ -376,6 +384,8 @@ impl<'tcx> EncodeContext<'tcx> {
     }
 
     fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
+        let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
+
         let mut i = self.position();
 
         let crate_deps = self.encode_crate_deps();
@@ -456,16 +466,23 @@ impl<'tcx> EncodeContext<'tcx> {
             self.lazy_seq(interpret_alloc_index)
         };
 
+
         i = self.position();
         let entries_index = self.entries_index.write_index(&mut self.opaque);
         let entries_index_bytes = self.position() - i;
 
+        // Encode the proc macro data
+        i = self.position();
+        let proc_macro_data = self.encode_proc_macros();
+        let proc_macro_data_bytes = self.position() - i;
+
+
         let attrs = tcx.hir().krate_attrs();
-        let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
         let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
         let has_global_allocator = *tcx.sess.has_global_allocator.get();
         let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
 
+
         let root = self.lazy(&CrateRoot {
             name: tcx.crate_name(LOCAL_CRATE),
             extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
@@ -484,6 +501,7 @@ impl<'tcx> EncodeContext<'tcx> {
             } else {
                 None
             },
+            proc_macro_data,
             proc_macro_stability: if is_proc_macro {
                 tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone())
             } else {
@@ -532,6 +550,7 @@ impl<'tcx> EncodeContext<'tcx> {
             println!("            impl bytes: {}", impl_bytes);
             println!("    exp. symbols bytes: {}", exported_symbols_bytes);
             println!("  def-path table bytes: {}", def_path_table_bytes);
+            println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
             println!("            item bytes: {}", item_bytes);
             println!("   entries index bytes: {}", entries_index_bytes);
             println!("            zero bytes: {}", zero_bytes);
@@ -1463,6 +1482,22 @@ impl EncodeContext<'tcx> {
         self.lazy_seq(foreign_modules.iter().cloned())
     }
 
+    fn encode_proc_macros(&mut self) -> Option<LazySeq<DefIndex>> {
+        let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
+        if is_proc_macro {
+            let proc_macros: Vec<_> = self.tcx.hir().krate().items.values().filter_map(|item| {
+                if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
+                    Some(item.hir_id.owner)
+                } else {
+                    None
+                }
+            }).collect();
+            Some(self.lazy_seq(proc_macros))
+        } else {
+            None
+        }
+    }
+
     fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
         let crates = self.tcx.crates();
 
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 3832c8ee227..ceba7cf0fe0 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -716,7 +716,9 @@ impl<'a> Context<'a> {
 
         let root = metadata.get_root();
         if let Some(is_proc_macro) = self.is_proc_macro {
-            if root.proc_macro_decls_static.is_some() != is_proc_macro {
+            if root.proc_macro_data.is_some() != is_proc_macro {
+                info!("Rejecting via proc macro: expected {} got {}",
+                      is_proc_macro, root.proc_macro_data.is_some());
                 return None;
             }
         }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index c0ac6915933..13c599cf997 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -182,6 +182,10 @@ pub struct CrateRoot<'tcx> {
 
     pub entries_index: LazySeq<index::Index<'tcx>>,
 
+    /// The DefIndex's of any proc macros delcared by
+    /// this crate
+    pub proc_macro_data: Option<LazySeq<DefIndex>>,
+
     pub compiler_builtins: bool,
     pub needs_allocator: bool,
     pub needs_panic_runtime: bool,
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 70d6c15d8e2..9ff0c6ca6a5 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -272,12 +272,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
 
     fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
         self.super_constant(constant, location);
-        self.sanitize_constant(constant, location);
-        self.sanitize_type(constant, constant.ty);
+        self.sanitize_type(constant, constant.literal.ty);
 
         if let Some(annotation_index) = constant.user_ty {
             if let Err(terr) = self.cx.relate_type_and_user_type(
-                constant.ty,
+                constant.literal.ty,
                 ty::Variance::Invariant,
                 &UserTypeProjection { base: annotation_index, projs: vec![], },
                 location.to_locations(),
@@ -289,7 +288,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                     constant,
                     "bad constant user type {:?} vs {:?}: {:?}",
                     annotation,
-                    constant.ty,
+                    constant.literal.ty,
                     terr,
                 );
             }
@@ -299,7 +298,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
                     location.to_locations(),
                     ConstraintCategory::Boring,
                     self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
-                        constant.ty, def_id, UserSubsts { substs, user_self_ty: None },
+                        constant.literal.ty, def_id, UserSubsts { substs, user_self_ty: None },
                     )),
                 ) {
                     span_mirbug!(
@@ -403,41 +402,6 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
         }
     }
 
-    /// Checks that the constant's `ty` field matches up with what would be
-    /// expected from its literal. Unevaluated constants and well-formed
-    /// constraints are checked by `visit_constant`.
-    fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
-        debug!(
-            "sanitize_constant(constant={:?}, location={:?})",
-            constant, location
-        );
-
-        let literal = constant.literal;
-
-        if let ConstValue::Unevaluated(..) = literal.val {
-            return;
-        }
-
-        debug!("sanitize_constant: expected_ty={:?}", literal.ty);
-
-        if let Err(terr) = self.cx.eq_types(
-            literal.ty,
-            constant.ty,
-            location.to_locations(),
-            ConstraintCategory::Boring,
-        ) {
-            span_mirbug!(
-                self,
-                constant,
-                "constant {:?} should have type {:?} but has {:?} ({:?})",
-                constant,
-                literal.ty,
-                constant.ty,
-                terr,
-            );
-        }
-    }
-
     /// Checks that the types internal to the `place` match up with
     /// what would be expected.
     fn sanitize_place(
diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs
index 5197981a85c..39bdc871d83 100644
--- a/src/librustc_mir/build/expr/as_constant.rs
+++ b/src/librustc_mir/build/expr/as_constant.rs
@@ -38,9 +38,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         inferred_ty: ty,
                     })
                 });
+                assert_eq!(literal.ty, ty);
                 Constant {
                     span,
-                    ty,
                     user_ty,
                     literal,
                 }
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index ec061e74535..1a186fa932d 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -591,7 +591,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let n = (!0u128) >> (128 - bits);
         let literal = ty::Const::from_bits(self.hir.tcx(), n, param_ty);
 
-        self.literal_operand(span, ty, literal)
+        self.literal_operand(span, literal)
     }
 
     // Helper to get the minimum value of the appropriate type
@@ -602,6 +602,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let n = 1 << (bits - 1);
         let literal = ty::Const::from_bits(self.hir.tcx(), n, param_ty);
 
-        self.literal_operand(span, ty, literal)
+        self.literal_operand(span, literal)
     }
 }
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 02ab53fe8c1..889861b8567 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -114,7 +114,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     destination,
                     Constant {
                         span: expr_span,
-                        ty: this.hir.bool_ty(),
                         user_ty: None,
                         literal: this.hir.true_literal(),
                     },
@@ -126,7 +125,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     destination,
                     Constant {
                         span: expr_span,
-                        ty: this.hir.bool_ty(),
                         user_ty: None,
                         literal: this.hir.false_literal(),
                     },
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index d72b0addae9..94323b15b69 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -657,6 +657,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     self.visit_bindings(&subpattern.pattern, subpattern_user_ty, f);
                 }
             }
+            PatternKind::Or { ref pats } => {
+                for pat in pats {
+                    self.visit_bindings(&pat, pattern_user_ty.clone(), f);
+                }
+            }
         }
     }
 }
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index d9b748f71f0..8d049b53988 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -108,8 +108,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 Err(match_pair)
             }
 
-            PatternKind::Range(PatternRange { lo, hi, ty, end }) => {
-                let (range, bias) = match ty.sty {
+            PatternKind::Range(PatternRange { lo, hi, end }) => {
+                let (range, bias) = match lo.ty.sty {
                     ty::Char => {
                         (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
                     }
@@ -195,6 +195,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 candidate.match_pairs.push(MatchPair::new(place, subpattern));
                 Ok(())
             }
+
+            PatternKind::Or { .. } => {
+                Err(match_pair)
+            }
         }
     }
 }
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 1c93abd40de..ec85daccd47 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -63,7 +63,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             PatternKind::Range(range) => {
-                assert!(range.ty == match_pair.pattern.ty);
+                assert_eq!(range.lo.ty, match_pair.pattern.ty);
+                assert_eq!(range.hi.ty, match_pair.pattern.ty);
                 Test {
                     span: match_pair.pattern.span,
                     kind: TestKind::Range(range),
@@ -86,6 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatternKind::AscribeUserType { .. } |
             PatternKind::Array { .. } |
             PatternKind::Wild |
+            PatternKind::Or { .. } |
             PatternKind::Binding { .. } |
             PatternKind::Leaf { .. } |
             PatternKind::Deref { .. } => {
@@ -129,6 +131,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatternKind::Slice { .. } |
             PatternKind::Array { .. } |
             PatternKind::Wild |
+            PatternKind::Or { .. } |
             PatternKind::Binding { .. } |
             PatternKind::AscribeUserType { .. } |
             PatternKind::Leaf { .. } |
@@ -270,8 +273,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     );
                 } else {
                     if let [success, fail] = *make_target_blocks(self) {
+                        assert_eq!(value.ty, ty);
+                        let expect = self.literal_operand(test.span, value);
                         let val = Operand::Copy(place.clone());
-                        let expect = self.literal_operand(test.span, ty, value);
                         self.compare(block, success, fail, source_info, BinOp::Eq, expect, val);
                     } else {
                         bug!("`TestKind::Eq` should have two target blocks");
@@ -279,13 +283,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 }
             }
 
-            TestKind::Range(PatternRange { ref lo, ref hi, ty, ref end }) => {
+            TestKind::Range(PatternRange { ref lo, ref hi, ref end }) => {
                 let lower_bound_success = self.cfg.start_new_block();
                 let target_blocks = make_target_blocks(self);
 
                 // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
-                let lo = self.literal_operand(test.span, ty, lo);
-                let hi = self.literal_operand(test.span, ty, hi);
+                let lo = self.literal_operand(test.span, lo);
+                let hi = self.literal_operand(test.span, hi);
                 let val = Operand::Copy(place.clone());
 
                 if let [success, fail] = *target_blocks {
@@ -387,7 +391,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ) {
         use rustc::middle::lang_items::EqTraitLangItem;
 
-        let mut expect = self.literal_operand(source_info.span, value.ty, value);
+        let mut expect = self.literal_operand(source_info.span, value);
         let mut val = Operand::Copy(place.clone());
 
         // If we're using `b"..."` as a pattern, we need to insert an
@@ -440,7 +444,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         let eq_def_id = self.hir.tcx().require_lang_item(EqTraitLangItem);
-        let (mty, method) = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
+        let method = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
 
         let bool_ty = self.hir.bool_ty();
         let eq_result = self.temp(bool_ty, source_info.span);
@@ -449,7 +453,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.cfg.terminate(block, source_info, TerminatorKind::Call {
             func: Operand::Constant(box Constant {
                 span: source_info.span,
-                ty: mty,
 
                 // FIXME(#54571): This constant comes from user input (a
                 // constant in a pattern).  Are there forms where users can add
@@ -656,8 +659,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                     let tcx = self.hir.tcx();
 
-                    let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test.ty)?;
-                    let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test.ty)?;
+                    let test_ty = test.lo.ty;
+                    let lo = compare_const_vals(tcx, test.lo, pat.hi, self.hir.param_env, test_ty)?;
+                    let hi = compare_const_vals(tcx, test.hi, pat.lo, self.hir.param_env, test_ty)?;
 
                     match (test.end, pat.end, lo, hi) {
                         // pat < test
@@ -774,8 +778,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         let tcx = self.hir.tcx();
 
-        let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.ty)?;
-        let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.ty)?;
+        let a = compare_const_vals(tcx, range.lo, value, self.hir.param_env, range.lo.ty)?;
+        let b = compare_const_vals(tcx, value, range.hi, self.hir.param_env, range.lo.ty)?;
 
         match (b, range.end) {
             (Less, _) |
diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs
index 56025eeaaa9..d038310dd44 100644
--- a/src/librustc_mir/build/misc.rs
+++ b/src/librustc_mir/build/misc.rs
@@ -26,12 +26,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// without any user type annotation.
     pub fn literal_operand(&mut self,
                            span: Span,
-                           ty: Ty<'tcx>,
                            literal: &'tcx ty::Const<'tcx>)
                            -> Operand<'tcx> {
         let constant = box Constant {
             span,
-            ty,
             user_ty: None,
             literal,
         };
@@ -47,7 +45,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> {
         let literal = ty::Const::from_bits(self.hir.tcx(), 0, ty::ParamEnv::empty().and(ty));
 
-        self.literal_operand(span, ty, literal)
+        self.literal_operand(span, literal)
     }
 
     pub fn push_usize(&mut self,
@@ -61,7 +59,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             block, source_info, &temp,
             Constant {
                 span: source_info.span,
-                ty: self.hir.usize_ty(),
                 user_ty: None,
                 literal: self.hir.usize_literal(value),
             });
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 52225ea8f02..76ee76a7456 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -11,9 +11,8 @@ use rustc::hir::def::DefKind;
 use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::{ConstEvalErr, ErrorHandled, ScalarMaybeUndef};
 use rustc::mir;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt, subst::Subst};
 use rustc::ty::layout::{self, LayoutOf, VariantIdx};
-use rustc::ty::subst::Subst;
 use rustc::traits::Reveal;
 use rustc_data_structures::fx::FxHashMap;
 
@@ -415,7 +414,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
         _bin_op: mir::BinOp,
         _left: ImmTy<'tcx>,
         _right: ImmTy<'tcx>,
-    ) -> InterpResult<'tcx, (Scalar, bool)> {
+    ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
         Err(
             ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into(),
         )
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 1c6a743155e..a33d7207ed4 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -927,7 +927,7 @@ fn convert_path_expr<'a, 'tcx>(
             ExprKind::Literal {
                 literal: cx.tcx.mk_const(ty::Const {
                     val: ConstValue::Unevaluated(def_id, substs),
-                    ty: cx.tcx.type_of(def_id),
+                    ty: cx.tables().node_type(expr.hir_id),
                 }),
                 user_ty,
             }
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 3d9349df5be..740dc2011ca 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -170,13 +170,13 @@ impl<'a, 'tcx> Cx<'a, 'tcx> {
                         method_name: Symbol,
                         self_ty: Ty<'tcx>,
                         params: &[Kind<'tcx>])
-                        -> (Ty<'tcx>, &'tcx ty::Const<'tcx>) {
+                        -> &'tcx ty::Const<'tcx> {
         let substs = self.tcx.mk_substs_trait(self_ty, params);
         for item in self.tcx.associated_items(trait_def_id) {
             if item.kind == ty::AssocKind::Method && item.ident.name == method_name {
                 let method_ty = self.tcx.type_of(item.def_id);
                 let method_ty = method_ty.subst(self.tcx, substs);
-                return (method_ty, ty::Const::zero_sized(self.tcx, method_ty));
+                return ty::Const::zero_sized(self.tcx, method_ty);
             }
         }
 
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 8a3d904e775..222750e602d 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -609,7 +609,6 @@ impl<'tcx> Witness<'tcx> {
                         ConstantRange(lo, hi, ty, end) => PatternKind::Range(PatternRange {
                             lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
                             hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
-                            ty,
                             end,
                         }),
                         _ => PatternKind::Wild,
@@ -880,10 +879,10 @@ impl<'tcx> IntRange<'tcx> {
         let range = loop {
             match pat.kind {
                 box PatternKind::Constant { value } => break ConstantValue(value),
-                box PatternKind::Range(PatternRange { lo, hi, ty, end }) => break ConstantRange(
-                    lo.eval_bits(tcx, param_env, ty),
-                    hi.eval_bits(tcx, param_env, ty),
-                    ty,
+                box PatternKind::Range(PatternRange { lo, hi, end }) => break ConstantRange(
+                    lo.eval_bits(tcx, param_env, lo.ty),
+                    hi.eval_bits(tcx, param_env, hi.ty),
+                    lo.ty,
                     end,
                 ),
                 box PatternKind::AscribeUserType { ref subpattern, .. } => {
@@ -1339,11 +1338,11 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
             Some(vec![Variant(adt_def.variants[variant_index].def_id)])
         }
         PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
-        PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
+        PatternKind::Range(PatternRange { lo, hi, end }) =>
             Some(vec![ConstantRange(
-                lo.eval_bits(cx.tcx, cx.param_env, ty),
-                hi.eval_bits(cx.tcx, cx.param_env, ty),
-                ty,
+                lo.eval_bits(cx.tcx, cx.param_env, lo.ty),
+                hi.eval_bits(cx.tcx, cx.param_env, hi.ty),
+                lo.ty,
                 end,
             )]),
         PatternKind::Array { .. } => match pcx.ty.sty {
@@ -1360,6 +1359,9 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
                 Some(vec![Slice(pat_len)])
             }
         }
+        PatternKind::Or { .. } => {
+            bug!("support for or-patterns has not been fully implemented yet.");
+        }
     }
 }
 
@@ -1656,7 +1658,7 @@ fn constructor_covered_by_range<'tcx>(
 ) -> Result<bool, ErrorReported> {
     let (from, to, end, ty) = match pat.kind {
         box PatternKind::Constant { value } => (value, value, RangeEnd::Included, value.ty),
-        box PatternKind::Range(PatternRange { lo, hi, end, ty }) => (lo, hi, end, ty),
+        box PatternKind::Range(PatternRange { lo, hi, end }) => (lo, hi, end, lo.ty),
         _ => bug!("`constructor_covered_by_range` called with {:?}", pat),
     };
     trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
@@ -1885,6 +1887,10 @@ fn specialize<'p, 'a: 'p, 'tcx>(
                     "unexpected ctor {:?} for slice pat", constructor)
             }
         }
+
+        PatternKind::Or { .. } => {
+            bug!("support for or-patterns has not been fully implemented yet.");
+        }
     };
     debug!("specialize({:#?}, {:#?}) = {:#?}", r[0], wild_patterns, head);
 
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 10223151f5c..6caccfddfa4 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -175,18 +175,35 @@ pub enum PatternKind<'tcx> {
         slice: Option<Pattern<'tcx>>,
         suffix: Vec<Pattern<'tcx>>,
     },
+
+    /// An or-pattern, e.g. `p | q`.
+    /// Invariant: `pats.len() >= 2`.
+    Or {
+        pats: Vec<Pattern<'tcx>>,
+    },
 }
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub struct PatternRange<'tcx> {
     pub lo: &'tcx ty::Const<'tcx>,
     pub hi: &'tcx ty::Const<'tcx>,
-    pub ty: Ty<'tcx>,
     pub end: RangeEnd,
 }
 
 impl<'tcx> fmt::Display for Pattern<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // Printing lists is a chore.
+        let mut first = true;
+        let mut start_or_continue = |s| {
+            if first {
+                first = false;
+                ""
+            } else {
+                s
+            }
+        };
+        let mut start_or_comma = || start_or_continue(", ");
+
         match *self.kind {
             PatternKind::Wild => write!(f, "_"),
             PatternKind::AscribeUserType { ref subpattern, .. } =>
@@ -225,9 +242,6 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
                     }
                 };
 
-                let mut first = true;
-                let mut start_or_continue = || if first { first = false; "" } else { ", " };
-
                 if let Some(variant) = variant {
                     write!(f, "{}", variant.ident)?;
 
@@ -242,12 +256,12 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
                                 continue;
                             }
                             let name = variant.fields[p.field.index()].ident;
-                            write!(f, "{}{}: {}", start_or_continue(), name, p.pattern)?;
+                            write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?;
                             printed += 1;
                         }
 
                         if printed < variant.fields.len() {
-                            write!(f, "{}..", start_or_continue())?;
+                            write!(f, "{}..", start_or_comma())?;
                         }
 
                         return write!(f, " }}");
@@ -258,7 +272,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
                 if num_fields != 0 || variant.is_none() {
                     write!(f, "(")?;
                     for i in 0..num_fields {
-                        write!(f, "{}", start_or_continue())?;
+                        write!(f, "{}", start_or_comma())?;
 
                         // Common case: the field is where we expect it.
                         if let Some(p) = subpatterns.get(i) {
@@ -296,7 +310,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
             PatternKind::Constant { value } => {
                 write!(f, "{}", value)
             }
-            PatternKind::Range(PatternRange { lo, hi, ty: _, end }) => {
+            PatternKind::Range(PatternRange { lo, hi, end }) => {
                 write!(f, "{}", lo)?;
                 match end {
                     RangeEnd::Included => write!(f, "..=")?,
@@ -306,14 +320,12 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
             }
             PatternKind::Slice { ref prefix, ref slice, ref suffix } |
             PatternKind::Array { ref prefix, ref slice, ref suffix } => {
-                let mut first = true;
-                let mut start_or_continue = || if first { first = false; "" } else { ", " };
                 write!(f, "[")?;
                 for p in prefix {
-                    write!(f, "{}{}", start_or_continue(), p)?;
+                    write!(f, "{}{}", start_or_comma(), p)?;
                 }
                 if let Some(ref slice) = *slice {
-                    write!(f, "{}", start_or_continue())?;
+                    write!(f, "{}", start_or_comma())?;
                     match *slice.kind {
                         PatternKind::Wild => {}
                         _ => write!(f, "{}", slice)?
@@ -321,10 +333,16 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
                     write!(f, "..")?;
                 }
                 for p in suffix {
-                    write!(f, "{}{}", start_or_continue(), p)?;
+                    write!(f, "{}{}", start_or_comma(), p)?;
                 }
                 write!(f, "]")
             }
+            PatternKind::Or { ref pats } => {
+                for pat in pats {
+                    write!(f, "{}{}", start_or_continue(" | "), pat)?;
+                }
+                Ok(())
+            }
         }
     }
 }
@@ -442,6 +460,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
 
                 let mut kind = match (lo, hi) {
                     (PatternKind::Constant { value: lo }, PatternKind::Constant { value: hi }) => {
+                        assert_eq!(lo.ty, ty);
+                        assert_eq!(hi.ty, ty);
                         let cmp = compare_const_vals(
                             self.tcx,
                             lo,
@@ -451,7 +471,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                         );
                         match (end, cmp) {
                             (RangeEnd::Excluded, Some(Ordering::Less)) =>
-                                PatternKind::Range(PatternRange { lo, hi, ty, end }),
+                                PatternKind::Range(PatternRange { lo, hi, end }),
                             (RangeEnd::Excluded, _) => {
                                 span_err!(
                                     self.tcx.sess,
@@ -465,7 +485,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                                 PatternKind::Constant { value: lo }
                             }
                             (RangeEnd::Included, Some(Ordering::Less)) => {
-                                PatternKind::Range(PatternRange { lo, hi, ty, end })
+                                PatternKind::Range(PatternRange { lo, hi, end })
                             }
                             (RangeEnd::Included, _) => {
                                 let mut err = struct_span_err!(
@@ -654,6 +674,12 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
 
                 self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns)
             }
+
+            PatKind::Or(ref pats) => {
+                PatternKind::Or {
+                    pats: pats.iter().map(|p| self.lower_pattern(p)).collect(),
+                }
+            }
         };
 
         Pattern {
@@ -1416,17 +1442,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
             } => PatternKind::Constant {
                 value,
             },
-            PatternKind::Range(PatternRange {
-                lo,
-                hi,
-                ty,
-                end,
-            }) => PatternKind::Range(PatternRange {
-                lo,
-                hi,
-                ty: ty.fold_with(folder),
-                end,
-            }),
+            PatternKind::Range(range) => PatternKind::Range(range),
             PatternKind::Slice {
                 ref prefix,
                 ref slice,
@@ -1445,6 +1461,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
                 slice: slice.fold_with(folder),
                 suffix: suffix.fold_with(folder)
             },
+            PatternKind::Or { ref pats } => PatternKind::Or { pats: pats.fold_with(folder) },
         }
     }
 }
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 89c5be137a4..4c86c53256e 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -110,18 +110,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 };
                 self.write_scalar(out_val, dest)?;
             }
-            | "overflowing_add"
-            | "overflowing_sub"
-            | "overflowing_mul"
+            | "wrapping_add"
+            | "wrapping_sub"
+            | "wrapping_mul"
             | "add_with_overflow"
             | "sub_with_overflow"
             | "mul_with_overflow" => {
                 let lhs = self.read_immediate(args[0])?;
                 let rhs = self.read_immediate(args[1])?;
                 let (bin_op, ignore_overflow) = match intrinsic_name {
-                    "overflowing_add" => (BinOp::Add, true),
-                    "overflowing_sub" => (BinOp::Sub, true),
-                    "overflowing_mul" => (BinOp::Mul, true),
+                    "wrapping_add" => (BinOp::Add, true),
+                    "wrapping_sub" => (BinOp::Sub, true),
+                    "wrapping_mul" => (BinOp::Mul, true),
                     "add_with_overflow" => (BinOp::Add, false),
                     "sub_with_overflow" => (BinOp::Sub, false),
                     "mul_with_overflow" => (BinOp::Mul, false),
@@ -137,7 +137,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let l = self.read_immediate(args[0])?;
                 let r = self.read_immediate(args[1])?;
                 let is_add = intrinsic_name == "saturating_add";
-                let (val, overflowed) = self.binary_op(if is_add {
+                let (val, overflowed, _ty) = self.overflowing_binary_op(if is_add {
                     BinOp::Add
                 } else {
                     BinOp::Sub
@@ -184,7 +184,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     "unchecked_shr" => BinOp::Shr,
                     _ => bug!("Already checked for int ops")
                 };
-                let (val, overflowed) = self.binary_op(bin_op, l, r)?;
+                let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?;
                 if overflowed {
                     let layout = self.layout_of(substs.type_at(0))?;
                     let r_val = r.to_scalar()?.to_bits(layout.size)?;
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index 33ffb1d320e..bb74a50156e 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -7,7 +7,7 @@ use std::hash::Hash;
 
 use rustc::hir::def_id::DefId;
 use rustc::mir;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, Ty, TyCtxt};
 
 use super::{
     Allocation, AllocId, InterpResult, Scalar, AllocationExtra,
@@ -176,7 +176,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
         bin_op: mir::BinOp,
         left: ImmTy<'tcx, Self::PointerTag>,
         right: ImmTy<'tcx, Self::PointerTag>,
-    ) -> InterpResult<'tcx, (Scalar<Self::PointerTag>, bool)>;
+    ) -> InterpResult<'tcx, (Scalar<Self::PointerTag>, bool, Ty<'tcx>)>;
 
     /// Heap allocations via the `box` keyword.
     fn box_alloc(
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 6771d7661e3..87d36dabb04 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -297,7 +297,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
     /// and `align`. On success, returns `None` for zero-sized accesses (where
     /// nothing else is left to do) and a `Pointer` to use for the actual access otherwise.
     /// Crucially, if the input is a `Pointer`, we will test it for liveness
-    /// *even of* the size is 0.
+    /// *even if* the size is 0.
     ///
     /// Everyone accessing memory based on a `Scalar` should use this method to get the
     /// `Pointer` they need. And even if you already have a `Pointer`, call this method
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 139a92c7b11..726ae6fab10 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -108,7 +108,7 @@ impl<'tcx, Tag> Immediate<Tag> {
 // as input for binary and cast operations.
 #[derive(Copy, Clone, Debug)]
 pub struct ImmTy<'tcx, Tag=()> {
-    pub imm: Immediate<Tag>,
+    pub(crate) imm: Immediate<Tag>,
     pub layout: TyLayout<'tcx>,
 }
 
@@ -155,7 +155,7 @@ impl<Tag> Operand<Tag> {
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
 pub struct OpTy<'tcx, Tag=()> {
-    op: Operand<Tag>,
+    op: Operand<Tag>, // Keep this private, it helps enforce invariants
     pub layout: TyLayout<'tcx>,
 }
 
@@ -187,14 +187,23 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
     }
 }
 
-impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag>
-{
+impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
     #[inline]
     pub fn from_scalar(val: Scalar<Tag>, layout: TyLayout<'tcx>) -> Self {
         ImmTy { imm: val.into(), layout }
     }
 
     #[inline]
+    pub fn from_uint(i: impl Into<u128>, layout: TyLayout<'tcx>) -> Self {
+        Self::from_scalar(Scalar::from_uint(i, layout.size), layout)
+    }
+
+    #[inline]
+    pub fn from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Self {
+        Self::from_scalar(Scalar::from_int(i, layout.size), layout)
+    }
+
+    #[inline]
     pub fn to_bits(self) -> InterpResult<'tcx, u128> {
         self.to_scalar()?.to_bits(self.layout.size)
     }
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs
index e638ebcc342..470cc9346ee 100644
--- a/src/librustc_mir/interpret/operator.rs
+++ b/src/librustc_mir/interpret/operator.rs
@@ -1,5 +1,5 @@
 use rustc::mir;
-use rustc::ty::{self, layout::TyLayout};
+use rustc::ty::{self, Ty, layout::{TyLayout, LayoutOf}};
 use syntax::ast::FloatTy;
 use rustc_apfloat::Float;
 use rustc::mir::interpret::{InterpResult, Scalar};
@@ -17,7 +17,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         right: ImmTy<'tcx, M::PointerTag>,
         dest: PlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
-        let (val, overflowed) = self.binary_op(op, left, right)?;
+        let (val, overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
+        debug_assert_eq!(
+            self.tcx.intern_tup(&[ty, self.tcx.types.bool]),
+            dest.layout.ty,
+            "type mismatch for result of {:?}", op,
+        );
         let val = Immediate::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
         self.write_immediate(val, dest)
     }
@@ -31,7 +36,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         right: ImmTy<'tcx, M::PointerTag>,
         dest: PlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
-        let (val, _overflowed) = self.binary_op(op, left, right)?;
+        let (val, _overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
+        assert_eq!(ty, dest.layout.ty, "type mismatch for result of {:?}", op);
         self.write_scalar(val, dest)
     }
 }
@@ -42,7 +48,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         bin_op: mir::BinOp,
         l: char,
         r: char,
-    ) -> (Scalar<M::PointerTag>, bool) {
+    ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
         use rustc::mir::BinOp::*;
 
         let res = match bin_op {
@@ -54,7 +60,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             Ge => l >= r,
             _ => bug!("Invalid operation on char: {:?}", bin_op),
         };
-        return (Scalar::from_bool(res), false);
+        return (Scalar::from_bool(res), false, self.tcx.types.bool);
     }
 
     fn binary_bool_op(
@@ -62,7 +68,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         bin_op: mir::BinOp,
         l: bool,
         r: bool,
-    ) -> (Scalar<M::PointerTag>, bool) {
+    ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
         use rustc::mir::BinOp::*;
 
         let res = match bin_op {
@@ -77,32 +83,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             BitXor => l ^ r,
             _ => bug!("Invalid operation on bool: {:?}", bin_op),
         };
-        return (Scalar::from_bool(res), false);
+        return (Scalar::from_bool(res), false, self.tcx.types.bool);
     }
 
     fn binary_float_op<F: Float + Into<Scalar<M::PointerTag>>>(
         &self,
         bin_op: mir::BinOp,
+        ty: Ty<'tcx>,
         l: F,
         r: F,
-    ) -> (Scalar<M::PointerTag>, bool) {
+    ) -> (Scalar<M::PointerTag>, bool, Ty<'tcx>) {
         use rustc::mir::BinOp::*;
 
-        let val = match bin_op {
-            Eq => Scalar::from_bool(l == r),
-            Ne => Scalar::from_bool(l != r),
-            Lt => Scalar::from_bool(l < r),
-            Le => Scalar::from_bool(l <= r),
-            Gt => Scalar::from_bool(l > r),
-            Ge => Scalar::from_bool(l >= r),
-            Add => (l + r).value.into(),
-            Sub => (l - r).value.into(),
-            Mul => (l * r).value.into(),
-            Div => (l / r).value.into(),
-            Rem => (l % r).value.into(),
+        let (val, ty) = match bin_op {
+            Eq => (Scalar::from_bool(l == r), self.tcx.types.bool),
+            Ne => (Scalar::from_bool(l != r), self.tcx.types.bool),
+            Lt => (Scalar::from_bool(l < r), self.tcx.types.bool),
+            Le => (Scalar::from_bool(l <= r), self.tcx.types.bool),
+            Gt => (Scalar::from_bool(l > r), self.tcx.types.bool),
+            Ge => (Scalar::from_bool(l >= r), self.tcx.types.bool),
+            Add => ((l + r).value.into(), ty),
+            Sub => ((l - r).value.into(), ty),
+            Mul => ((l * r).value.into(), ty),
+            Div => ((l / r).value.into(), ty),
+            Rem => ((l % r).value.into(), ty),
             _ => bug!("invalid float op: `{:?}`", bin_op),
         };
-        return (val, false);
+        return (val, false, ty);
     }
 
     fn binary_int_op(
@@ -113,7 +120,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         left_layout: TyLayout<'tcx>,
         r: u128,
         right_layout: TyLayout<'tcx>,
-    ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> {
+    ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool, Ty<'tcx>)> {
         use rustc::mir::BinOp::*;
 
         // Shift ops can have an RHS with a different numeric type.
@@ -142,7 +149,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             };
             let truncated = self.truncate(result, left_layout);
-            return Ok((Scalar::from_uint(truncated, size), oflo));
+            return Ok((Scalar::from_uint(truncated, size), oflo, left_layout.ty));
         }
 
         // For the remaining ops, the types must be the same on both sides
@@ -167,7 +174,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             if let Some(op) = op {
                 let l = self.sign_extend(l, left_layout) as i128;
                 let r = self.sign_extend(r, right_layout) as i128;
-                return Ok((Scalar::from_bool(op(&l, &r)), false));
+                return Ok((Scalar::from_bool(op(&l, &r)), false, self.tcx.types.bool));
             }
             let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
                 Div if r == 0 => throw_panic!(DivisionByZero),
@@ -187,7 +194,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     Rem | Div => {
                         // int_min / -1
                         if r == -1 && l == (1 << (size.bits() - 1)) {
-                            return Ok((Scalar::from_uint(l, size), true));
+                            return Ok((Scalar::from_uint(l, size), true, left_layout.ty));
                         }
                     },
                     _ => {},
@@ -202,25 +209,24 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // this may be out-of-bounds for the result type, so we have to truncate ourselves
                 let result = result as u128;
                 let truncated = self.truncate(result, left_layout);
-                return Ok((Scalar::from_uint(truncated, size), oflo));
+                return Ok((Scalar::from_uint(truncated, size), oflo, left_layout.ty));
             }
         }
 
         let size = left_layout.size;
 
-        // only ints left
-        let val = match bin_op {
-            Eq => Scalar::from_bool(l == r),
-            Ne => Scalar::from_bool(l != r),
+        let (val, ty) = match bin_op {
+            Eq => (Scalar::from_bool(l == r), self.tcx.types.bool),
+            Ne => (Scalar::from_bool(l != r), self.tcx.types.bool),
 
-            Lt => Scalar::from_bool(l < r),
-            Le => Scalar::from_bool(l <= r),
-            Gt => Scalar::from_bool(l > r),
-            Ge => Scalar::from_bool(l >= r),
+            Lt => (Scalar::from_bool(l < r), self.tcx.types.bool),
+            Le => (Scalar::from_bool(l <= r), self.tcx.types.bool),
+            Gt => (Scalar::from_bool(l > r), self.tcx.types.bool),
+            Ge => (Scalar::from_bool(l >= r), self.tcx.types.bool),
 
-            BitOr => Scalar::from_uint(l | r, size),
-            BitAnd => Scalar::from_uint(l & r, size),
-            BitXor => Scalar::from_uint(l ^ r, size),
+            BitOr => (Scalar::from_uint(l | r, size), left_layout.ty),
+            BitAnd => (Scalar::from_uint(l & r, size), left_layout.ty),
+            BitXor => (Scalar::from_uint(l ^ r, size), left_layout.ty),
 
             Add | Sub | Mul | Rem | Div => {
                 debug_assert!(!left_layout.abi.is_signed());
@@ -236,7 +242,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 };
                 let (result, oflo) = op(l, r);
                 let truncated = self.truncate(result, left_layout);
-                return Ok((Scalar::from_uint(truncated, size), oflo || truncated != result));
+                return Ok((
+                    Scalar::from_uint(truncated, size),
+                    oflo || truncated != result,
+                    left_layout.ty,
+                ));
             }
 
             _ => {
@@ -250,17 +260,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
         };
 
-        Ok((val, false))
+        Ok((val, false, ty))
     }
 
-    /// Returns the result of the specified operation and whether it overflowed.
-    #[inline]
-    pub fn binary_op(
+    /// Returns the result of the specified operation, whether it overflowed, and
+    /// the result type.
+    pub fn overflowing_binary_op(
         &self,
         bin_op: mir::BinOp,
         left: ImmTy<'tcx, M::PointerTag>,
         right: ImmTy<'tcx, M::PointerTag>,
-    ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool)> {
+    ) -> InterpResult<'tcx, (Scalar<M::PointerTag>, bool, Ty<'tcx>)> {
         trace!("Running binary op {:?}: {:?} ({:?}), {:?} ({:?})",
             bin_op, *left, left.layout.ty, *right, right.layout.ty);
 
@@ -279,11 +289,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
             ty::Float(fty) => {
                 assert_eq!(left.layout.ty, right.layout.ty);
+                let ty = left.layout.ty;
                 let left = left.to_scalar()?;
                 let right = right.to_scalar()?;
                 Ok(match fty {
-                    FloatTy::F32 => self.binary_float_op(bin_op, left.to_f32()?, right.to_f32()?),
-                    FloatTy::F64 => self.binary_float_op(bin_op, left.to_f64()?, right.to_f64()?),
+                    FloatTy::F32 =>
+                        self.binary_float_op(bin_op, ty, left.to_f32()?, right.to_f32()?),
+                    FloatTy::F64 =>
+                        self.binary_float_op(bin_op, ty, left.to_f64()?, right.to_f64()?),
                 })
             }
             _ if left.layout.ty.is_integral() => {
@@ -312,11 +325,23 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
+    /// Typed version of `checked_binary_op`, returning an `ImmTy`. Also ignores overflows.
+    #[inline]
+    pub fn binary_op(
+        &self,
+        bin_op: mir::BinOp,
+        left: ImmTy<'tcx, M::PointerTag>,
+        right: ImmTy<'tcx, M::PointerTag>,
+    ) -> InterpResult<'tcx, ImmTy<'tcx, M::PointerTag>> {
+        let (val, _overflow, ty) = self.overflowing_binary_op(bin_op, left, right)?;
+        Ok(ImmTy::from_scalar(val, self.layout_of(ty)?))
+    }
+
     pub fn unary_op(
         &self,
         un_op: mir::UnOp,
         val: ImmTy<'tcx, M::PointerTag>,
-    ) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
+    ) -> InterpResult<'tcx, ImmTy<'tcx, M::PointerTag>> {
         use rustc::mir::UnOp::*;
 
         let layout = val.layout;
@@ -330,7 +355,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     Not => !val,
                     _ => bug!("Invalid bool op {:?}", un_op)
                 };
-                Ok(Scalar::from_bool(res))
+                Ok(ImmTy::from_scalar(Scalar::from_bool(res), self.layout_of(self.tcx.types.bool)?))
             }
             ty::Float(fty) => {
                 let res = match (un_op, fty) {
@@ -338,7 +363,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     (Neg, FloatTy::F64) => Scalar::from_f64(-val.to_f64()?),
                     _ => bug!("Invalid float op {:?}", un_op)
                 };
-                Ok(res)
+                Ok(ImmTy::from_scalar(res, layout))
             }
             _ => {
                 assert!(layout.ty.is_integral());
@@ -351,7 +376,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     }
                 };
                 // res needs tuncating
-                Ok(Scalar::from_uint(self.truncate(res, layout), layout.size))
+                Ok(ImmTy::from_uint(self.truncate(res, layout), layout))
             }
         }
     }
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 16686c3800f..ef9f20d5c97 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -45,7 +45,7 @@ pub enum Place<Tag=(), Id=AllocId> {
 
 #[derive(Copy, Clone, Debug)]
 pub struct PlaceTy<'tcx, Tag=()> {
-    place: Place<Tag>,
+    place: Place<Tag>, // Keep this private, it helps enforce invariants
     pub layout: TyLayout<'tcx>,
 }
 
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index e55827837fa..b010bf049dd 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -177,7 +177,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // The operand always has the same type as the result.
                 let val = self.read_immediate(self.eval_operand(operand, Some(dest.layout))?)?;
                 let val = self.unary_op(un_op, val)?;
-                self.write_scalar(val, dest)?;
+                assert_eq!(val.layout, dest.layout, "layout mismatch for result of {:?}", un_op);
+                self.write_immediate(*val, dest)?;
             }
 
             Aggregate(ref kind, ref operands) => {
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 1d6b48e9da4..5de297923ce 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -7,7 +7,7 @@ use syntax::source_map::Span;
 use rustc_target::spec::abi::Abi;
 
 use super::{
-    InterpResult, PointerArithmetic, Scalar,
+    InterpResult, PointerArithmetic,
     InterpCx, Machine, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal,
 };
 
@@ -50,11 +50,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
                 for (index, &const_int) in values.iter().enumerate() {
                     // Compare using binary_op, to also support pointer values
-                    let const_int = Scalar::from_uint(const_int, discr.layout.size);
-                    let (res, _) = self.binary_op(mir::BinOp::Eq,
+                    let res = self.overflowing_binary_op(mir::BinOp::Eq,
                         discr,
-                        ImmTy::from_scalar(const_int, discr.layout),
-                    )?;
+                        ImmTy::from_uint(const_int, discr.layout),
+                    )?.0;
                     if res.to_bool()? {
                         target_block = targets[index];
                         break;
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 33447eba749..063e7796371 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -445,7 +445,6 @@ impl CloneShimBuilder<'tcx> {
         let func_ty = tcx.mk_fn_def(self.def_id, substs);
         let func = Operand::Constant(box Constant {
             span: self.span,
-            ty: func_ty,
             user_ty: None,
             literal: ty::Const::zero_sized(tcx, func_ty),
         });
@@ -505,7 +504,6 @@ impl CloneShimBuilder<'tcx> {
     fn make_usize(&self, value: u64) -> Box<Constant<'tcx>> {
         box Constant {
             span: self.span,
-            ty: self.tcx.types.usize,
             user_ty: None,
             literal: ty::Const::from_usize(self.tcx, value),
         }
@@ -745,7 +743,6 @@ fn build_call_shim<'tcx>(
             let ty = tcx.type_of(def_id);
             (Operand::Constant(box Constant {
                 span,
-                ty,
                 user_ty: None,
                 literal: ty::Const::zero_sized(tcx, ty),
              }),
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 38d26d0ba50..98d8ca58ee1 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -19,7 +19,7 @@ use syntax_pos::{Span, DUMMY_SP};
 use rustc::ty::subst::InternalSubsts;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::ty::layout::{
-    LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
+    LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
 };
 
 use crate::interpret::{
@@ -396,17 +396,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 if let ty::Slice(_) = mplace.layout.ty.sty {
                     let len = mplace.meta.unwrap().to_usize(&self.ecx).unwrap();
 
-                    Some(ImmTy {
-                        imm: Immediate::Scalar(
-                            Scalar::from_uint(
-                                len,
-                                Size::from_bits(
-                                    self.tcx.sess.target.usize_ty.bit_width().unwrap() as u64
-                                )
-                            ).into(),
-                        ),
-                        layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
-                    }.into())
+                    Some(ImmTy::from_uint(
+                        len,
+                        self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
+                    ).into())
                 } else {
                     trace!("not slice: {:?}", mplace.layout.ty.sty);
                     None
@@ -414,12 +407,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             },
             Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
                 type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(
-                    ImmTy {
-                        imm: Immediate::Scalar(
-                            Scalar::from_uint(n, self.tcx.data_layout.pointer_size).into()
-                        ),
-                        layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
-                    }.into()
+                    ImmTy::from_uint(
+                        n,
+                        self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
+                    ).into()
                 ))
             }
             Rvalue::UnaryOp(op, ref arg) => {
@@ -452,11 +443,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     // Now run the actual operation.
                     this.ecx.unary_op(op, prim)
                 })?;
-                let res = ImmTy {
-                    imm: Immediate::Scalar(val.into()),
-                    layout: place_layout,
-                };
-                Some(res.into())
+                Some(val.into())
             }
             Rvalue::CheckedBinaryOp(op, ref left, ref right) |
             Rvalue::BinaryOp(op, ref left, ref right) => {
@@ -510,8 +497,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     this.ecx.read_immediate(left)
                 })?;
                 trace!("const evaluating {:?} for {:?} and {:?}", op, left, right);
-                let (val, overflow) = self.use_ecx(source_info, |this| {
-                    this.ecx.binary_op(op, l, r)
+                let (val, overflow, _ty) = self.use_ecx(source_info, |this| {
+                    this.ecx.overflowing_binary_op(op, l, r)
                 })?;
                 let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
                     Immediate::ScalarPair(
@@ -539,7 +526,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         Operand::Constant(Box::new(
             Constant {
                 span,
-                ty,
                 user_ty: None,
                 literal: self.tcx.mk_const(*ty::Const::from_scalar(
                     self.tcx,
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 0a021d9b8fa..4480d1e0a05 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -527,7 +527,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     fn constant_bool(&self, span: Span, val: bool) -> Rvalue<'tcx> {
         Rvalue::Use(Operand::Constant(Box::new(Constant {
             span,
-            ty: self.tcx.types.bool,
             user_ty: None,
             literal: ty::Const::from_bool(self.tcx, val),
         })))
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 94bb70e10aa..f6941880240 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -975,7 +975,6 @@ fn insert_panic_block<'tcx>(
     let term = TerminatorKind::Assert {
         cond: Operand::Constant(box Constant {
             span: body.span,
-            ty: tcx.types.bool,
             user_ty: None,
             literal: ty::Const::from_bool(tcx, false),
         }),
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 40cb1fbdc57..bc7bd39be48 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -328,7 +328,7 @@ impl Inliner<'tcx> {
                 }
 
                 TerminatorKind::Call {func: Operand::Constant(ref f), .. } => {
-                    if let ty::FnDef(def_id, _) = f.ty.sty {
+                    if let ty::FnDef(def_id, _) = f.literal.ty.sty {
                         // Don't give intrinsics the extra penalty for calls
                         let f = tcx.fn_sig(def_id);
                         if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index 55429265036..b2d063a1f4e 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -97,8 +97,7 @@ impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
             let place_ty = place.ty(&self.body.local_decls, self.tcx).ty;
             if let ty::Array(_, len) = place_ty.sty {
                 let span = self.body.source_info(location).span;
-                let ty = self.tcx.types.usize;
-                let constant = Constant { span, ty, literal: len, user_ty: None };
+                let constant = Constant { span, literal: len, user_ty: None };
                 self.optimizations.arrays_lengths.insert(location, constant);
             }
         }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index dcfc80968f3..649cccc36c3 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -249,7 +249,7 @@ trait Qualif {
                 if let ConstValue::Unevaluated(def_id, _) = constant.literal.val {
                     // Don't peek inside trait associated constants.
                     if cx.tcx.trait_of_item(def_id).is_some() {
-                        Self::in_any_value_of_ty(cx, constant.ty).unwrap_or(false)
+                        Self::in_any_value_of_ty(cx, constant.literal.ty).unwrap_or(false)
                     } else {
                         let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(def_id);
 
@@ -258,7 +258,7 @@ trait Qualif {
                         // Just in case the type is more specific than
                         // the definition, e.g., impl associated const
                         // with type parameters, take it into account.
-                        qualif && Self::mask_for_ty(cx, constant.ty)
+                        qualif && Self::mask_for_ty(cx, constant.literal.ty)
                     }
                 } else {
                     false
@@ -537,9 +537,9 @@ impl Qualif for IsNotPromotable {
                             | "cttz_nonzero"
                             | "ctlz"
                             | "ctlz_nonzero"
-                            | "overflowing_add"
-                            | "overflowing_sub"
-                            | "overflowing_mul"
+                            | "wrapping_add"
+                            | "wrapping_sub"
+                            | "wrapping_mul"
                             | "unchecked_shl"
                             | "unchecked_shr"
                             | "rotate_left"
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index b84bc31ec2a..334d0cee9fb 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -379,9 +379,9 @@ fn is_intrinsic_whitelisted(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
         | "add_with_overflow" // ~> .overflowing_add
         | "sub_with_overflow" // ~> .overflowing_sub
         | "mul_with_overflow" // ~> .overflowing_mul
-        | "overflowing_add" // ~> .wrapping_add
-        | "overflowing_sub" // ~> .wrapping_sub
-        | "overflowing_mul" // ~> .wrapping_mul
+        | "wrapping_add" // ~> .wrapping_add
+        | "wrapping_sub" // ~> .wrapping_sub
+        | "wrapping_mul" // ~> .wrapping_mul
         | "saturating_add" // ~> .saturating_add
         | "saturating_sub" // ~> .saturating_sub
         | "unchecked_shl" // ~> .wrapping_shl
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 7fe8480c819..598de3a77e6 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -224,7 +224,7 @@ fn is_rustc_peek<'a, 'tcx>(
     if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
         if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind {
             if let mir::Operand::Constant(ref func) = *oper {
-                if let ty::FnDef(def_id, _) = func.ty.sty {
+                if let ty::FnDef(def_id, _) = func.literal.ty.sty {
                     let abi = tcx.fn_sig(def_id).abi();
                     let name = tcx.item_name(def_id);
                     if abi == Abi::RustIntrinsic && name == sym::rustc_peek {
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 52fd645e38e..c5561a1ae0d 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -970,7 +970,6 @@ where
     fn constant_usize(&self, val: u16) -> Operand<'tcx> {
         Operand::Constant(box Constant {
             span: self.source_info.span,
-            ty: self.tcx().types.usize,
             user_ty: None,
             literal: ty::Const::from_usize(self.tcx(), val.into()),
         })
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 68880fc345a..ac2701971df 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -397,10 +397,9 @@ impl ExtraComments<'tcx> {
 impl Visitor<'tcx> for ExtraComments<'tcx> {
     fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
         self.super_constant(constant, location);
-        let Constant { span, ty, user_ty, literal } = constant;
+        let Constant { span, user_ty, literal } = constant;
         self.push("mir::Constant");
         self.push(&format!("+ span: {:?}", span));
-        self.push(&format!("+ ty: {:?}", ty));
         if let Some(user_ty) = user_ty {
             self.push(&format!("+ user_ty: {:?}", user_ty));
         }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 0a32b0c6e95..42428456b6e 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -1,9 +1,11 @@
-//! Reduced graph building.
+//! After we obtain a fresh AST fragment from a macro, code in this module helps to integrate
+//! that fragment into the module structures that are already partially built.
 //!
-//! Here we build the "reduced graph": the graph of the module tree without
-//! any imports resolved.
+//! Items from the fragment are placed into modules,
+//! unexpanded macros in the fragment are visited and registered.
+//! Imports are also considered items and placed into modules here, but not resolved yet.
 
-use crate::macros::{InvocationData, LegacyBinding, LegacyScope};
+use crate::macros::{LegacyBinding, LegacyScope};
 use crate::resolve_imports::ImportDirective;
 use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
 use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding};
@@ -14,6 +16,7 @@ use crate::{ResolutionError, Determinacy, PathResult, CrateLint};
 use rustc::bug;
 use rustc::hir::def::{self, *};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
+use rustc::hir::map::DefCollector;
 use rustc::ty;
 use rustc::middle::cstore::CrateStore;
 use rustc_metadata::cstore::LoadedMacro;
@@ -30,6 +33,7 @@ use syntax::attr;
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
 use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
+use syntax::ext::expand::AstFragment;
 use syntax::ext::hygiene::ExpnId;
 use syntax::feature_gate::is_builtin_attr;
 use syntax::parse::token::{self, Token};
@@ -67,7 +71,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId) {
     }
 }
 
-pub(crate) struct IsMacroExport;
+struct IsMacroExport;
 
 impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport) {
     fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> &'a NameBinding<'a> {
@@ -84,7 +88,7 @@ impl<'a> ToNameBinding<'a> for (Res, ty::Visibility, Span, ExpnId, IsMacroExport
 impl<'a> Resolver<'a> {
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    pub fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
+    crate fn define<T>(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T)
         where T: ToNameBinding<'a>,
     {
         let binding = def.to_name_binding(self.arenas);
@@ -93,7 +97,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
+    crate fn get_module(&mut self, def_id: DefId) -> Module<'a> {
         if def_id.krate == LOCAL_CRATE {
             return self.module_map[&def_id]
         }
@@ -119,7 +123,7 @@ impl<'a> Resolver<'a> {
         module
     }
 
-    pub fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
+    crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
         let def_id = match self.macro_defs.get(&expn_id) {
             Some(def_id) => *def_id,
             None => return self.graph_root,
@@ -141,7 +145,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
+    fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
         if let Some(ext) = self.macro_map.get(&def_id) {
             return Some(ext.clone());
         }
@@ -156,23 +160,45 @@ impl<'a> Resolver<'a> {
         Some(ext)
     }
 
-    /// Ensures that the reduced graph rooted at the given external module
-    /// is built, building it if it is not.
-    pub fn populate_module_if_necessary(&mut self, module: Module<'a>) {
-        if module.populated.get() { return }
-        let def_id = module.def_id().unwrap();
+    // FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
+    crate fn build_reduced_graph(
+        &mut self,
+        fragment: &AstFragment,
+        extra_placeholders: &[NodeId],
+        parent_scope: ParentScope<'a>,
+    ) -> LegacyScope<'a> {
+        let mut def_collector = DefCollector::new(&mut self.definitions, parent_scope.expansion);
+        fragment.visit_with(&mut def_collector);
+        for placeholder in extra_placeholders {
+            def_collector.visit_macro_invoc(*placeholder);
+        }
+
+        let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope };
+        fragment.visit_with(&mut visitor);
+        for placeholder in extra_placeholders {
+            visitor.parent_scope.legacy = visitor.visit_invoc(*placeholder);
+        }
+
+        visitor.parent_scope.legacy
+    }
+
+    crate fn build_reduced_graph_external(&mut self, module: Module<'a>) {
+        let def_id = module.def_id().expect("unpopulated module without a def-id");
         for child in self.cstore.item_children_untracked(def_id, self.session) {
             let child = child.map_id(|_| panic!("unexpected id"));
-            BuildReducedGraphVisitor { parent_scope: self.dummy_parent_scope(), r: self }
-                .build_reduced_graph_for_external_crate_res(module, child);
+            BuildReducedGraphVisitor { r: self, parent_scope: ParentScope::module(module) }
+                .build_reduced_graph_for_external_crate_res(child);
         }
-        module.populated.set(true)
     }
 }
 
-pub struct BuildReducedGraphVisitor<'a, 'b> {
-    pub r: &'b mut Resolver<'a>,
-    pub parent_scope: ParentScope<'a>,
+struct BuildReducedGraphVisitor<'a, 'b> {
+    r: &'b mut Resolver<'a>,
+    parent_scope: ParentScope<'a>,
+}
+
+impl<'a> AsMut<Resolver<'a>> for BuildReducedGraphVisitor<'a, '_> {
+    fn as_mut(&mut self) -> &mut Resolver<'a> { self.r }
 }
 
 impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
@@ -300,10 +326,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         root_id: NodeId,
         vis: ty::Visibility,
     ) {
-        let parent_scope = &self.parent_scope;
-        let current_module = parent_scope.module;
+        let current_module = self.parent_scope.module;
         let directive = self.r.arenas.alloc_import_directive(ImportDirective {
-            parent_scope: parent_scope.clone(),
+            parent_scope: self.parent_scope,
             module_path,
             imported_module: Cell::new(None),
             subclass,
@@ -593,15 +618,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                     self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
                 };
 
-                self.r.populate_module_if_necessary(module);
-
                 let used = self.process_legacy_macro_imports(item, module);
                 let binding =
                     (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
                 let directive = self.r.arenas.alloc_import_directive(ImportDirective {
                     root_id: item.id,
                     id: item.id,
-                    parent_scope: self.parent_scope.clone(),
+                    parent_scope: self.parent_scope,
                     imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
                     subclass: ImportDirectiveSubclass::ExternCrate {
                         source: orig_name,
@@ -706,7 +729,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
 
                 for variant in &(*enum_definition).variants {
-                    self.build_reduced_graph_for_variant(variant, module, vis, expansion);
+                    self.build_reduced_graph_for_variant(variant, module, vis);
                 }
             }
 
@@ -797,8 +820,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     fn build_reduced_graph_for_variant(&mut self,
                                        variant: &Variant,
                                        parent: Module<'a>,
-                                       vis: ty::Visibility,
-                                       expn_id: ExpnId) {
+                                       vis: ty::Visibility) {
+        let expn_id = self.parent_scope.expansion;
         let ident = variant.ident;
 
         // Define a name in the type namespace.
@@ -861,20 +884,19 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     }
 
     /// Builds the reduced graph for a single item in an external crate.
-    fn build_reduced_graph_for_external_crate_res(
-        &mut self,
-        parent: Module<'a>,
-        child: Export<ast::NodeId>,
-    ) {
+    fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>) {
+        let parent = self.parent_scope.module;
         let Export { ident, res, vis, span } = child;
         // FIXME: We shouldn't create the gensym here, it should come from metadata,
         // but metadata cannot encode gensyms currently, so we create it here.
         // This is only a guess, two equivalent idents may incorrectly get different gensyms here.
         let ident = ident.gensym_if_underscore();
         let expansion = ExpnId::root(); // FIXME(jseyfried) intercrate hygiene
+        // Record primary definitions.
         match res {
             Res::Def(kind @ DefKind::Mod, def_id)
-            | Res::Def(kind @ DefKind::Enum, def_id) => {
+            | Res::Def(kind @ DefKind::Enum, def_id)
+            | Res::Def(kind @ DefKind::Trait, def_id) => {
                 let module = self.r.new_module(parent,
                                              ModuleKind::Def(kind, def_id, ident.name),
                                              def_id,
@@ -882,70 +904,55 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                                              span);
                 self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
             }
-            Res::Def(DefKind::Variant, _)
+            Res::Def(DefKind::Struct, _)
+            | Res::Def(DefKind::Union, _)
+            | Res::Def(DefKind::Variant, _)
             | Res::Def(DefKind::TyAlias, _)
             | Res::Def(DefKind::ForeignTy, _)
             | Res::Def(DefKind::OpaqueTy, _)
             | Res::Def(DefKind::TraitAlias, _)
+            | Res::Def(DefKind::AssocTy, _)
+            | Res::Def(DefKind::AssocOpaqueTy, _)
             | Res::PrimTy(..)
-            | Res::ToolMod => {
-                self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
-            }
+            | Res::ToolMod =>
+                self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)),
             Res::Def(DefKind::Fn, _)
+            | Res::Def(DefKind::Method, _)
             | Res::Def(DefKind::Static, _)
             | Res::Def(DefKind::Const, _)
-            | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _) => {
-                self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion));
-            }
-            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
-                self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion));
-
-                if let Some(struct_def_id) =
-                        self.r.cstore.def_key(def_id).parent
-                            .map(|index| DefId { krate: def_id.krate, index: index }) {
-                    self.r.struct_constructors.insert(struct_def_id, (res, vis));
-                }
-            }
-            Res::Def(DefKind::Trait, def_id) => {
-                let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name);
-                let module = self.r.new_module(parent,
-                                             module_kind,
-                                             parent.normal_ancestor_id,
-                                             expansion,
-                                             span);
-                self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
-
-                for child in self.r.cstore.item_children_untracked(def_id, self.r.session) {
-                    let res = child.res.map_id(|_| panic!("unexpected id"));
-                    let ns = if let Res::Def(DefKind::AssocTy, _) = res {
-                        TypeNS
-                    } else { ValueNS };
-                    self.r.define(module, child.ident, ns,
-                                (res, ty::Visibility::Public, DUMMY_SP, expansion));
-
-                    if self.r.cstore.associated_item_cloned_untracked(child.res.def_id())
-                           .method_has_self_argument {
-                        self.r.has_self.insert(res.def_id());
-                    }
-                }
-                module.populated.set(true);
-            }
+            | Res::Def(DefKind::AssocConst, _)
+            | Res::Def(DefKind::Ctor(..), _) =>
+                self.r.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)),
+            Res::Def(DefKind::Macro(..), _)
+            | Res::NonMacroAttr(..) =>
+                self.r.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion)),
+            Res::Def(DefKind::TyParam, _) | Res::Def(DefKind::ConstParam, _)
+            | Res::Local(..) | Res::SelfTy(..) | Res::SelfCtor(..) | Res::Err =>
+                bug!("unexpected resolution: {:?}", res)
+        }
+        // Record some extra data for better diagnostics.
+        match res {
             Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
-                self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
-
-                // Record field names for error reporting.
                 let field_names = self.r.cstore.struct_field_names_untracked(def_id);
                 self.insert_field_names(def_id, field_names);
             }
-            Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
-                self.r.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion));
+            Res::Def(DefKind::Method, def_id) => {
+                if self.r.cstore.associated_item_cloned_untracked(def_id).method_has_self_argument {
+                    self.r.has_self.insert(def_id);
+                }
+            }
+            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
+                let parent = self.r.cstore.def_key(def_id).parent;
+                if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) {
+                    self.r.struct_constructors.insert(struct_def_id, (res, vis));
+                }
             }
-            _ => bug!("unexpected resolution: {:?}", res)
+            _ => {}
         }
     }
 
     fn legacy_import_macro(&mut self,
-                           name: Name,
+                           name: ast::Name,
                            binding: &'a NameBinding<'a>,
                            span: Span,
                            allow_shadowing: bool) {
@@ -997,7 +1004,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 |this: &Self, span| this.r.arenas.alloc_import_directive(ImportDirective {
             root_id: item.id,
             id: item.id,
-            parent_scope: this.parent_scope.clone(),
+            parent_scope: this.parent_scope,
             imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
             subclass: ImportDirectiveSubclass::MacroUse,
             use_span_with_attributes: item.span_with_attributes(),
@@ -1014,9 +1021,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         if let Some(span) = import_all {
             let directive = macro_use_directive(self, span);
             self.r.potentially_unused_imports.push(directive);
-            module.for_each_child(|ident, ns, binding| if ns == MacroNS {
-                let imported_binding = self.r.import(binding, directive);
-                self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
+            module.for_each_child(self, |this, ident, ns, binding| if ns == MacroNS {
+                let imported_binding = this.r.import(binding, directive);
+                this.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
             });
         } else {
             for ident in single_imports.iter().cloned() {
@@ -1066,20 +1073,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         false
     }
 
-    fn visit_invoc(&mut self, id: ast::NodeId) -> &'a InvocationData<'a> {
+    fn visit_invoc(&mut self, id: NodeId) -> LegacyScope<'a> {
         let invoc_id = id.placeholder_to_expn_id();
 
-        self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
+        self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
 
-        let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData {
-            module: self.parent_scope.module,
-            parent_legacy_scope: self.parent_scope.legacy,
-            output_legacy_scope: Cell::new(None),
-        });
-        let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data);
-        assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation");
+        let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
+        assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
 
-        invocation_data
+        LegacyScope::Invocation(invoc_id)
     }
 
     fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
@@ -1180,7 +1182,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
                 return
             }
             ItemKind::Mac(..) => {
-                self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id));
+                self.parent_scope.legacy = self.visit_invoc(item.id);
                 return
             }
             ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
@@ -1199,7 +1201,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_stmt(&mut self, stmt: &'b ast::Stmt) {
         if let ast::StmtKind::Mac(..) = stmt.node {
-            self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id));
+            self.parent_scope.legacy = self.visit_invoc(stmt.id);
         } else {
             visit::walk_stmt(self, stmt);
         }
@@ -1267,9 +1269,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_attribute(&mut self, attr: &'b ast::Attribute) {
         if !attr.is_sugared_doc && is_builtin_attr(attr) {
-            self.parent_scope.module.builtin_attrs.borrow_mut().push((
-                attr.path.segments[0].ident, self.parent_scope.clone()
-            ));
+            self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope));
         }
         visit::walk_attribute(self, attr);
     }
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 1de67edb95c..b79e0c2bd3b 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -73,20 +73,23 @@ crate fn add_typo_suggestion(
     false
 }
 
-crate fn add_module_candidates(
-    module: Module<'_>, names: &mut Vec<TypoSuggestion>, filter_fn: &impl Fn(Res) -> bool
-) {
-    for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
-        if let Some(binding) = resolution.borrow().binding {
-            let res = binding.res();
-            if filter_fn(res) {
-                names.push(TypoSuggestion::from_res(ident.name, res));
+impl<'a> Resolver<'a> {
+    crate fn add_module_candidates(
+        &mut self,
+        module: Module<'a>,
+        names: &mut Vec<TypoSuggestion>,
+        filter_fn: &impl Fn(Res) -> bool,
+    ) {
+        for (&(ident, _), resolution) in self.resolutions(module).borrow().iter() {
+            if let Some(binding) = resolution.borrow().binding {
+                let res = binding.res();
+                if filter_fn(res) {
+                    names.push(TypoSuggestion::from_res(ident.name, res));
+                }
             }
         }
     }
-}
 
-impl<'a> Resolver<'a> {
     /// Combines an error with provided span and emits it.
     ///
     /// This takes the error provided, combines it with the span and any additional spans inside the
@@ -166,12 +169,14 @@ impl<'a> Resolver<'a> {
                 err
             }
             ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => {
-                let mut err = struct_span_err!(self.session,
-                                                span,
-                                                E0403,
-                                                "the name `{}` is already used for a generic \
-                                                parameter in this list of generic parameters",
-                                                name);
+                let mut err = struct_span_err!(
+                    self.session,
+                    span,
+                    E0403,
+                    "the name `{}` is already used for a generic \
+                     parameter in this item's generic parameters",
+                    name,
+                );
                 err.span_label(span, "already used");
                 err.span_label(first_use_span, format!("first use of `{}`", name));
                 err
@@ -376,9 +381,9 @@ impl<'a> Resolver<'a> {
                 Scope::DeriveHelpers => {
                     let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
                     if filter_fn(res) {
-                        for derive in &parent_scope.derives {
+                        for derive in parent_scope.derives {
                             let parent_scope =
-                                &ParentScope { derives: Vec::new(), ..*parent_scope };
+                                &ParentScope { derives: &[], ..*parent_scope };
                             if let Ok((Some(ext), _)) = this.resolve_macro_path(
                                 derive, Some(MacroKind::Derive), parent_scope, false, false
                             ) {
@@ -402,10 +407,10 @@ impl<'a> Resolver<'a> {
                 Scope::CrateRoot => {
                     let root_ident = Ident::new(kw::PathRoot, ident.span);
                     let root_module = this.resolve_crate_root(root_ident);
-                    add_module_candidates(root_module, &mut suggestions, filter_fn);
+                    this.add_module_candidates(root_module, &mut suggestions, filter_fn);
                 }
                 Scope::Module(module) => {
-                    add_module_candidates(module, &mut suggestions, filter_fn);
+                    this.add_module_candidates(module, &mut suggestions, filter_fn);
                 }
                 Scope::MacroUsePrelude => {
                     suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| {
@@ -453,9 +458,9 @@ impl<'a> Resolver<'a> {
                 Scope::StdLibPrelude => {
                     if let Some(prelude) = this.prelude {
                         let mut tmp_suggestions = Vec::new();
-                        add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
+                        this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
                         suggestions.extend(tmp_suggestions.into_iter().filter(|s| {
-                            use_prelude || this.is_builtin_macro(s.res.opt_def_id())
+                            use_prelude || this.is_builtin_macro(s.res)
                         }));
                     }
                 }
@@ -509,11 +514,9 @@ impl<'a> Resolver<'a> {
         while let Some((in_module,
                         path_segments,
                         in_module_is_extern)) = worklist.pop() {
-            self.populate_module_if_necessary(in_module);
-
             // We have to visit module children in deterministic order to avoid
             // instabilities in reported imports (#43552).
-            in_module.for_each_child_stable(|ident, ns, name_binding| {
+            in_module.for_each_child_stable(self, |this, ident, ns, name_binding| {
                 // avoid imports entirely
                 if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
                 // avoid non-importable candidates as well
@@ -547,7 +550,7 @@ impl<'a> Resolver<'a> {
                         // outside crate private modules => no need to check this)
                         if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
                             let did = match res {
-                                Res::Def(DefKind::Ctor(..), did) => self.parent(did),
+                                Res::Def(DefKind::Ctor(..), did) => this.parent(did),
                                 _ => res.opt_def_id(),
                             };
                             candidates.push(ImportSuggestion { did, path });
@@ -595,7 +598,7 @@ impl<'a> Resolver<'a> {
         where FilterFn: Fn(Res) -> bool
     {
         let mut suggestions = self.lookup_import_candidates_from_module(
-            lookup_ident, namespace, self.graph_root, Ident::with_empty_ctxt(kw::Crate), &filter_fn
+            lookup_ident, namespace, self.graph_root, Ident::with_dummy_span(kw::Crate), &filter_fn
         );
 
         if lookup_ident.span.rust_2018() {
@@ -607,8 +610,6 @@ impl<'a> Resolver<'a> {
                         krate: crate_id,
                         index: CRATE_DEF_INDEX,
                     });
-                    self.populate_module_if_necessary(&crate_root);
-
                     suggestions.extend(self.lookup_import_candidates_from_module(
                         lookup_ident, namespace, crate_root, ident, &filter_fn));
                 }
@@ -805,7 +806,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ///            at the root of the crate instead of the module where it is defined
     /// ```
     pub(crate) fn check_for_module_export_macro(
-        &self,
+        &mut self,
         directive: &'b ImportDirective<'b>,
         module: ModuleOrUniformRoot<'b>,
         ident: Ident,
@@ -826,7 +827,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             return None;
         }
 
-        let resolutions = crate_module.resolutions.borrow();
+        let resolutions = self.r.resolutions(crate_module).borrow();
         let resolution = resolutions.get(&(ident, MacroNS))?;
         let binding = resolution.borrow().binding()?;
         if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index e01f53786ed..1faaf97e981 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -526,15 +526,25 @@ Some type parameters have the same name.
 Erroneous code example:
 
 ```compile_fail,E0403
-fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
-                            //        parameter in this type parameter list
+fn f<T, T>(s: T, u: T) {} // error: the name `T` is already used for a generic
+                          //        parameter in this item's generic parameters
 ```
 
 Please verify that none of the type parameters are misspelled, and rename any
 clashing parameters. Example:
 
 ```
-fn foo<T, Y>(s: T, u: Y) {} // ok!
+fn f<T, Y>(s: T, u: Y) {} // ok!
+```
+
+Type parameters in an associated item also cannot shadow parameters from the
+containing item:
+
+```compile_fail,E0403
+trait Foo<T> {
+    fn do_something(&self) -> T;
+    fn do_something_else<T: Clone>(&self, bar: T);
+}
 ```
 "##,
 
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 358eaae11e7..e15d02a9f7e 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1,3 +1,10 @@
+//! "Late resolution" is the pass that resolves most of names in a crate beside imports and macros.
+//! It runs when the crate is fully expanded and its module structure is fully built.
+//! So it just walks through the crate and resolves all the expressions, types, etc.
+//!
+//! If you wonder why there's no `early.rs`, that's because it's split into three files -
+//! `build_reduced_graph.rs`, `macros.rs` and `resolve_imports.rs`.
+
 use GenericParameters::*;
 use RibKind::*;
 
@@ -104,6 +111,24 @@ crate enum RibKind<'a> {
     TyParamAsConstParamTy,
 }
 
+impl RibKind<'_> {
+    // Whether this rib kind contains generic parameters, as opposed to local
+    // variables.
+    crate fn contains_params(&self) -> bool {
+        match self {
+            NormalRibKind
+            | FnItemRibKind
+            | ConstantItemRibKind
+            | ModuleRibKind(_)
+            | MacroDefinition(_) => false,
+            AssocItemRibKind
+            | ItemRibKind
+            | ForwardTyParamBanRibKind
+            | TyParamAsConstParamTy => true,
+        }
+    }
+}
+
 /// A single local scope.
 ///
 /// A rib represents a scope names can live in. Note that these appear in many places, not just
@@ -352,7 +377,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type);
             }
             TyKind::ImplicitSelf => {
-                let self_ty = Ident::with_empty_ctxt(kw::SelfUpper);
+                let self_ty = Ident::with_dummy_span(kw::SelfUpper);
                 let res = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span)
                               .map_or(Res::Err, |d| d.res());
                 self.r.record_partial_res(ty.id, PartialRes::new(res));
@@ -442,7 +467,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 GenericParamKind::Type { ref default, .. } => {
                     found_default |= default.is_some();
                     if found_default {
-                        Some((Ident::with_empty_ctxt(param.ident.name), Res::Err))
+                        Some((Ident::with_dummy_span(param.ident.name), Res::Err))
                     } else {
                         None
                     }
@@ -459,7 +484,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                     false
                 }
             })
-            .map(|param| (Ident::with_empty_ctxt(param.ident.name), Res::Err)));
+            .map(|param| (Ident::with_dummy_span(param.ident.name), Res::Err)));
 
         for param in &generics.params {
             match param.kind {
@@ -476,7 +501,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                     }
 
                     // Allow all following defaults to refer to this type parameter.
-                    default_ban_rib.bindings.remove(&Ident::with_empty_ctxt(param.ident.name));
+                    default_ban_rib.bindings.remove(&Ident::with_dummy_span(param.ident.name));
                 }
                 GenericParamKind::Const { ref ty } => {
                     self.ribs[TypeNS].push(const_ty_param_ban_rib);
@@ -501,8 +526,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> {
         // During late resolution we only track the module component of the parent scope,
         // although it may be useful to track other components as well for diagnostics.
-        let parent_scope = resolver.dummy_parent_scope();
         let graph_root = resolver.graph_root;
+        let parent_scope = ParentScope::module(graph_root);
         LateResolutionVisitor {
             r: resolver,
             parent_scope,
@@ -574,7 +599,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
 
-            self.r.finalize_current_module_macro_resolutions(module);
             let ret = f(self);
 
             self.parent_scope.module = orig_module;
@@ -792,6 +816,19 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut function_value_rib = Rib::new(rib_kind);
                 let mut seen_bindings = FxHashMap::default();
+                // We also can't shadow bindings from the parent item
+                if let AssocItemRibKind = rib_kind {
+                    let mut add_bindings_for_ns = |ns| {
+                        let parent_rib = self.ribs[ns].iter()
+                            .rfind(|rib| if let ItemRibKind = rib.kind { true } else { false })
+                            .expect("associated item outside of an item");
+                        seen_bindings.extend(
+                            parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span)),
+                        );
+                    };
+                    add_bindings_for_ns(ValueNS);
+                    add_bindings_for_ns(TypeNS);
+                }
                 for param in &generics.params {
                     match param.kind {
                         GenericParamKind::Lifetime { .. } => {}
@@ -965,7 +1002,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // Plain insert (no renaming, since types are not currently hygienic)
-        self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res);
+        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
         self.ribs[TypeNS].push(self_type_rib);
         f(self);
         self.ribs[TypeNS].pop();
@@ -976,7 +1013,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     {
         let self_res = Res::SelfCtor(impl_id);
         let mut self_type_rib = Rib::new(NormalRibKind);
-        self_type_rib.bindings.insert(Ident::with_empty_ctxt(kw::SelfUpper), self_res);
+        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
         self.ribs[ValueNS].push(self_type_rib);
         f(self);
         self.ribs[ValueNS].pop();
@@ -1227,7 +1264,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.parent_scope.module = anonymous_module;
-            self.r.finalize_current_module_macro_resolutions(anonymous_module);
         } else {
             self.ribs[ValueNS].push(Rib::new(NormalRibKind));
         }
@@ -1476,7 +1512,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     self.r.trait_map.insert(id, traits);
                 }
 
-                let mut std_path = vec![Segment::from_ident(Ident::with_empty_ctxt(sym::std))];
+                let mut std_path = vec![Segment::from_ident(Ident::with_dummy_span(sym::std))];
                 std_path.extend(path);
                 if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
                     let cl = CrateLint::No;
@@ -1507,7 +1543,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     fn self_type_is_available(&mut self, span: Span) -> bool {
         let binding = self.resolve_ident_in_lexical_scope(
-            Ident::with_empty_ctxt(kw::SelfUpper),
+            Ident::with_dummy_span(kw::SelfUpper),
             TypeNS,
             None,
             span,
@@ -1924,7 +1960,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut traits = module.traits.borrow_mut();
         if traits.is_none() {
             let mut collected_traits = Vec::new();
-            module.for_each_child(|name, ns, binding| {
+            module.for_each_child(self.r, |_, name, ns, binding| {
                 if ns != TypeNS { return }
                 match binding.res() {
                     Res::Def(DefKind::Trait, _) |
@@ -1984,7 +2020,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
 impl<'a> Resolver<'a> {
     pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
-        self.finalize_current_module_macro_resolutions(self.graph_root);
         let mut late_resolution_visitor = LateResolutionVisitor::new(self);
         visit::walk_crate(&mut late_resolution_visitor, krate);
         for (id, span) in late_resolution_visitor.unused_labels.iter() {
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 68f9c1684d6..a822fa049ca 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -1,8 +1,7 @@
 use crate::{CrateLint, Module, ModuleKind, ModuleOrUniformRoot};
 use crate::{PathResult, PathSource, Segment};
 use crate::path_names_to_string;
-use crate::diagnostics::{add_typo_suggestion, add_module_candidates};
-use crate::diagnostics::{ImportSuggestion, TypoSuggestion};
+use crate::diagnostics::{add_typo_suggestion, ImportSuggestion, TypoSuggestion};
 use crate::late::{LateResolutionVisitor, RibKind};
 
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
@@ -548,7 +547,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                 // Items in scope
                 if let RibKind::ModuleRibKind(module) = rib.kind {
                     // Items from this module
-                    add_module_candidates(module, &mut names, &filter_fn);
+                    self.r.add_module_candidates(module, &mut names, &filter_fn);
 
                     if let ModuleKind::Block(..) = module.kind {
                         // We can see through blocks
@@ -577,7 +576,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                             }));
 
                             if let Some(prelude) = self.r.prelude {
-                                add_module_candidates(prelude, &mut names, &filter_fn);
+                                self.r.add_module_candidates(prelude, &mut names, &filter_fn);
                             }
                         }
                         break;
@@ -599,7 +598,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                 mod_path, Some(TypeNS), false, span, CrateLint::No
             ) {
                 if let ModuleOrUniformRoot::Module(module) = module {
-                    add_module_candidates(module, &mut names, &filter_fn);
+                    self.r.add_module_candidates(module, &mut names, &filter_fn);
                 }
             }
         }
@@ -717,9 +716,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             // abort if the module is already found
             if result.is_some() { break; }
 
-            self.r.populate_module_if_necessary(in_module);
-
-            in_module.for_each_child_stable(|ident, _, name_binding| {
+            in_module.for_each_child_stable(self.r, |_, ident, _, name_binding| {
                 // abort if the module is already found or if name_binding is private external
                 if result.is_some() || !name_binding.vis.is_visible_locally() {
                     return
@@ -750,10 +747,8 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
     fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> {
         self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
-            self.r.populate_module_if_necessary(enum_module);
-
             let mut variants = Vec::new();
-            enum_module.for_each_child_stable(|ident, _, name_binding| {
+            enum_module.for_each_child_stable(self.r, |_, ident, _, name_binding| {
                 if let Res::Def(DefKind::Variant, _) = name_binding.res() {
                     let mut segms = enum_import_suggestion.path.segments.clone();
                     segms.push(ast::PathSegment::from_ident(ident));
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 8a4a60c16b0..2dd0ad13c52 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1,3 +1,12 @@
+//! This crate is responsible for the part of name resolution that doesn't require type checker.
+//!
+//! Module structure of the crate is built here.
+//! Paths in macros, imports, expressions, types, patterns are resolved here.
+//! Label names are resolved here as well.
+//!
+//! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`.
+//! Lifetime names are resolved in `librustc/middle/resolve_lifetime.rs`.
+
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![feature(crate_visibility_modifier)]
@@ -54,7 +63,7 @@ use diagnostics::{Suggestion, ImportSuggestion};
 use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding};
 use late::{PathSource, Rib, RibKind::*};
 use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver};
-use macros::{InvocationData, LegacyBinding, LegacyScope};
+use macros::{LegacyBinding, LegacyScope};
 
 type Res = def::Res<NodeId>;
 
@@ -122,12 +131,25 @@ enum ScopeSet {
 /// Serves as a starting point for the scope visitor.
 /// This struct is currently used only for early resolution (imports and macros),
 /// but not for late resolution yet.
-#[derive(Clone, Debug)]
+#[derive(Clone, Copy, Debug)]
 pub struct ParentScope<'a> {
     module: Module<'a>,
     expansion: ExpnId,
     legacy: LegacyScope<'a>,
-    derives: Vec<ast::Path>,
+    derives: &'a [ast::Path],
+}
+
+impl<'a> ParentScope<'a> {
+    /// Creates a parent scope with the passed argument used as the module scope component,
+    /// and other scope components set to default empty values.
+    pub fn module(module: Module<'a>) -> ParentScope<'a> {
+        ParentScope {
+            module,
+            expansion: ExpnId::root(),
+            legacy: LegacyScope::Empty,
+            derives: &[],
+        }
+    }
 }
 
 #[derive(Eq)]
@@ -274,7 +296,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
                 ItemKind::Use(..) => {
                     // don't suggest placing a use before the prelude
                     // import or other generated ones
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
@@ -284,7 +306,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
                 ItemKind::ExternCrate(_) => {}
                 // but place them before the first other item
                 _ => if self.span.map_or(true, |span| item.span < span ) {
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         // don't insert between attributes and an item
                         if item.attrs.is_empty() {
                             self.span = Some(item.span.shrink_to_lo());
@@ -409,6 +431,8 @@ impl ModuleKind {
     }
 }
 
+type Resolutions<'a> = RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>;
+
 /// One node in the tree of modules.
 pub struct ModuleData<'a> {
     parent: Option<Module<'a>>,
@@ -417,15 +441,14 @@ pub struct ModuleData<'a> {
     // The def id of the closest normal module (`mod`) ancestor (including this module).
     normal_ancestor_id: DefId,
 
-    resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
-    single_segment_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
-                                                   Option<&'a NameBinding<'a>>)>>,
-    multi_segment_macro_resolutions: RefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
-                                                  Option<Res>)>>,
-    builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
+    // Mapping between names and their (possibly in-progress) resolutions in this module.
+    // Resolutions in modules from other crates are not populated until accessed.
+    lazy_resolutions: Resolutions<'a>,
+    // True if this is a module from other crate that needs to be populated on access.
+    populate_on_access: Cell<bool>,
 
     // Macro invocations that can expand into items in this module.
-    unresolved_invocations: RefCell<FxHashSet<ExpnId>>,
+    unexpanded_invocations: RefCell<FxHashSet<ExpnId>>,
 
     no_implicit_prelude: bool,
 
@@ -435,11 +458,6 @@ pub struct ModuleData<'a> {
     // Used to memoize the traits in this module for faster searches through all traits in scope.
     traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
 
-    // Whether this module is populated. If not populated, any attempt to
-    // access the children must be preceded with a
-    // `populate_module_if_necessary` call.
-    populated: Cell<bool>,
-
     /// Span of the module itself. Used for error reporting.
     span: Span,
 
@@ -458,33 +476,34 @@ impl<'a> ModuleData<'a> {
             parent,
             kind,
             normal_ancestor_id,
-            resolutions: Default::default(),
-            single_segment_macro_resolutions: RefCell::new(Vec::new()),
-            multi_segment_macro_resolutions: RefCell::new(Vec::new()),
-            builtin_attrs: RefCell::new(Vec::new()),
-            unresolved_invocations: Default::default(),
+            lazy_resolutions: Default::default(),
+            populate_on_access: Cell::new(!normal_ancestor_id.is_local()),
+            unexpanded_invocations: Default::default(),
             no_implicit_prelude: false,
             glob_importers: RefCell::new(Vec::new()),
             globs: RefCell::new(Vec::new()),
             traits: RefCell::new(None),
-            populated: Cell::new(normal_ancestor_id.is_local()),
             span,
             expansion,
         }
     }
 
-    fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
-        for (&(ident, ns), name_resolution) in self.resolutions.borrow().iter() {
-            name_resolution.borrow().binding.map(|binding| f(ident, ns, binding));
+    fn for_each_child<R, F>(&'a self, resolver: &mut R, mut f: F)
+        where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
+    {
+        for (&(ident, ns), name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
+            name_resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
         }
     }
 
-    fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
-        let resolutions = self.resolutions.borrow();
+    fn for_each_child_stable<R, F>(&'a self, resolver: &mut R, mut f: F)
+        where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
+    {
+        let resolutions = resolver.as_mut().resolutions(self).borrow();
         let mut resolutions = resolutions.iter().collect::<Vec<_>>();
         resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.as_str(), ns));
         for &(&(ident, ns), &resolution) in resolutions.iter() {
-            resolution.borrow().binding.map(|binding| f(ident, ns, binding));
+            resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
         }
     }
 
@@ -807,7 +826,7 @@ pub struct Resolver<'a> {
 
     pub definitions: Definitions,
 
-    graph_root: Module<'a>,
+    pub graph_root: Module<'a>,
 
     prelude: Option<Module<'a>>,
     pub extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
@@ -896,15 +915,24 @@ pub struct Resolver<'a> {
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
     unused_macros: NodeMap<Span>,
     proc_macro_stubs: NodeSet,
+    /// Traces collected during macro resolution and validated when it's complete.
+    single_segment_macro_resolutions: Vec<(Ident, MacroKind, ParentScope<'a>,
+                                           Option<&'a NameBinding<'a>>)>,
+    multi_segment_macro_resolutions: Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
+                                          Option<Res>)>,
+    builtin_attrs: Vec<(Ident, ParentScope<'a>)>,
     /// Some built-in derives mark items they are applied to so they are treated specially later.
     /// Derive macros cannot modify the item themselves and have to store the markers in the global
     /// context, so they attach the markers to derive container IDs using this resolver table.
     /// FIXME: Find a way for `PartialEq` and `Eq` to emulate `#[structural_match]`
     /// by marking the produced impls rather than the original items.
     special_derives: FxHashMap<ExpnId, SpecialDerives>,
-
-    /// Maps the `ExpnId` of an expansion to its containing module or block.
-    invocations: FxHashMap<ExpnId, &'a InvocationData<'a>>,
+    /// Parent scopes in which the macros were invoked.
+    /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere.
+    invocation_parent_scopes: FxHashMap<ExpnId, ParentScope<'a>>,
+    /// Legacy scopes *produced* by expanding the macro invocations,
+    /// include all the `macro_rules` items and other invocations generated by them.
+    output_legacy_scopes: FxHashMap<ExpnId, LegacyScope<'a>>,
 
     /// Avoid duplicated errors for "name already defined".
     name_already_seen: FxHashMap<Name, Span>,
@@ -927,8 +955,8 @@ pub struct ResolverArenas<'a> {
     name_bindings: arena::TypedArena<NameBinding<'a>>,
     import_directives: arena::TypedArena<ImportDirective<'a>>,
     name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
-    invocation_data: arena::TypedArena<InvocationData<'a>>,
     legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
+    ast_paths: arena::TypedArena<ast::Path>,
 }
 
 impl<'a> ResolverArenas<'a> {
@@ -952,13 +980,16 @@ impl<'a> ResolverArenas<'a> {
     fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
         self.name_resolutions.alloc(Default::default())
     }
-    fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>)
-                             -> &'a InvocationData<'a> {
-        self.invocation_data.alloc(expansion_data)
-    }
     fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> {
         self.legacy_bindings.alloc(binding)
     }
+    fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] {
+        self.ast_paths.alloc_from_iter(paths.iter().cloned())
+    }
+}
+
+impl<'a> AsMut<Resolver<'a>> for Resolver<'a> {
+    fn as_mut(&mut self) -> &mut Resolver<'a> { self }
 }
 
 impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
@@ -985,11 +1016,11 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
         } else {
             kw::Crate
         };
-        let segments = iter::once(Ident::with_empty_ctxt(root))
+        let segments = iter::once(Ident::with_dummy_span(root))
             .chain(
                 crate_root.into_iter()
                     .chain(components.iter().cloned())
-                    .map(Ident::with_empty_ctxt)
+                    .map(Ident::with_dummy_span)
             ).map(|i| self.new_ast_path_segment(i)).collect::<Vec<_>>();
 
         let path = ast::Path {
@@ -997,7 +1028,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
             segments,
         };
 
-        let parent_scope = &self.dummy_parent_scope();
+        let parent_scope = &ParentScope::module(self.graph_root);
         let res = match self.resolve_ast_path(&path, ns, parent_scope) {
             Ok(res) => res,
             Err((span, error)) => {
@@ -1060,18 +1091,17 @@ impl<'a> Resolver<'a> {
                                        .collect();
 
         if !attr::contains_name(&krate.attrs, sym::no_core) {
-            extern_prelude.insert(Ident::with_empty_ctxt(sym::core), Default::default());
+            extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
             if !attr::contains_name(&krate.attrs, sym::no_std) {
-                extern_prelude.insert(Ident::with_empty_ctxt(sym::std), Default::default());
+                extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default());
                 if session.rust_2018() {
-                    extern_prelude.insert(Ident::with_empty_ctxt(sym::meta), Default::default());
+                    extern_prelude.insert(Ident::with_dummy_span(sym::meta), Default::default());
                 }
             }
         }
 
-        let mut invocations = FxHashMap::default();
-        invocations.insert(ExpnId::root(),
-                           arenas.alloc_invocation_data(InvocationData::root(graph_root)));
+        let mut invocation_parent_scopes = FxHashMap::default();
+        invocation_parent_scopes.insert(ExpnId::root(), ParentScope::module(graph_root));
 
         let mut macro_defs = FxHashMap::default();
         macro_defs.insert(ExpnId::root(), root_def_id);
@@ -1143,7 +1173,8 @@ impl<'a> Resolver<'a> {
             dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())),
             dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())),
             non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)],
-            invocations,
+            invocation_parent_scopes,
+            output_legacy_scopes: Default::default(),
             macro_defs,
             local_macro_def_scopes: FxHashMap::default(),
             name_already_seen: FxHashMap::default(),
@@ -1151,6 +1182,9 @@ impl<'a> Resolver<'a> {
             struct_constructors: Default::default(),
             unused_macros: Default::default(),
             proc_macro_stubs: Default::default(),
+            single_segment_macro_resolutions: Default::default(),
+            multi_segment_macro_resolutions: Default::default(),
+            builtin_attrs: Default::default(),
             special_derives: Default::default(),
             active_features:
                 features.declared_lib_features.iter().map(|(feat, ..)| *feat)
@@ -1182,9 +1216,8 @@ impl<'a> Resolver<'a> {
         f(self, MacroNS);
     }
 
-    fn is_builtin_macro(&mut self, def_id: Option<DefId>) -> bool {
-        def_id.and_then(|def_id| self.get_macro_by_def_id(def_id))
-              .map_or(false, |ext| ext.is_builtin)
+    fn is_builtin_macro(&mut self, res: Res) -> bool {
+        self.get_macro(res).map_or(false, |ext| ext.is_builtin)
     }
 
     fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
@@ -1203,6 +1236,7 @@ impl<'a> Resolver<'a> {
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
         ImportResolver { r: self }.finalize_imports();
+        self.finalize_macro_resolutions();
 
         self.late_resolve_crate(krate);
 
@@ -1223,6 +1257,20 @@ impl<'a> Resolver<'a> {
         self.arenas.alloc_module(module)
     }
 
+    fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> {
+        if module.populate_on_access.get() {
+            module.populate_on_access.set(false);
+            self.build_reduced_graph_external(module);
+        }
+        &module.lazy_resolutions
+    }
+
+    fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace)
+                  -> &'a RefCell<NameResolution<'a>> {
+        *self.resolutions(module).borrow_mut().entry((ident.modern(), ns))
+               .or_insert_with(|| self.arenas.alloc_name_resolution())
+    }
+
     fn record_use(&mut self, ident: Ident, ns: Namespace,
                   used_binding: &'a NameBinding<'a>, is_lexical_scope: bool) {
         if let Some((b2, kind)) = used_binding.ambiguity {
@@ -1319,13 +1367,15 @@ impl<'a> Resolver<'a> {
             ScopeSet::AbsolutePath(ns) => (ns, true),
             ScopeSet::Macro(_) => (MacroNS, false),
         };
+        // Jump out of trait or enum modules, they do not act as scopes.
+        let module = parent_scope.module.nearest_item_scope();
         let mut scope = match ns {
             _ if is_absolute_path => Scope::CrateRoot,
-            TypeNS | ValueNS => Scope::Module(parent_scope.module),
+            TypeNS | ValueNS => Scope::Module(module),
             MacroNS => Scope::DeriveHelpers,
         };
         let mut ident = ident.modern();
-        let mut use_prelude = !parent_scope.module.no_implicit_prelude;
+        let mut use_prelude = !module.no_implicit_prelude;
 
         loop {
             let visit = match scope {
@@ -1355,10 +1405,11 @@ impl<'a> Resolver<'a> {
                     LegacyScope::Binding(binding) => Scope::MacroRules(
                         binding.parent_legacy_scope
                     ),
-                    LegacyScope::Invocation(invoc) => Scope::MacroRules(
-                        invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope)
+                    LegacyScope::Invocation(invoc_id) => Scope::MacroRules(
+                        self.output_legacy_scopes.get(&invoc_id).cloned()
+                            .unwrap_or(self.invocation_parent_scopes[&invoc_id].legacy)
                     ),
-                    LegacyScope::Empty => Scope::Module(parent_scope.module),
+                    LegacyScope::Empty => Scope::Module(module),
                 }
                 Scope::CrateRoot => match ns {
                     TypeNS => {
@@ -1430,7 +1481,7 @@ impl<'a> Resolver<'a> {
         }
         let (general_span, modern_span) = if ident.name == kw::SelfUpper {
             // FIXME(jseyfried) improve `Self` hygiene
-            let empty_span = ident.span.with_ctxt(SyntaxContext::empty());
+            let empty_span = ident.span.with_ctxt(SyntaxContext::root());
             (empty_span, empty_span)
         } else if ns == TypeNS {
             let modern_span = ident.span.modern();
@@ -1448,7 +1499,7 @@ impl<'a> Resolver<'a> {
             debug!("walk rib\n{:?}", ribs[i].bindings);
             // Use the rib kind to determine whether we are resolving parameters
             // (modern hygiene) or local variables (legacy hygiene).
-            let rib_ident = if let AssocItemRibKind | ItemRibKind = ribs[i].kind {
+            let rib_ident = if ribs[i].kind.contains_params() {
                 modern_ident
             } else {
                 ident
@@ -1501,7 +1552,7 @@ impl<'a> Resolver<'a> {
                 self.hygienic_lexical_parent(module, &mut ident.span)
             };
             module = unwrap_or!(opt_module, break);
-            let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() };
+            let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
             let result = self.resolve_ident_in_module_unadjusted(
                 ModuleOrUniformRoot::Module(module),
                 ident,
@@ -1637,7 +1688,7 @@ impl<'a> Resolver<'a> {
             ModuleOrUniformRoot::Module(m) => {
                 if let Some(def) = ident.span.modernize_and_adjust(m.expansion) {
                     tmp_parent_scope =
-                        ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() };
+                        ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
                     adjusted_parent_scope = &tmp_parent_scope;
                 }
             }
@@ -2606,7 +2657,6 @@ impl<'a> Resolver<'a> {
                     return None;
                 };
                 let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
-                self.populate_module_if_necessary(&crate_root);
                 Some((crate_root, ty::Visibility::Public, DUMMY_SP, ExpnId::root())
                     .to_name_binding(self.arenas))
             }
@@ -2624,7 +2674,7 @@ impl<'a> Resolver<'a> {
         let path = if path_str.starts_with("::") {
             ast::Path {
                 span,
-                segments: iter::once(Ident::with_empty_ctxt(kw::PathRoot))
+                segments: iter::once(Ident::with_dummy_span(kw::PathRoot))
                     .chain({
                         path_str.split("::").skip(1).map(Ident::from_str)
                     })
@@ -2645,7 +2695,7 @@ impl<'a> Resolver<'a> {
             let def_id = self.definitions.local_def_id(module_id);
             self.module_map.get(&def_id).copied().unwrap_or(self.graph_root)
         });
-        let parent_scope = &ParentScope { module, ..self.dummy_parent_scope() };
+        let parent_scope = &ParentScope::module(module);
         let res = self.resolve_ast_path(&path, ns, parent_scope).map_err(|_| ())?;
         Ok((path, res))
     }
@@ -2713,7 +2763,7 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
     fn collect_mod(names: &mut Vec<Ident>, module: Module<'_>) {
         if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
-                names.push(Ident::with_empty_ctxt(name));
+                names.push(Ident::with_dummy_span(name));
                 collect_mod(names, parent);
             }
         } else {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 71e26dac57c..01ad67252a3 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -1,56 +1,32 @@
+//! A bunch of methods and structures more or less related to resolving macros and
+//! interface provided by `Resolver` to macro expander.
+
 use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
 use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
-use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
+use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
 use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
 use crate::Namespace::*;
-use crate::build_reduced_graph::BuildReducedGraphVisitor;
 use crate::resolve_imports::ImportResolver;
 use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
-use rustc::hir::map::DefCollector;
 use rustc::middle::stability;
 use rustc::{ty, lint, span_bug};
-use syntax::ast::{self, Ident};
+use syntax::ast::{self, NodeId, Ident};
 use syntax::attr::StabilityLevel;
 use syntax::edition::Edition;
 use syntax::ext::base::{self, Indeterminate, SpecialDerives};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
-use syntax::ext::hygiene::{self, ExpnId, ExpnInfo, ExpnKind};
+use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
 use syntax::feature_gate::GateIssue;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::{Span, DUMMY_SP};
 
-use std::cell::Cell;
 use std::{mem, ptr};
 use rustc_data_structures::sync::Lrc;
 
-type Res = def::Res<ast::NodeId>;
-
-// FIXME: Merge this with `ParentScope`.
-#[derive(Clone, Debug)]
-pub struct InvocationData<'a> {
-    /// The module in which the macro was invoked.
-    crate module: Module<'a>,
-    /// The legacy scope in which the macro was invoked.
-    /// The invocation path is resolved in this scope.
-    crate parent_legacy_scope: LegacyScope<'a>,
-    /// The legacy scope *produced* by expanding this macro invocation,
-    /// includes all the macro_rules items, other invocations, etc generated by it.
-    /// `None` if the macro is not expanded yet.
-    crate output_legacy_scope: Cell<Option<LegacyScope<'a>>>,
-}
-
-impl<'a> InvocationData<'a> {
-    pub fn root(graph_root: Module<'a>) -> Self {
-        InvocationData {
-            module: graph_root,
-            parent_legacy_scope: LegacyScope::Empty,
-            output_legacy_scope: Cell::new(None),
-        }
-    }
-}
+type Res = def::Res<NodeId>;
 
 /// Binding produced by a `macro_rules` item.
 /// Not modularized, can shadow previous legacy bindings, etc.
@@ -75,7 +51,7 @@ pub enum LegacyScope<'a> {
     Binding(&'a LegacyBinding<'a>),
     /// The scope introduced by a macro invocation that can potentially
     /// create a `macro_rules!` macro definition.
-    Invocation(&'a InvocationData<'a>),
+    Invocation(ExpnId),
 }
 
 // Macro namespace is separated into two sub-namespaces, one for bang macros and
@@ -115,22 +91,17 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
 }
 
 impl<'a> base::Resolver for Resolver<'a> {
-    fn next_node_id(&mut self) -> ast::NodeId {
+    fn next_node_id(&mut self) -> NodeId {
         self.session.next_node_id()
     }
 
-    fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId {
-        let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::default(
+    fn get_module_scope(&mut self, id: NodeId) -> ExpnId {
+        let expn_id = ExpnId::fresh(Some(ExpnData::default(
             ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
-        ));
-        let expn_id = span.ctxt().outer_expn();
+        )));
         let module = self.module_map[&self.definitions.local_def_id(id)];
+        self.invocation_parent_scopes.insert(expn_id, ParentScope::module(module));
         self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index);
-        self.invocations.insert(expn_id, self.arenas.alloc_invocation_data(InvocationData {
-            module,
-            parent_legacy_scope: LegacyScope::Empty,
-            output_legacy_scope: Cell::new(None),
-        }));
         expn_id
     }
 
@@ -144,29 +115,18 @@ impl<'a> base::Resolver for Resolver<'a> {
         });
     }
 
-    fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
-                                            derives: &[ExpnId]) {
-        fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expn_id));
-
-        let invocation = self.invocations[&expn_id];
-        invocation.module.unresolved_invocations.borrow_mut().remove(&expn_id);
-        invocation.module.unresolved_invocations.borrow_mut().extend(derives);
-        let parent_def = self.definitions.invocation_parent(expn_id);
-        for &derive_invoc_id in derives {
-            self.definitions.set_invocation_parent(derive_invoc_id, parent_def);
-        }
-        self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
-        let mut visitor = BuildReducedGraphVisitor {
-            r: self,
-            parent_scope: ParentScope {
-                module: invocation.module,
-                expansion: expn_id,
-                legacy: invocation.parent_legacy_scope,
-                derives: Vec::new(),
-            },
-        };
-        fragment.visit_with(&mut visitor);
-        invocation.output_legacy_scope.set(Some(visitor.parent_scope.legacy));
+    // FIXME: `extra_placeholders` should be included into the `fragment` as regular placeholders.
+    fn visit_ast_fragment_with_placeholders(
+        &mut self, expansion: ExpnId, fragment: &AstFragment, extra_placeholders: &[NodeId]
+    ) {
+        // Integrate the new AST fragment into all the definition and module structures.
+        // We are inside the `expansion` now, but other parent scope components are still the same.
+        let parent_scope = ParentScope { expansion, ..self.invocation_parent_scopes[&expansion] };
+        let output_legacy_scope =
+            self.build_reduced_graph(fragment, extra_placeholders, parent_scope);
+        self.output_legacy_scopes.insert(expansion, output_legacy_scope);
+
+        parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion);
     }
 
     fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {
@@ -182,13 +142,14 @@ impl<'a> base::Resolver for Resolver<'a> {
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
-        let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
+        let parent_scope = self.invocation_parent_scopes[&invoc_id];
+        let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
-                (&attr.path, MacroKind::Attr, derives.clone(), after_derive),
+                (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive),
             InvocationKind::Bang { ref mac, .. } =>
-                (&mac.path, MacroKind::Bang, Vec::new(), false),
+                (&mac.path, MacroKind::Bang, &[][..], false),
             InvocationKind::Derive { ref path, .. } =>
-                (path, MacroKind::Derive, Vec::new(), false),
+                (path, MacroKind::Derive, &[][..], false),
             InvocationKind::DeriveContainer { ref derives, .. } => {
                 // Block expansion of derives in the container until we know whether one of them
                 // is a built-in `Copy`. Skip the resolution if there's only one derive - either
@@ -196,10 +157,9 @@ impl<'a> base::Resolver for Resolver<'a> {
                 // will automatically knows about itself.
                 let mut result = Ok(None);
                 if derives.len() > 1 {
-                    let parent_scope = &self.invoc_parent_scope(invoc_id, Vec::new());
                     for path in derives {
                         match self.resolve_macro_path(path, Some(MacroKind::Derive),
-                                                      parent_scope, true, force) {
+                                                      &parent_scope, true, force) {
                             Ok((Some(ref ext), _)) if ext.is_derive_copy => {
                                 self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
                                 return Ok(None);
@@ -213,11 +173,14 @@ impl<'a> base::Resolver for Resolver<'a> {
             }
         };
 
-        let parent_scope = &self.invoc_parent_scope(invoc_id, derives_in_scope);
+        // Derives are not included when `invocations` are collected, so we have to add them here.
+        let parent_scope = &ParentScope { derives, ..parent_scope };
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
-        invoc.expansion_data.id.set_expn_info(ext.expn_info(span, fast_print_path(path)));
+        invoc.expansion_data.id.set_expn_data(
+            ext.expn_data(parent_scope.expansion, span, fast_print_path(path))
+        );
 
         if let Res::Def(_, def_id) = res {
             if after_derive {
@@ -251,20 +214,6 @@ impl<'a> base::Resolver for Resolver<'a> {
 }
 
 impl<'a> Resolver<'a> {
-    pub fn dummy_parent_scope(&self) -> ParentScope<'a> {
-        self.invoc_parent_scope(ExpnId::root(), Vec::new())
-    }
-
-    fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec<ast::Path>) -> ParentScope<'a> {
-        let invoc = self.invocations[&invoc_id];
-        ParentScope {
-            module: invoc.module.nearest_item_scope(),
-            expansion: invoc_id.parent(),
-            legacy: invoc.parent_legacy_scope,
-            derives,
-        }
-    }
-
     /// Resolve macro path with error reporting and recovery.
     fn smart_resolve_macro_path(
         &mut self,
@@ -346,8 +295,7 @@ impl<'a> Resolver<'a> {
 
         // Possibly apply the macro helper hack
         if kind == Some(MacroKind::Bang) && path.len() == 1 &&
-           path[0].ident.span.ctxt().outer_expn_info()
-               .map_or(false, |info| info.local_inner_macros) {
+           path[0].ident.span.ctxt().outer_expn_data().local_inner_macros {
             let root = Ident::new(kw::DollarCrate, path[0].ident.span);
             path.insert(0, Segment::from_ident(root));
         }
@@ -367,8 +315,8 @@ impl<'a> Resolver<'a> {
 
             if trace {
                 let kind = kind.expect("macro kind must be specified if tracing is enabled");
-                parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
-                    .push((path, path_span, kind, parent_scope.clone(), res.ok()));
+                self.multi_segment_macro_resolutions
+                    .push((path, path_span, kind, *parent_scope, res.ok()));
             }
 
             self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
@@ -384,8 +332,8 @@ impl<'a> Resolver<'a> {
 
             if trace {
                 let kind = kind.expect("macro kind must be specified if tracing is enabled");
-                parent_scope.module.single_segment_macro_resolutions.borrow_mut()
-                    .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
+                self.single_segment_macro_resolutions
+                    .push((path[0].ident, kind, *parent_scope, binding.ok()));
             }
 
             let res = binding.map(|binding| binding.res());
@@ -454,8 +402,8 @@ impl<'a> Resolver<'a> {
             let result = match scope {
                 Scope::DeriveHelpers => {
                     let mut result = Err(Determinacy::Determined);
-                    for derive in &parent_scope.derives {
-                        let parent_scope = &ParentScope { derives: Vec::new(), ..*parent_scope };
+                    for derive in parent_scope.derives {
+                        let parent_scope = &ParentScope { derives: &[], ..*parent_scope };
                         match this.resolve_macro_path(derive, Some(MacroKind::Derive),
                                                       parent_scope, true, force) {
                             Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
@@ -475,8 +423,9 @@ impl<'a> Resolver<'a> {
                 Scope::MacroRules(legacy_scope) => match legacy_scope {
                     LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
                         Ok((legacy_binding.binding, Flags::MACRO_RULES)),
-                    LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() =>
-                        Err(Determinacy::Undetermined),
+                    LegacyScope::Invocation(invoc_id)
+                        if !this.output_legacy_scopes.contains_key(&invoc_id) =>
+                            Err(Determinacy::Undetermined),
                     _ => Err(Determinacy::Determined),
                 }
                 Scope::CrateRoot => {
@@ -500,7 +449,7 @@ impl<'a> Resolver<'a> {
                     }
                 }
                 Scope::Module(module) => {
-                    let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() };
+                    let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
                     let binding = this.resolve_ident_in_module_unadjusted_ext(
                         ModuleOrUniformRoot::Module(module),
                         ident,
@@ -531,7 +480,7 @@ impl<'a> Resolver<'a> {
                 Scope::MacroUsePrelude => match this.macro_use_prelude.get(&ident.name).cloned() {
                     Some(binding) => Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)),
                     None => Err(Determinacy::determined(
-                        this.graph_root.unresolved_invocations.borrow().is_empty()
+                        this.graph_root.unexpanded_invocations.borrow().is_empty()
                     ))
                 }
                 Scope::BuiltinAttrs => if is_builtin_attr_name(ident.name) {
@@ -554,7 +503,7 @@ impl<'a> Resolver<'a> {
                 Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) {
                     Some(binding) => Ok((binding, Flags::PRELUDE)),
                     None => Err(Determinacy::determined(
-                        this.graph_root.unresolved_invocations.borrow().is_empty()
+                        this.graph_root.unexpanded_invocations.borrow().is_empty()
                     )),
                 }
                 Scope::ToolPrelude => if KNOWN_TOOLS.contains(&ident.name) {
@@ -575,7 +524,7 @@ impl<'a> Resolver<'a> {
                             false,
                             path_span,
                         ) {
-                            if use_prelude || this.is_builtin_macro(binding.res().opt_def_id()) {
+                            if use_prelude || this.is_builtin_macro(binding.res()) {
                                 result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
                             }
                         }
@@ -694,7 +643,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    pub fn finalize_current_module_macro_resolutions(&mut self, module: Module<'a>) {
+    crate fn finalize_macro_resolutions(&mut self) {
         let check_consistency = |this: &mut Self, path: &[Segment], span, kind: MacroKind,
                                  initial_res: Option<Res>, res: Res| {
             if let Some(initial_res) = initial_res {
@@ -730,8 +679,7 @@ impl<'a> Resolver<'a> {
             }
         };
 
-        let macro_resolutions =
-            mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut());
+        let macro_resolutions = mem::take(&mut self.multi_segment_macro_resolutions);
         for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions {
             // FIXME: Path resolution will ICE if segment IDs present.
             for seg in &mut path { seg.id = None; }
@@ -758,8 +706,7 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        let macro_resolutions =
-            mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut());
+        let macro_resolutions = mem::take(&mut self.single_segment_macro_resolutions);
         for (ident, kind, parent_scope, initial_binding) in macro_resolutions {
             match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind),
                                                             &parent_scope, true, true, ident.span) {
@@ -784,7 +731,7 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut());
+        let builtin_attrs = mem::take(&mut self.builtin_attrs);
         for (ident, parent_scope) in builtin_attrs {
             let _ = self.early_resolve_ident_in_lexical_scope(
                 ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 00e89f0fdae..fd222a132a3 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1,3 +1,5 @@
+//! A bunch of methods and structures more or less related to resolving imports.
+
 use ImportDirectiveSubclass::*;
 
 use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
@@ -5,9 +7,8 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, ParentScope
 use crate::Determinacy::{self, *};
 use crate::Namespace::{self, TypeNS, MacroNS};
 use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
-use crate::{Resolver, ResolutionError, Segment};
+use crate::{Resolver, ResolutionError, Segment, ModuleKind};
 use crate::{names_to_string, module_to_string};
-use crate::ModuleKind;
 use crate::diagnostics::Suggestion;
 
 use errors::Applicability;
@@ -35,7 +36,7 @@ use syntax_pos::{MultiSpan, Span};
 
 use log::*;
 
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use std::{mem, ptr};
 
 type Res = def::Res<NodeId>;
@@ -159,12 +160,6 @@ impl<'a> NameResolution<'a> {
 }
 
 impl<'a> Resolver<'a> {
-    crate fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
-                  -> &'a RefCell<NameResolution<'a>> {
-        *module.resolutions.borrow_mut().entry((ident.modern(), ns))
-               .or_insert_with(|| self.arenas.alloc_name_resolution())
-    }
-
     crate fn resolve_ident_in_module_unadjusted(
         &mut self,
         module: ModuleOrUniformRoot<'a>,
@@ -207,7 +202,7 @@ impl<'a> Resolver<'a> {
                     Err((Determined, Weak::No))
                 } else if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
                     Ok(binding)
-                } else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
+                } else if !self.graph_root.unexpanded_invocations.borrow().is_empty() {
                     // Macro-expanded `extern crate` items can add names to extern prelude.
                     Err((Undetermined, Weak::No))
                 } else {
@@ -240,8 +235,6 @@ impl<'a> Resolver<'a> {
             }
         };
 
-        self.populate_module_if_necessary(module);
-
         let resolution = self.resolution(module, ident, ns)
             .try_borrow_mut()
             .map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
@@ -355,7 +348,7 @@ impl<'a> Resolver<'a> {
         // progress, we have to ignore those potential unresolved invocations from other modules
         // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
         // shadowing is enabled, see `macro_expanded_macro_export_errors`).
-        let unexpanded_macros = !module.unresolved_invocations.borrow().is_empty();
+        let unexpanded_macros = !module.unexpanded_invocations.borrow().is_empty();
         if let Some(binding) = resolution.binding {
             if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
                 return check_usable(self, binding);
@@ -394,7 +387,7 @@ impl<'a> Resolver<'a> {
             match ident.span.glob_adjust(module.expansion, glob_import.span) {
                 Some(Some(def)) => {
                     tmp_parent_scope =
-                        ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() };
+                        ParentScope { module: self.macro_def_scope(def), ..*parent_scope };
                     adjusted_parent_scope = &tmp_parent_scope;
                 }
                 Some(None) => {}
@@ -848,7 +841,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         directive.vis.set(orig_vis);
         let module = match path_res {
             PathResult::Module(module) => {
-                // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+                // Consistency checks, analogous to `finalize_macro_resolutions`.
                 if let Some(initial_module) = directive.imported_module.get() {
                     if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
                         span_bug!(directive.span, "inconsistent resolution for an import");
@@ -973,7 +966,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             match binding {
                 Ok(binding) => {
-                    // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+                    // Consistency checks, analogous to `finalize_macro_resolutions`.
                     let initial_res = source_bindings[ns].get().map(|initial_binding| {
                         all_ns_err = false;
                         if let Some(target_binding) = target_bindings[ns].get() {
@@ -1025,7 +1018,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             return if all_ns_failed {
                 let resolutions = match module {
-                    ModuleOrUniformRoot::Module(module) => Some(module.resolutions.borrow()),
+                    ModuleOrUniformRoot::Module(module) =>
+                        Some(self.r.resolutions(module).borrow()),
                     _ => None,
                 };
                 let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
@@ -1263,8 +1257,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             }
         };
 
-        self.r.populate_module_if_necessary(module);
-
         if module.is_trait() {
             self.r.session.span_err(directive.span, "items in traits are not importable.");
             return;
@@ -1280,8 +1272,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
         // Ensure that `resolutions` isn't borrowed during `try_define`,
         // since it might get updated via a glob cycle.
-        let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
-            resolution.borrow().binding().map(|binding| (ident, binding))
+        let bindings = self.r.resolutions(module).borrow().iter().filter_map(|(ident, resolution)| {
+            resolution.borrow().binding().map(|binding| (*ident, binding))
         }).collect::<Vec<_>>();
         for ((mut ident, ns), binding) in bindings {
             let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) {
@@ -1308,7 +1300,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
         let mut reexports = Vec::new();
 
-        for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
+        for (&(ident, ns), resolution) in self.r.resolutions(module).borrow().iter() {
             let resolution = &mut *resolution.borrow_mut();
             let binding = match resolution.binding {
                 Some(binding) => binding,
@@ -1367,8 +1359,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                             Some(ModuleOrUniformRoot::Module(module)) => module,
                             _ => bug!("module should exist"),
                         };
-                        let resolutions = imported_module.parent.expect("parent should exist")
-                            .resolutions.borrow();
+                        let parent_module = imported_module.parent.expect("parent should exist");
+                        let resolutions = self.r.resolutions(parent_module).borrow();
                         let enum_path_segment_index = directive.module_path.len() - 1;
                         let enum_ident = directive.module_path[enum_path_segment_index].ident;
 
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 9da6cd80057..0bbbbb8249c 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -1156,7 +1156,7 @@ fn escape(s: String) -> String {
 // Helper function to determine if a span came from a
 // macro expansion or syntax extension.
 fn generated_code(span: Span) -> bool {
-    span.ctxt() != NO_EXPANSION || span.is_dummy()
+    span.from_expansion() || span.is_dummy()
 }
 
 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
diff --git a/src/librustc_target/spec/aarch64_wrs_vxworks.rs b/src/librustc_target/spec/aarch64_wrs_vxworks.rs
index 6ad6632341c..65caeac5ed1 100644
--- a/src/librustc_target/spec/aarch64_wrs_vxworks.rs
+++ b/src/librustc_target/spec/aarch64_wrs_vxworks.rs
@@ -9,15 +9,14 @@ pub fn target() -> TargetResult {
         target_endian: "little".to_string(),
         target_pointer_width: "64".to_string(),
         target_c_int_width: "32".to_string(),
-        target_env: "gnu".to_string(),
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         target_os: "vxworks".to_string(),
-        target_vendor: "unknown".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "wrs".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
             abi_blacklist: super::arm_base::abi_blacklist(),
-            target_mcount: "\u{1}_mcount".to_string(),
             .. base
         },
     })
diff --git a/src/librustc_target/spec/arm_wrs_vxworks_sf.rs b/src/librustc_target/spec/arm_wrs_vxworks_sf.rs
deleted file mode 100644
index bde903de102..00000000000
--- a/src/librustc_target/spec/arm_wrs_vxworks_sf.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
-
-pub fn target() -> TargetResult {
-    let mut base = super::vxworks_base::opts();
-    base.max_atomic_width = Some(64);
-    Ok(Target {
-        llvm_target: "arm-unknown-linux-gnueabi".to_string(),
-        target_endian: "little".to_string(),
-        target_pointer_width: "32".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
-        arch: "arm".to_string(),
-        target_os: "vxworks".to_string(),
-        target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-
-        options: TargetOptions {
-            features: "+strict-align,+v6".to_string(),
-            abi_blacklist: super::arm_base::abi_blacklist(),
-            target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            .. base
-        },
-    })
-}
diff --git a/src/librustc_target/spec/armv7_wrs_vxworks.rs b/src/librustc_target/spec/armv7_wrs_vxworks.rs
deleted file mode 100644
index 06c51ae6106..00000000000
--- a/src/librustc_target/spec/armv7_wrs_vxworks.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
-
-// This target is for glibc Linux on ARMv7 without NEON or
-// thumb-mode. See the thumbv7neon variant for enabling both.
-
-pub fn target() -> TargetResult {
-    let base = super::vxworks_base::opts();
-    Ok(Target {
-        llvm_target: "armv7-unknown-linux-gnueabihf".to_string(),
-        target_endian: "little".to_string(),
-        target_pointer_width: "32".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
-        arch: "arm".to_string(),
-        target_os: "vxworks".to_string(),
-        target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-
-        options: TargetOptions {
-            // Info about features at https://wiki.debian.org/ArmHardFloatPort
-            features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
-            cpu: "generic".to_string(),
-            max_atomic_width: Some(64),
-            abi_blacklist: super::arm_base::abi_blacklist(),
-            target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            position_independent_executables: false,
-            .. base
-        }
-    })
-}
diff --git a/src/librustc_target/spec/arm_wrs_vxworks.rs b/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs
index 06c51ae6106..9e3b24dd327 100644
--- a/src/librustc_target/spec/arm_wrs_vxworks.rs
+++ b/src/librustc_target/spec/armv7_wrs_vxworks_eabihf.rs
@@ -1,8 +1,5 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
-// This target is for glibc Linux on ARMv7 without NEON or
-// thumb-mode. See the thumbv7neon variant for enabling both.
-
 pub fn target() -> TargetResult {
     let base = super::vxworks_base::opts();
     Ok(Target {
@@ -14,17 +11,14 @@ pub fn target() -> TargetResult {
         arch: "arm".to_string(),
         target_os: "vxworks".to_string(),
         target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
+        target_vendor: "wrs".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
-
         options: TargetOptions {
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             cpu: "generic".to_string(),
             max_atomic_width: Some(64),
             abi_blacklist: super::arm_base::abi_blacklist(),
-            target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
-            position_independent_executables: false,
             .. base
         }
     })
diff --git a/src/librustc_target/spec/i586_wrs_vxworks.rs b/src/librustc_target/spec/i586_wrs_vxworks.rs
deleted file mode 100644
index 355250e6eca..00000000000
--- a/src/librustc_target/spec/i586_wrs_vxworks.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use crate::spec::TargetResult;
-
-pub fn target() -> TargetResult {
-    let mut base = super::i686_wrs_vxworks::target()?;
-    base.options.cpu = "pentium".to_string();
-    base.llvm_target = "i586-unknown-linux-gnu".to_string();
-    Ok(base)
-}
diff --git a/src/librustc_target/spec/i686_wrs_vxworks.rs b/src/librustc_target/spec/i686_wrs_vxworks.rs
index 4b1ff5ccbe8..c5f9583a358 100644
--- a/src/librustc_target/spec/i686_wrs_vxworks.rs
+++ b/src/librustc_target/spec/i686_wrs_vxworks.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
         arch: "x86".to_string(),
         target_os: "vxworks".to_string(),
         target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
+        target_vendor: "wrs".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: base,
     })
diff --git a/src/librustc_target/spec/i686_wrs_vxworks_gnu.rs b/src/librustc_target/spec/i686_wrs_vxworks_gnu.rs
deleted file mode 100644
index 4b1ff5ccbe8..00000000000
--- a/src/librustc_target/spec/i686_wrs_vxworks_gnu.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetResult};
-
-pub fn target() -> TargetResult {
-    let mut base = super::vxworks_base::opts();
-    base.cpu = "pentium4".to_string();
-    base.max_atomic_width = Some(64);
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
-    base.stack_probes = true;
-
-    Ok(Target {
-        llvm_target: "i686-unknown-linux-gnu".to_string(),
-        target_endian: "little".to_string(),
-        target_pointer_width: "32".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128".to_string(),
-        arch: "x86".to_string(),
-        target_os: "vxworks".to_string(),
-        target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-        options: base,
-    })
-}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 9a009ca68ee..539e28f7088 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -398,6 +398,7 @@ supported_targets! {
 
     ("aarch64-unknown-openbsd", aarch64_unknown_openbsd),
     ("i686-unknown-openbsd", i686_unknown_openbsd),
+    ("sparc64-unknown-openbsd", sparc64_unknown_openbsd),
     ("x86_64-unknown-openbsd", x86_64_unknown_openbsd),
 
     ("aarch64-unknown-netbsd", aarch64_unknown_netbsd),
@@ -492,10 +493,9 @@ supported_targets! {
 
     ("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
 
-    ("x86_64-wrs-vxworks", x86_64_wrs_vxworks),
     ("i686-wrs-vxworks", i686_wrs_vxworks),
-    ("i586-wrs-vxworks", i586_wrs_vxworks),
-    ("armv7-wrs-vxworks", armv7_wrs_vxworks),
+    ("x86_64-wrs-vxworks", x86_64_wrs_vxworks),
+    ("armv7-wrs-vxworks-eabihf", armv7_wrs_vxworks_eabihf),
     ("aarch64-wrs-vxworks", aarch64_wrs_vxworks),
     ("powerpc-wrs-vxworks", powerpc_wrs_vxworks),
     ("powerpc-wrs-vxworks-spe", powerpc_wrs_vxworks_spe),
diff --git a/src/librustc_target/spec/powerpc64_wrs_vxworks.rs b/src/librustc_target/spec/powerpc64_wrs_vxworks.rs
index a9520709e66..27a84b953dd 100644
--- a/src/librustc_target/spec/powerpc64_wrs_vxworks.rs
+++ b/src/librustc_target/spec/powerpc64_wrs_vxworks.rs
@@ -15,10 +15,9 @@ pub fn target() -> TargetResult {
         arch: "powerpc64".to_string(),
         target_os: "vxworks".to_string(),
         target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
+        target_vendor: "wrs".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
-            target_mcount: "_mcount".to_string(),
             .. base
         },
     })
diff --git a/src/librustc_target/spec/powerpc64_wrs_vxworks_gnusf.rs b/src/librustc_target/spec/powerpc64_wrs_vxworks_gnusf.rs
deleted file mode 100644
index c2dae8535a2..00000000000
--- a/src/librustc_target/spec/powerpc64_wrs_vxworks_gnusf.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
-
-pub fn target() -> TargetResult {
-    let mut base = super::vxworks_base::opts();
-    base.cpu = "ppc64".to_string();
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
-    base.max_atomic_width = Some(64);
-
-    Ok(Target {
-        llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
-        target_endian: "big".to_string(),
-        target_pointer_width: "64".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "E-m:e-i64:64-n32:64".to_string(),
-        arch: "powerpc64".to_string(),
-        target_os: "vxworks".to_string(),
-        target_env: "gnu".to_string(),
-        target_vendor: "unknown".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions {
-            features: "-hard-float".to_string(),
-            target_mcount: "_mcount".to_string(),
-            .. base
-        },
-    })
-}
diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks.rs b/src/librustc_target/spec/powerpc_wrs_vxworks.rs
index 2e833ee1d48..a4d2897f892 100644
--- a/src/librustc_target/spec/powerpc_wrs_vxworks.rs
+++ b/src/librustc_target/spec/powerpc_wrs_vxworks.rs
@@ -19,7 +19,6 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
             features: "+secure-plt".to_string(),
-            target_mcount: "_mcount".to_string(),
             .. base
         },
     })
diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks_gnusf.rs b/src/librustc_target/spec/powerpc_wrs_vxworks_gnusf.rs
deleted file mode 100644
index 43723ea7c0c..00000000000
--- a/src/librustc_target/spec/powerpc_wrs_vxworks_gnusf.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
-
-pub fn target() -> TargetResult {
-    let mut base = super::vxworks_base::opts();
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string());
-    base.max_atomic_width = Some(32);
-
-    Ok(Target {
-        llvm_target: "powerpc-unknown-linux-gnu".to_string(),
-        target_endian: "big".to_string(),
-        target_pointer_width: "32".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
-        arch: "powerpc".to_string(),
-        target_os: "vxworks".to_string(),
-        target_env: "gnu".to_string(),
-        target_vendor: "wrs".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions {
-            features: "+secure-plt,-hard-float".to_string(),
-            target_mcount: "_mcount".to_string(),
-            .. base
-        },
-    })
-}
diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks_gnuspesf.rs b/src/librustc_target/spec/powerpc_wrs_vxworks_gnuspesf.rs
deleted file mode 100644
index 8f236235867..00000000000
--- a/src/librustc_target/spec/powerpc_wrs_vxworks_gnuspesf.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
-
-pub fn target() -> TargetResult {
-    let mut base = super::vxworks_base::opts();
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-mspe".to_string());
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("--secure-plt".to_string());
-    base.max_atomic_width = Some(32);
-
-    Ok(Target {
-        llvm_target: "powerpc-unknown-linux-gnuspe".to_string(),
-        target_endian: "big".to_string(),
-        target_pointer_width: "32".to_string(),
-        target_c_int_width: "32".to_string(),
-        data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
-        arch: "powerpc".to_string(),
-        target_os: "vxworks".to_string(),
-        target_env: "gnu".to_string(),
-        target_vendor: "wrs".to_string(),
-        linker_flavor: LinkerFlavor::Gcc,
-        options: TargetOptions {
-            // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2
-            features: "+secure-plt,+msync,-hard-float".to_string(),
-            target_mcount: "_mcount".to_string(),
-            .. base
-        },
-    })
-}
diff --git a/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs b/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs
index 2305b4b7ab8..90118a14852 100644
--- a/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs
+++ b/src/librustc_target/spec/powerpc_wrs_vxworks_spe.rs
@@ -20,7 +20,6 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2
             features: "+secure-plt,+msync".to_string(),
-            target_mcount: "_mcount".to_string(),
             .. base
         },
     })
diff --git a/src/librustc_target/spec/sparc64_unknown_openbsd.rs b/src/librustc_target/spec/sparc64_unknown_openbsd.rs
new file mode 100644
index 00000000000..229e0621e0d
--- /dev/null
+++ b/src/librustc_target/spec/sparc64_unknown_openbsd.rs
@@ -0,0 +1,22 @@
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::openbsd_base::opts();
+    base.cpu = "v9".to_string();
+    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+    base.max_atomic_width = Some(64);
+
+    Ok(Target {
+        llvm_target: "sparc64-unknown-openbsd".to_string(),
+        target_endian: "big".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "E-m:e-i64:64-n32:64-S128".to_string(),
+        arch: "sparc64".to_string(),
+        target_os: "openbsd".to_string(),
+        target_env: String::new(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: base,
+    })
+}
diff --git a/src/librustc_target/spec/vxworks_base.rs b/src/librustc_target/spec/vxworks_base.rs
index 6db56c553a9..16acd411dca 100644
--- a/src/librustc_target/spec/vxworks_base.rs
+++ b/src/librustc_target/spec/vxworks_base.rs
@@ -1,7 +1,11 @@
-use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions, RelroLevel};
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
 use std::default::Default;
 
 pub fn opts() -> TargetOptions {
+    let mut args_crt = LinkArgs::new();
+    args_crt.insert(LinkerFlavor::Gcc, vec![
+        "--static-crt".to_string(),
+    ]);
     let mut args = LinkArgs::new();
     args.insert(LinkerFlavor::Gcc, vec![
         // We want to be able to strip as much executable code as possible
@@ -12,30 +16,25 @@ pub fn opts() -> TargetOptions {
         // following libraries so we're sure to pass it as one of the first
         // arguments.
         "-Wl,--as-needed".to_string(),
-
-        // Always enable NX protection when it is available
-        "-Wl,-z,noexecstack".to_string(),
-    ]);
-
-    let mut late_lk_args = LinkArgs::new();
-    late_lk_args.insert(LinkerFlavor::Gcc, vec![
-        "-lnet".to_string(),
-        "-lunix".to_string(),
     ]);
 
     TargetOptions {
-        linker: Some("vx-cxx".to_string()),
+        linker: Some("wr-c++".to_string()),
         exe_suffix: ".vxe".to_string(),
-        late_link_args: late_lk_args,
         dynamic_linking: true,
         executables: true,
         target_family: Some("unix".to_string()),
         linker_is_gnu: true,
         has_rpath: true,
         pre_link_args: args,
-        position_independent_executables: true,
-        relro_level: RelroLevel::Full,
+        position_independent_executables: false,
         has_elf_tls: true,
+        pre_link_args_crt: args_crt,
+        crt_static_default: true,
+        crt_static_respected: true,
+        crt_static_allows_dylibs: true,
+        // VxWorks needs to implement this to support profiling
+        target_mcount: "_mcount".to_string(),
         .. Default::default()
     }
 }
diff --git a/src/librustc_target/spec/x86_64_wrs_vxworks.rs b/src/librustc_target/spec/x86_64_wrs_vxworks.rs
index eac7cd7502d..1ab2f3a47c4 100644
--- a/src/librustc_target/spec/x86_64_wrs_vxworks.rs
+++ b/src/librustc_target/spec/x86_64_wrs_vxworks.rs
@@ -6,6 +6,7 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
     base.stack_probes = true;
+    base.disable_redzone = true;
 
     Ok(Target {
         llvm_target: "x86_64-unknown-linux-gnu".to_string(),
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 99ae777bb63..fc25eb44cbd 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -53,6 +53,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let is_non_ref_pat = match pat.node {
             PatKind::Struct(..) |
             PatKind::TupleStruct(..) |
+            PatKind::Or(_) |
             PatKind::Tuple(..) |
             PatKind::Box(_) |
             PatKind::Range(..) |
@@ -309,6 +310,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             PatKind::Struct(ref qpath, ref fields, etc) => {
                 self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
             }
+            PatKind::Or(ref pats) => {
+                let expected_ty = self.structurally_resolved_type(pat.span, expected);
+                for pat in pats {
+                    self.check_pat_walk(pat, expected, def_bm, discrim_span);
+                }
+                expected_ty
+            }
             PatKind::Tuple(ref elements, ddpos) => {
                 let mut expected_len = elements.len();
                 if ddpos.is_some() {
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index ed25601208a..de5ba8bc8eb 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -347,9 +347,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             sp,
         );
 
-        // Check the `expn_info()` to see if this is a macro; if so, it's hard to
-        // extract the text and make a good suggestion, so don't bother.
-        let is_macro = sp.ctxt().outer_expn_info().is_some();
+        // If the span is from a macro, then it's hard to extract the text
+        // and make a good suggestion, so don't bother.
+        let is_macro = sp.from_expansion();
 
         match (&expr.node, &expected.sty, &checked_ty.sty) {
             (_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.sty, &check.sty) {
@@ -554,6 +554,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // FIXME(estebank): modify once we decide to suggest `as` casts
             return false;
         }
+        if !self.tcx.sess.source_map().span_to_filename(expr.span).is_real() {
+            // Ignore if span is from within a macro.
+            return false;
+        }
 
         // If casting this expression to a given numeric type would be appropriate in case of a type
         // mismatch.
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 9680f61d699..d139cd4264c 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -24,6 +24,7 @@ use syntax::source_map::Span;
 use syntax::util::lev_distance::find_best_match_for_name;
 use rustc::hir;
 use rustc::hir::{ExprKind, QPath};
+use rustc::hir::def_id::DefId;
 use rustc::hir::def::{CtorKind, Res, DefKind};
 use rustc::hir::ptr::P;
 use rustc::infer;
@@ -1336,116 +1337,182 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         autoderef.unambiguous_final_ty(self);
 
         if let Some((did, field_ty)) = private_candidate {
-            let struct_path = self.tcx().def_path_str(did);
-            let mut err = struct_span_err!(self.tcx().sess, expr.span, E0616,
-                                           "field `{}` of struct `{}` is private",
-                                           field, struct_path);
-            // Also check if an accessible method exists, which is often what is meant.
-            if self.method_exists(field, expr_t, expr.hir_id, false)
-                && !self.expr_in_place(expr.hir_id)
-            {
-                self.suggest_method_call(
-                    &mut err,
-                    &format!("a method `{}` also exists, call it with parentheses", field),
-                    field,
-                    expr_t,
-                    expr.hir_id,
-                );
-            }
-            err.emit();
-            field_ty
-        } else if field.name == kw::Invalid {
-            self.tcx().types.err
+            self.ban_private_field_access(expr, expr_t, field, did);
+            return field_ty;
+        }
+
+        if field.name == kw::Invalid {
         } else if self.method_exists(field, expr_t, expr.hir_id, true) {
-            let mut err = type_error_struct!(self.tcx().sess, field.span, expr_t, E0615,
-                               "attempted to take value of method `{}` on type `{}`",
-                               field, expr_t);
-
-            if !self.expr_in_place(expr.hir_id) {
-                self.suggest_method_call(
-                    &mut err,
-                    "use parentheses to call the method",
-                    field,
-                    expr_t,
-                    expr.hir_id
-                );
-            } else {
-                err.help("methods are immutable and cannot be assigned to");
+            self.ban_take_value_of_method(expr, expr_t, field);
+        } else if !expr_t.is_primitive_ty() {
+            let mut err = self.no_such_field_err(field.span, field, expr_t);
+
+            match expr_t.sty {
+                ty::Adt(def, _) if !def.is_enum() => {
+                    self.suggest_fields_on_recordish(&mut err, def, field);
+                }
+                ty::Array(_, len) => {
+                    self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
+                }
+                ty::RawPtr(..) => {
+                    self.suggest_first_deref_field(&mut err, expr, base, field);
+                }
+                _ => {}
+            }
+
+            if field.name == kw::Await {
+                // We know by construction that `<expr>.await` is either on Rust 2015
+                // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
+                err.note("to `.await` a `Future`, switch to Rust 2018");
+                err.help("set `edition = \"2018\"` in `Cargo.toml`");
+                err.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
             }
 
             err.emit();
-            self.tcx().types.err
         } else {
-            if !expr_t.is_primitive_ty() {
-                let mut err = self.no_such_field_err(field.span, field, expr_t);
-
-                match expr_t.sty {
-                    ty::Adt(def, _) if !def.is_enum() => {
-                        if let Some(suggested_field_name) =
-                            Self::suggest_field_name(def.non_enum_variant(),
-                                                     &field.as_str(), vec![]) {
-                                err.span_suggestion(
-                                    field.span,
-                                    "a field with a similar name exists",
-                                    suggested_field_name.to_string(),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            } else {
-                                err.span_label(field.span, "unknown field");
-                                let struct_variant_def = def.non_enum_variant();
-                                let field_names = self.available_field_names(struct_variant_def);
-                                if !field_names.is_empty() {
-                                    err.note(&format!("available fields are: {}",
-                                                      self.name_series_display(field_names)));
-                                }
-                            };
-                    }
-                    ty::Array(_, len) => {
-                        if let (Some(len), Ok(user_index)) = (
-                            len.try_eval_usize(self.tcx, self.param_env),
-                            field.as_str().parse::<u64>()
-                        ) {
-                            let base = self.tcx.sess.source_map()
-                                .span_to_snippet(base.span)
-                                .unwrap_or_else(|_|
-                                    self.tcx.hir().hir_to_pretty_string(base.hir_id));
-                            let help = "instead of using tuple indexing, use array indexing";
-                            let suggestion = format!("{}[{}]", base, field);
-                            let applicability = if len < user_index {
-                                Applicability::MachineApplicable
-                            } else {
-                                Applicability::MaybeIncorrect
-                            };
-                            err.span_suggestion(
-                                expr.span, help, suggestion, applicability
-                            );
-                        }
-                    }
-                    ty::RawPtr(..) => {
-                        let base = self.tcx.sess.source_map()
-                            .span_to_snippet(base.span)
-                            .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
-                        let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
-                        let suggestion = format!("(*{}).{}", base, field);
-                        err.span_suggestion(
-                            expr.span,
-                            &msg,
-                            suggestion,
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                    _ => {}
-                }
-                err
+            type_error_struct!(
+                self.tcx().sess,
+                field.span,
+                expr_t,
+                E0610,
+                "`{}` is a primitive type and therefore doesn't have fields",
+                expr_t
+            )
+            .emit();
+        }
+
+        self.tcx().types.err
+    }
+
+    fn ban_private_field_access(
+        &self,
+        expr: &hir::Expr,
+        expr_t: Ty<'tcx>,
+        field: ast::Ident,
+        base_did: DefId,
+    ) {
+        let struct_path = self.tcx().def_path_str(base_did);
+        let mut err = struct_span_err!(
+            self.tcx().sess,
+            expr.span,
+            E0616,
+            "field `{}` of struct `{}` is private",
+            field,
+            struct_path
+        );
+        // Also check if an accessible method exists, which is often what is meant.
+        if self.method_exists(field, expr_t, expr.hir_id, false)
+            && !self.expr_in_place(expr.hir_id)
+        {
+            self.suggest_method_call(
+                &mut err,
+                &format!("a method `{}` also exists, call it with parentheses", field),
+                field,
+                expr_t,
+                expr.hir_id,
+            );
+        }
+        err.emit();
+    }
+
+    fn ban_take_value_of_method(&self, expr: &hir::Expr, expr_t: Ty<'tcx>, field: ast::Ident) {
+        let mut err = type_error_struct!(
+            self.tcx().sess,
+            field.span,
+            expr_t,
+            E0615,
+            "attempted to take value of method `{}` on type `{}`",
+            field,
+            expr_t
+        );
+
+        if !self.expr_in_place(expr.hir_id) {
+            self.suggest_method_call(
+                &mut err,
+                "use parentheses to call the method",
+                field,
+                expr_t,
+                expr.hir_id
+            );
+        } else {
+            err.help("methods are immutable and cannot be assigned to");
+        }
+
+        err.emit();
+    }
+
+    fn suggest_fields_on_recordish(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        def: &'tcx ty::AdtDef,
+        field: ast::Ident,
+    ) {
+        if let Some(suggested_field_name) =
+            Self::suggest_field_name(def.non_enum_variant(), &field.as_str(), vec![])
+        {
+            err.span_suggestion(
+                field.span,
+                "a field with a similar name exists",
+                suggested_field_name.to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        } else {
+            err.span_label(field.span, "unknown field");
+            let struct_variant_def = def.non_enum_variant();
+            let field_names = self.available_field_names(struct_variant_def);
+            if !field_names.is_empty() {
+                err.note(&format!("available fields are: {}",
+                                    self.name_series_display(field_names)));
+            }
+        }
+    }
+
+    fn maybe_suggest_array_indexing(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr,
+        base: &hir::Expr,
+        field: ast::Ident,
+        len: &ty::Const<'tcx>,
+    ) {
+        if let (Some(len), Ok(user_index)) = (
+            len.try_eval_usize(self.tcx, self.param_env),
+            field.as_str().parse::<u64>()
+        ) {
+            let base = self.tcx.sess.source_map()
+                .span_to_snippet(base.span)
+                .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
+            let help = "instead of using tuple indexing, use array indexing";
+            let suggestion = format!("{}[{}]", base, field);
+            let applicability = if len < user_index {
+                Applicability::MachineApplicable
             } else {
-                type_error_struct!(self.tcx().sess, field.span, expr_t, E0610,
-                                   "`{}` is a primitive type and therefore doesn't have fields",
-                                   expr_t)
-            }.emit();
-            self.tcx().types.err
+                Applicability::MaybeIncorrect
+            };
+            err.span_suggestion(expr.span, help, suggestion, applicability);
         }
     }
 
+    fn suggest_first_deref_field(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        expr: &hir::Expr,
+        base: &hir::Expr,
+        field: ast::Ident,
+    ) {
+        let base = self.tcx.sess.source_map()
+            .span_to_snippet(base.span)
+            .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id));
+        let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
+        let suggestion = format!("(*{}).{}", base, field);
+        err.span_suggestion(
+            expr.span,
+            &msg,
+            suggestion,
+            Applicability::MaybeIncorrect,
+        );
+    }
+
     fn no_such_field_err<T: Display>(&self, span: Span, field: T, expr_t: &ty::TyS<'_>)
         -> DiagnosticBuilder<'_> {
         type_error_struct!(self.tcx().sess, span, expr_t, E0609,
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 8bb24eef5e9..dfbf8bcd0f6 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -67,7 +67,7 @@ pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
     match intrinsic {
         "size_of" | "min_align_of" | "needs_drop" |
         "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
-        "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
+        "wrapping_add" | "wrapping_sub" | "wrapping_mul" |
         "saturating_add" | "saturating_sub" |
         "rotate_left" | "rotate_right" |
         "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" |
@@ -314,7 +314,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
                 (1, vec![param(0), param(0)], param(0)),
             "unchecked_add" | "unchecked_sub" | "unchecked_mul" =>
                 (1, vec![param(0), param(0)], param(0)),
-            "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
+            "wrapping_add" | "wrapping_sub" | "wrapping_mul" =>
                 (1, vec![param(0), param(0)], param(0)),
             "saturating_add" | "saturating_sub" =>
                 (1, vec![param(0), param(0)], param(0)),
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 4a5eba1df88..53024d97c3b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -985,7 +985,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
                 hir::ItemKind::Use(..) => {
                     // Don't suggest placing a `use` before the prelude
                     // import or other generated ones.
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         self.span = Some(item.span.shrink_to_lo());
                         self.found_use = true;
                         return;
@@ -995,7 +995,7 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> {
                 hir::ItemKind::ExternCrate(_) => {}
                 // ...but do place them before the first other item.
                 _ => if self.span.map_or(true, |span| item.span < span ) {
-                    if item.span.ctxt().outer_expn_info().is_none() {
+                    if !item.span.from_expansion() {
                         // Don't insert between attributes and an item.
                         if item.attrs.is_empty() {
                             self.span = Some(item.span.shrink_to_lo());
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 92f8fb30db8..fc1ee649e28 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2943,7 +2943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             (PlaceOp::Index, false) => (self.tcx.lang_items().index_trait(), sym::index),
             (PlaceOp::Index, true) => (self.tcx.lang_items().index_mut_trait(), sym::index_mut),
         };
-        (tr, ast::Ident::with_empty_ctxt(name))
+        (tr, ast::Ident::with_dummy_span(name))
     }
 
     fn try_overloaded_place_op(&self,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index b2c0e34d6fa..28a1ccda4d8 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -203,7 +203,6 @@ fn check_associated_item(
                 fcx.register_wf_obligation(ty, span, code.clone());
             }
             ty::AssocKind::Method => {
-                reject_shadowing_parameters(fcx.tcx, item.def_id);
                 let sig = fcx.tcx.fn_sig(item.def_id);
                 let sig = fcx.normalize_associated_types_in(span, &sig);
                 check_fn_or_method(tcx, fcx, span, sig,
@@ -998,34 +997,6 @@ fn report_bivariance(tcx: TyCtxt<'_>, span: Span, param_name: ast::Name) {
     err.emit();
 }
 
-fn reject_shadowing_parameters(tcx: TyCtxt<'_>, def_id: DefId) {
-    let generics = tcx.generics_of(def_id);
-    let parent = tcx.generics_of(generics.parent.unwrap());
-    let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
-        GenericParamDefKind::Lifetime => None,
-        GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => {
-            Some((param.name, param.def_id))
-        }
-    }).collect();
-
-    for method_param in &generics.params {
-        // Shadowing is checked in `resolve_lifetime`.
-        if let GenericParamDefKind::Lifetime = method_param.kind {
-            continue
-        }
-        if impl_params.contains_key(&method_param.name) {
-            // Tighten up the span to focus on only the shadowing type.
-            let type_span = tcx.def_span(method_param.def_id);
-
-            // The expectation here is that the original trait declaration is
-            // local so it should be okay to just unwrap everything.
-            let trait_def_id = impl_params[&method_param.name];
-            let trait_decl_span = tcx.def_span(trait_def_id);
-            error_194(tcx, type_span, trait_decl_span, &method_param.name.as_str()[..]);
-        }
-    }
-}
-
 /// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
 /// aren't true.
 fn check_false_global_bounds(fcx: &FnCtxt<'_, '_>, span: Span, id: hir::HirId) {
@@ -1152,12 +1123,3 @@ fn error_392(
     err.span_label(span, "unused parameter");
     err
 }
-
-fn error_194(tcx: TyCtxt<'_>, span: Span, trait_decl_span: Span, name: &str) {
-    struct_span_err!(tcx.sess, span, E0194,
-                     "type parameter `{}` shadows another type parameter of the same name",
-                     name)
-        .span_label(span, "shadows another type parameter")
-        .span_label(trait_decl_span, format!("first `{}` declared here", name))
-        .emit();
-}
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 90118a9f191..ca9ce3d22b5 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -1718,22 +1718,6 @@ Since we know for certain that `Wrapper<u32>` implements `Clone`, there's no
 reason to also specify it in a `where` clause.
 "##,
 
-E0194: r##"
-A type parameter was declared which shadows an existing one. An example of this
-error:
-
-```compile_fail,E0194
-trait Foo<T> {
-    fn do_something(&self) -> T;
-    fn do_something_else<T: Clone>(&self, bar: T);
-}
-```
-
-In this example, the trait `Foo` and the trait method `do_something_else` both
-define a type parameter `T`. This is not allowed: if the method wishes to
-define a type parameter, it must use a different name for it.
-"##,
-
 E0195: r##"
 Your method's lifetime parameters do not match the trait declaration.
 Erroneous code example:
@@ -4837,6 +4821,7 @@ register_diagnostics! {
 //  E0188, // can not cast an immutable reference to a mutable pointer
 //  E0189, // deprecated: can only cast a boxed pointer to a boxed object
 //  E0190, // deprecated: can only cast a &-pointer to an &-object
+//  E0194, // merged into E0403
 //  E0196, // cannot determine a type for this closure
     E0203, // type parameter has more than one relaxed default bound,
            // and only one is supported
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d5becd2e1a9..023d22861de 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -930,7 +930,7 @@ impl Attributes {
             if attr.check_name(sym::enable) {
                 if let Some(feat) = attr.value_str() {
                     let meta = attr::mk_name_value_item_str(
-                        Ident::with_empty_ctxt(sym::target_feature), feat, DUMMY_SP
+                        Ident::with_dummy_span(sym::target_feature), feat, DUMMY_SP
                     );
                     if let Ok(feat_cfg) = Cfg::parse(&meta) {
                         cfg &= feat_cfg;
@@ -4107,6 +4107,9 @@ fn name_from_pat(p: &hir::Pat) -> String {
                 if etc { ", .." } else { "" }
             )
         }
+        PatKind::Or(ref pats) => {
+            pats.iter().map(|p| name_from_pat(&**p)).collect::<Vec<String>>().join(" | ")
+        }
         PatKind::Tuple(ref elts, _) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
                                             .collect::<Vec<String>>().join(", ")),
         PatKind::Box(ref p) => name_from_pat(&**p),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 5c9fac7eab4..c73c46472d8 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -4,6 +4,7 @@ use rustc::hir::def_id::DefId;
 use rustc::hir;
 use rustc::lint as lint;
 use rustc::ty;
+use rustc_resolve::ParentScope;
 use syntax;
 use syntax::ast::{self, Ident};
 use syntax::ext::base::SyntaxExtensionKind;
@@ -431,7 +432,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
     let path = ast::Path::from_ident(Ident::from_str(path_str));
     cx.enter_resolver(|resolver| {
         if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
-            &path, None, &resolver.dummy_parent_scope(), false, false
+            &path, None, &ParentScope::module(resolver.graph_root), false, false
         ) {
             if let SyntaxExtensionKind::LegacyBang { .. } = ext.kind {
                 return Some(res.map_id(|_| panic!("unexpected id")));
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 5334c4dfc68..3288d0b4df2 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -23,7 +23,7 @@ libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of
 compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
-hashbrown = { version = "0.4.0", features = ['rustc-dep-of-std'] }
+hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
 [dependencies.backtrace]
 version = "0.3.34"
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 1e28ee8da26..a0538986a22 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -6,7 +6,7 @@ use hashbrown::hash_map as base;
 
 use crate::borrow::Borrow;
 use crate::cell::Cell;
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::fmt::{self, Debug};
 #[allow(deprecated)]
 use crate::hash::{BuildHasher, Hash, Hasher, SipHasher13};
@@ -588,7 +588,7 @@ where
     /// ```
     #[inline]
     #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.base
             .try_reserve(additional)
             .map_err(map_collection_alloc_err)
@@ -2542,10 +2542,13 @@ fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K,
 }
 
 #[inline]
-fn map_collection_alloc_err(err: hashbrown::CollectionAllocErr) -> CollectionAllocErr {
+fn map_collection_alloc_err(err: hashbrown::CollectionAllocErr) -> TryReserveError {
     match err {
-        hashbrown::CollectionAllocErr::CapacityOverflow => CollectionAllocErr::CapacityOverflow,
-        hashbrown::CollectionAllocErr::AllocErr => CollectionAllocErr::AllocErr,
+        hashbrown::CollectionAllocErr::CapacityOverflow => TryReserveError::CapacityOverflow,
+        hashbrown::CollectionAllocErr::AllocErr { layout } => TryReserveError::AllocError {
+            layout,
+            non_exhaustive: (),
+        },
     }
 }
 
@@ -2605,7 +2608,7 @@ mod test_map {
     use super::RandomState;
     use crate::cell::RefCell;
     use rand::{thread_rng, Rng};
-    use realstd::collections::CollectionAllocErr::*;
+    use realstd::collections::TryReserveError::*;
     use realstd::usize;
 
     // https://github.com/rust-lang/rust/issues/62301
@@ -3405,7 +3408,7 @@ mod test_map {
             panic!("usize::MAX should trigger an overflow!");
         }
 
-        if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE / 8) {
+        if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
         } else {
             panic!("usize::MAX / 8 should trigger an OOM!")
         }
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index d243412405a..26db651ef89 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -1,5 +1,5 @@
 use crate::borrow::Borrow;
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::fmt;
 use crate::hash::{Hash, BuildHasher};
 use crate::iter::{Chain, FromIterator, FusedIterator};
@@ -383,7 +383,7 @@ impl<T, S> HashSet<T, S>
     /// ```
     #[inline]
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.map.try_reserve(additional)
     }
 
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index 15c2532f8b4..f5957466be8 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -427,7 +427,7 @@ pub use self::hash_map::HashMap;
 pub use self::hash_set::HashSet;
 
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-pub use alloc_crate::collections::CollectionAllocErr;
+pub use alloc_crate::collections::TryReserveError;
 
 mod hash;
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 1f48315d3f8..c3882bacf87 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -228,7 +228,6 @@
 // std is implemented with unstable features, many of which are internal
 // compiler details that will never be stable
 // NB: the following list is sorted to minimize merge conflicts.
-#![feature(__rust_unstable_column)]
 #![feature(alloc_error_handler)]
 #![feature(alloc_layout_extra)]
 #![feature(allocator_api)]
@@ -251,6 +250,7 @@
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
 #![feature(const_raw_ptr_deref)]
+#![feature(container_error_extra)]
 #![feature(core_intrinsics)]
 #![feature(custom_test_frameworks)]
 #![feature(doc_alias)]
@@ -550,7 +550,6 @@ pub use core::{
     option_env,
     stringify,
     // Unstable
-    __rust_unstable_column,
     asm,
     concat_idents,
     format_args_nl,
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index f2000936b9a..cbeaf20b13a 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -53,20 +53,20 @@
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable(__rust_unstable_column, libstd_sys_internals)]
+#[allow_internal_unstable(libstd_sys_internals)]
 macro_rules! panic {
     () => ({
         $crate::panic!("explicit panic")
     });
     ($msg:expr) => ({
-        $crate::rt::begin_panic($msg, &(file!(), line!(), __rust_unstable_column!()))
+        $crate::rt::begin_panic($msg, &($crate::file!(), $crate::line!(), $crate::column!()))
     });
     ($msg:expr,) => ({
         $crate::panic!($msg)
     });
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+),
-                                    &(file!(), line!(), __rust_unstable_column!()))
+        $crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+),
+                                    &($crate::file!(), $crate::line!(), $crate::column!()))
     });
 }
 
@@ -113,7 +113,7 @@ macro_rules! panic {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(print_internals)]
 macro_rules! print {
-    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
+    ($($arg:tt)*) => ($crate::io::_print($crate::format_args!($($arg)*)));
 }
 
 /// Prints to the standard output, with a newline.
@@ -147,7 +147,7 @@ macro_rules! print {
 macro_rules! println {
     () => ($crate::print!("\n"));
     ($($arg:tt)*) => ({
-        $crate::io::_print(format_args_nl!($($arg)*));
+        $crate::io::_print($crate::format_args_nl!($($arg)*));
     })
 }
 
@@ -176,7 +176,7 @@ macro_rules! println {
 #[stable(feature = "eprint", since = "1.19.0")]
 #[allow_internal_unstable(print_internals)]
 macro_rules! eprint {
-    ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
+    ($($arg:tt)*) => ($crate::io::_eprint($crate::format_args!($($arg)*)));
 }
 
 /// Prints to the standard error, with a newline.
@@ -206,7 +206,7 @@ macro_rules! eprint {
 macro_rules! eprintln {
     () => ($crate::eprint!("\n"));
     ($($arg:tt)*) => ({
-        $crate::io::_eprint(format_args_nl!($($arg)*));
+        $crate::io::_eprint($crate::format_args_nl!($($arg)*));
     })
 }
 
@@ -337,7 +337,7 @@ macro_rules! eprintln {
 #[stable(feature = "dbg_macro", since = "1.32.0")]
 macro_rules! dbg {
     () => {
-        $crate::eprintln!("[{}:{}]", file!(), line!());
+        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
     };
     ($val:expr) => {
         // Use of `match` here is intentional because it affects the lifetimes
@@ -345,7 +345,7 @@ macro_rules! dbg {
         match $val {
             tmp => {
                 $crate::eprintln!("[{}:{}] {} = {:#?}",
-                    file!(), line!(), stringify!($val), &tmp);
+                    $crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);
                 tmp
             }
         }
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
index 752c6202ee4..3e4cf91127f 100644
--- a/src/libstd/prelude/v1.rs
+++ b/src/libstd/prelude/v1.rs
@@ -40,7 +40,6 @@ pub use crate::result::Result::{self, Ok, Err};
 #[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
 #[doc(no_inline)]
 pub use core::prelude::v1::{
-    __rust_unstable_column,
     asm,
     assert,
     cfg,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 3ae37f734b7..50e428ea0cc 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -5,7 +5,7 @@ pub use UnsafeSource::*;
 pub use crate::symbol::{Ident, Symbol as Name};
 pub use crate::util::parser::ExprPrecedence;
 
-use crate::ext::hygiene::{ExpnId, SyntaxContext};
+use crate::ext::hygiene::ExpnId;
 use crate::parse::token::{self, DelimToken};
 use crate::print::pprust;
 use crate::ptr::P;
@@ -572,9 +572,10 @@ impl Pat {
         match &self.node {
             PatKind::Ident(_, _, Some(p)) => p.walk(it),
             PatKind::Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk(it)),
-            PatKind::TupleStruct(_, s) | PatKind::Tuple(s) | PatKind::Slice(s) => {
-                s.iter().all(|p| p.walk(it))
-            }
+            PatKind::TupleStruct(_, s)
+            | PatKind::Tuple(s)
+            | PatKind::Slice(s)
+            | PatKind::Or(s) => s.iter().all(|p| p.walk(it)),
             PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
             PatKind::Wild
             | PatKind::Rest
@@ -648,6 +649,10 @@ pub enum PatKind {
     /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
     TupleStruct(Path, Vec<P<Pat>>),
 
+    /// An or-pattern `A | B | C`.
+    /// Invariant: `pats.len() >= 2`.
+    Or(Vec<P<Pat>>),
+
     /// A possibly qualified path pattern.
     /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
     /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
@@ -1782,7 +1787,6 @@ pub struct InlineAsm {
     pub volatile: bool,
     pub alignstack: bool,
     pub dialect: AsmDialect,
-    pub ctxt: SyntaxContext,
 }
 
 /// An argument in a function header.
@@ -2030,7 +2034,6 @@ pub struct ForeignMod {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub struct GlobalAsm {
     pub asm: Symbol,
-    pub ctxt: SyntaxContext,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 85c661d320a..bcf03b5237a 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -327,7 +327,7 @@ impl Attribute {
         if self.is_sugared_doc {
             let comment = self.value_str().unwrap();
             let meta = mk_name_value_item_str(
-                Ident::with_empty_ctxt(sym::doc),
+                Ident::with_dummy_span(sym::doc),
                 Symbol::intern(&strip_doc_comment_decoration(&comment.as_str())),
                 DUMMY_SP,
             );
@@ -412,7 +412,7 @@ pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute {
     Attribute {
         id: mk_attr_id(),
         style,
-        path: Path::from_ident(Ident::with_empty_ctxt(sym::doc).with_span_pos(span)),
+        path: Path::from_ident(Ident::with_dummy_span(sym::doc).with_span_pos(span)),
         tokens: MetaItemKind::NameValue(lit).tokens(span),
         is_sugared_doc: true,
         span,
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 80591ad304d..9618b5acfb0 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -172,7 +172,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    let static_ = ecx.lifetime(span, Ident::with_empty_ctxt(kw::StaticLifetime));
+    let static_ = ecx.lifetime(span, Ident::with_dummy_span(kw::StaticLifetime));
     let ty_str = ecx.ty_rptr(
         span,
         ecx.ty_ident(span, ecx.ident_of("str")),
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index edeca046c7b..b0a4a6af983 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1,4 +1,4 @@
-use crate::ast::{self, Attribute, Name, PatKind};
+use crate::ast::{self, NodeId, Attribute, Name, PatKind};
 use crate::attr::{HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
@@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
 use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnInfo, ExpnKind};
+use syntax_pos::hygiene::{ExpnData, ExpnKind};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
@@ -640,10 +640,11 @@ impl SyntaxExtension {
         SyntaxExtension::default(SyntaxExtensionKind::NonMacroAttr { mark_used }, edition)
     }
 
-    pub fn expn_info(&self, call_site: Span, descr: Symbol) -> ExpnInfo {
-        ExpnInfo {
-            call_site,
+    pub fn expn_data(&self, parent: ExpnId, call_site: Span, descr: Symbol) -> ExpnData {
+        ExpnData {
             kind: ExpnKind::Macro(self.macro_kind(), descr),
+            parent,
+            call_site,
             def_site: self.span,
             default_transparency: self.default_transparency,
             allow_internal_unstable: self.allow_internal_unstable.clone(),
@@ -670,13 +671,13 @@ bitflags::bitflags! {
 }
 
 pub trait Resolver {
-    fn next_node_id(&mut self) -> ast::NodeId;
+    fn next_node_id(&mut self) -> NodeId;
 
-    fn get_module_scope(&mut self, id: ast::NodeId) -> ExpnId;
+    fn get_module_scope(&mut self, id: NodeId) -> ExpnId;
 
     fn resolve_dollar_crates(&mut self);
     fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
-                                            derives: &[ExpnId]);
+                                            extra_placeholders: &[NodeId]);
     fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
 
     fn resolve_imports(&mut self);
@@ -707,7 +708,7 @@ pub struct ExpansionData {
 
 /// One of these is made during expansion and incrementally updated as we go;
 /// when a macro expansion occurs, the resulting nodes have the `backtrace()
-/// -> expn_info` of their expansion context stored into their span.
+/// -> expn_data` of their expansion context stored into their span.
 pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
     pub ecfg: expand::ExpansionConfig<'a>,
@@ -756,13 +757,10 @@ impl<'a> ExtCtxt<'a> {
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
     pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
     pub fn call_site(&self) -> Span {
-        match self.current_expansion.id.expn_info() {
-            Some(expn_info) => expn_info.call_site,
-            None => DUMMY_SP,
-        }
+        self.current_expansion.id.expn_data().call_site
     }
     pub fn backtrace(&self) -> SyntaxContext {
-        SyntaxContext::empty().apply_mark(self.current_expansion.id)
+        SyntaxContext::root().apply_mark(self.current_expansion.id)
     }
 
     /// Returns span for the macro which originally caused the current expansion to happen.
@@ -772,17 +770,13 @@ impl<'a> ExtCtxt<'a> {
         let mut ctxt = self.backtrace();
         let mut last_macro = None;
         loop {
-            if ctxt.outer_expn_info().map_or(None, |info| {
-                if info.kind.descr() == sym::include {
-                    // Stop going up the backtrace once include! is encountered
-                    return None;
-                }
-                ctxt = info.call_site.ctxt();
-                last_macro = Some(info.call_site);
-                Some(())
-            }).is_none() {
-                break
+            let expn_data = ctxt.outer_expn_data();
+            // Stop going up the backtrace once include! is encountered
+            if expn_data.is_root() || expn_data.kind.descr() == sym::include {
+                break;
             }
+            ctxt = expn_data.call_site.ctxt();
+            last_macro = Some(expn_data.call_site);
         }
         last_macro
     }
@@ -872,7 +866,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
         let def_site = DUMMY_SP.apply_mark(self.current_expansion.id);
         iter::once(Ident::new(kw::DollarCrate, def_site))
-            .chain(components.iter().map(|&s| Ident::with_empty_ctxt(s)))
+            .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
             .collect()
     }
     pub fn name_of(&self, st: &str) -> ast::Name {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 38f46ee207c..e2ac4d573a1 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -340,7 +340,7 @@ impl<'a> ExtCtxt<'a> {
         self.expr_path(self.path_ident(span, id))
     }
     pub fn expr_self(&self, span: Span) -> P<ast::Expr> {
-        self.expr_ident(span, Ident::with_empty_ctxt(kw::SelfLower))
+        self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
     }
 
     pub fn expr_binary(&self, sp: Span, op: ast::BinOpKind,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 97983944931..c1d52c97455 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -5,7 +5,7 @@ use crate::source_map::respan;
 use crate::config::StripUnconfigured;
 use crate::ext::base::*;
 use crate::ext::proc_macro::collect_derives;
-use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind};
+use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind};
 use crate::ext::tt::macro_rules::annotate_err_with_kind;
 use crate::ext::placeholders::{placeholder, PlaceholderExpander};
 use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
@@ -25,7 +25,6 @@ use syntax_pos::{Span, DUMMY_SP, FileName};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
-use std::fs;
 use std::io::ErrorKind;
 use std::{iter, mem};
 use std::ops::DerefMut;
@@ -292,7 +291,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         // Unresolved macros produce dummy outputs as a recovery measure.
         invocations.reverse();
         let mut expanded_fragments = Vec::new();
-        let mut derives: FxHashMap<ExpnId, Vec<_>> = FxHashMap::default();
+        let mut all_derive_placeholders: FxHashMap<ExpnId, Vec<_>> = FxHashMap::default();
         let mut undetermined_invocations = Vec::new();
         let (mut progress, mut force) = (false, !self.monotonic);
         loop {
@@ -348,13 +347,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
 
                 let mut item = self.fully_configure(item);
                 item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
-                let derives = derives.entry(invoc.expansion_data.id).or_default();
+                let derive_placeholders =
+                    all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
 
-                derives.reserve(traits.len());
+                derive_placeholders.reserve(traits.len());
                 invocations.reserve(traits.len());
                 for path in traits {
-                    let expn_id = ExpnId::fresh(self.cx.current_expansion.id, None);
-                    derives.push(expn_id);
+                    let expn_id = ExpnId::fresh(None);
+                    derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
                     invocations.push(Invocation {
                         kind: InvocationKind::Derive { path, item: item.clone() },
                         fragment_kind: invoc.fragment_kind,
@@ -366,7 +366,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 }
                 let fragment = invoc.fragment_kind
                     .expect_from_annotatables(::std::iter::once(item));
-                self.collect_invocations(fragment, derives)
+                self.collect_invocations(fragment, derive_placeholders)
             } else {
                 unreachable!()
             };
@@ -385,10 +385,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         // Finally incorporate all the expanded macros into the input AST fragment.
         let mut placeholder_expander = PlaceholderExpander::new(self.cx, self.monotonic);
         while let Some(expanded_fragments) = expanded_fragments.pop() {
-            for (mark, expanded_fragment) in expanded_fragments.into_iter().rev() {
-                let derives = derives.remove(&mark).unwrap_or_else(Vec::new);
-                placeholder_expander.add(NodeId::placeholder_from_expn_id(mark),
-                                         expanded_fragment, derives);
+            for (expn_id, expanded_fragment) in expanded_fragments.into_iter().rev() {
+                let derive_placeholders =
+                    all_derive_placeholders.remove(&expn_id).unwrap_or_else(Vec::new);
+                placeholder_expander.add(NodeId::placeholder_from_expn_id(expn_id),
+                                         expanded_fragment, derive_placeholders);
             }
         }
         fragment_with_placeholders.mut_visit_with(&mut placeholder_expander);
@@ -405,7 +406,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
     /// them with "placeholders" - dummy macro invocations with specially crafted `NodeId`s.
     /// Then call into resolver that builds a skeleton ("reduced graph") of the fragment and
     /// prepares data for resolving paths of macro invocations.
-    fn collect_invocations(&mut self, mut fragment: AstFragment, derives: &[ExpnId])
+    fn collect_invocations(&mut self, mut fragment: AstFragment, extra_placeholders: &[NodeId])
                            -> (AstFragment, Vec<Invocation>) {
         // Resolve `$crate`s in the fragment for pretty-printing.
         self.cx.resolver.resolve_dollar_crates();
@@ -424,9 +425,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             collector.invocations
         };
 
+        // FIXME: Merge `extra_placeholders` into the `fragment` as regular placeholders.
         if self.monotonic {
             self.cx.resolver.visit_ast_fragment_with_placeholders(
-                self.cx.current_expansion.id, &fragment, derives);
+                self.cx.current_expansion.id, &fragment, extra_placeholders);
         }
 
         (fragment, invocations)
@@ -475,11 +477,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         }
 
         if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit {
-            let info = self.cx.current_expansion.id.expn_info().unwrap();
+            let expn_data = self.cx.current_expansion.id.expn_data();
             let suggested_limit = self.cx.ecfg.recursion_limit * 2;
-            let mut err = self.cx.struct_span_err(info.call_site,
+            let mut err = self.cx.struct_span_err(expn_data.call_site,
                 &format!("recursion limit reached while expanding the macro `{}`",
-                         info.kind.descr()));
+                         expn_data.kind.descr()));
             err.help(&format!(
                 "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
                 suggested_limit));
@@ -759,7 +761,7 @@ impl<'a> Parser<'a> {
             let msg = format!("macro expansion ignores token `{}` and any following",
                               self.this_token_to_string());
             // Avoid emitting backtrace info twice.
-            let def_site_span = self.token.span.with_ctxt(SyntaxContext::empty());
+            let def_site_span = self.token.span.with_ctxt(SyntaxContext::root());
             let mut err = self.diagnostic().struct_span_err(def_site_span, &msg);
             err.span_label(span, "caused by the macro expansion here");
             let msg = format!(
@@ -796,17 +798,20 @@ struct InvocationCollector<'a, 'b> {
 
 impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
-        // Expansion info for all the collected invocations is set upon their resolution,
+        // Expansion data for all the collected invocations is set upon their resolution,
         // with exception of the derive container case which is not resolved and can get
-        // its expansion info immediately.
-        let expn_info = match &kind {
-            InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default(
-                ExpnKind::Macro(MacroKind::Attr, sym::derive),
-                item.span(), self.cx.parse_sess.edition,
-            )),
+        // its expansion data immediately.
+        let expn_data = match &kind {
+            InvocationKind::DeriveContainer { item, .. } => Some(ExpnData {
+                parent: self.cx.current_expansion.id,
+                ..ExpnData::default(
+                    ExpnKind::Macro(MacroKind::Attr, sym::derive),
+                    item.span(), self.cx.parse_sess.edition,
+                )
+            }),
             _ => None,
         };
-        let expn_id = ExpnId::fresh(self.cx.current_expansion.id, expn_info);
+        let expn_id = ExpnId::fresh(expn_data);
         self.invocations.push(Invocation {
             kind,
             fragment_kind,
@@ -1238,32 +1243,30 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                     }
 
                     let filename = self.cx.resolve_path(&*file.as_str(), it.span());
-                    match fs::read_to_string(&filename) {
-                        Ok(src) => {
-                            let src_interned = Symbol::intern(&src);
-
-                            // Add this input file to the code map to make it available as
-                            // dependency information
-                            self.cx.source_map().new_source_file(filename.into(), src);
+                    match self.cx.source_map().load_file(&filename) {
+                        Ok(source_file) => {
+                            let src = source_file.src.as_ref()
+                                .expect("freshly loaded file should have a source");
+                            let src_interned = Symbol::intern(src.as_str());
 
                             let include_info = vec![
                                 ast::NestedMetaItem::MetaItem(
                                     attr::mk_name_value_item_str(
-                                        Ident::with_empty_ctxt(sym::file),
+                                        Ident::with_dummy_span(sym::file),
                                         file,
                                         DUMMY_SP,
                                     ),
                                 ),
                                 ast::NestedMetaItem::MetaItem(
                                     attr::mk_name_value_item_str(
-                                        Ident::with_empty_ctxt(sym::contents),
+                                        Ident::with_dummy_span(sym::contents),
                                         src_interned,
                                         DUMMY_SP,
                                     ),
                                 ),
                             ];
 
-                            let include_ident = Ident::with_empty_ctxt(sym::include);
+                            let include_ident = Ident::with_dummy_span(sym::include);
                             let item = attr::mk_list_item(include_ident, include_info);
                             items.push(ast::NestedMetaItem::MetaItem(item));
                         }
@@ -1325,7 +1328,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                 }
             }
 
-            let meta = attr::mk_list_item(Ident::with_empty_ctxt(sym::doc), items);
+            let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items);
             *at = attr::Attribute {
                 span: at.span,
                 id: at.id,
diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs
index 2d05f8f0b00..d800cfedcfb 100644
--- a/src/libsyntax/ext/placeholders.rs
+++ b/src/libsyntax/ext/placeholders.rs
@@ -2,7 +2,6 @@ use crate::ast::{self, NodeId};
 use crate::source_map::{DUMMY_SP, dummy_spanned};
 use crate::ext::base::ExtCtxt;
 use crate::ext::expand::{AstFragment, AstFragmentKind};
-use crate::ext::hygiene::ExpnId;
 use crate::tokenstream::TokenStream;
 use crate::mut_visit::*;
 use crate::ptr::P;
@@ -86,11 +85,11 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
         }
     }
 
-    pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, derives: Vec<ExpnId>) {
+    pub fn add(&mut self, id: ast::NodeId, mut fragment: AstFragment, placeholders: Vec<NodeId>) {
         fragment.mut_visit_with(self);
         if let AstFragment::Items(mut items) = fragment {
-            for derive in derives {
-                match self.remove(NodeId::placeholder_from_expn_id(derive)) {
+            for placeholder in placeholders {
+                match self.remove(placeholder) {
                     AstFragment::Items(derived_items) => items.extend(derived_items),
                     _ => unreachable!(),
                 }
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 36621ce7775..1619fa69941 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -362,10 +362,10 @@ pub(crate) struct Rustc<'a> {
 impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
         // No way to determine def location for a proc macro right now, so use call location.
-        let location = cx.current_expansion.id.expn_info().unwrap().call_site;
+        let location = cx.current_expansion.id.expn_data().call_site;
         let to_span = |transparency| {
             location.with_ctxt(
-                SyntaxContext::empty()
+                SyntaxContext::root()
                     .apply_mark_with_transparency(cx.current_expansion.id, transparency),
             )
         };
@@ -677,7 +677,7 @@ impl server::Span for Rustc<'_> {
         self.sess.source_map().lookup_char_pos(span.lo()).file
     }
     fn parent(&mut self, span: Self::Span) -> Option<Self::Span> {
-        span.ctxt().outer_expn_info().map(|i| i.call_site)
+        span.parent()
     }
     fn source(&mut self, span: Self::Span) -> Self::Span {
         span.source_callsite()
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 8a56ae13b6f..bbc3ae28225 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -30,7 +30,6 @@ use crate::tokenstream::TokenTree;
 
 use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lock;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
@@ -560,6 +559,9 @@ declare_features! (
     // Allows `impl Trait` to be used inside type aliases (RFC 2515).
     (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
 
+    // Allows the use of or-patterns, e.g. `0 | 1`.
+    (active, or_patterns, "1.38.0", Some(54883), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
@@ -572,6 +574,7 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
     sym::impl_trait_in_bindings,
     sym::generic_associated_types,
     sym::const_generics,
+    sym::or_patterns,
     sym::let_chains,
 ];
 
@@ -2088,11 +2091,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                        "type ascription is experimental");
                 }
             }
-            ast::ExprKind::Yield(..) => {
-                gate_feature_post!(&self, generators,
-                                  e.span,
-                                  "yield syntax is experimental");
-            }
             ast::ExprKind::TryBlock(_) => {
                 gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
             }
@@ -2427,10 +2425,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
     features
 }
 
-fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
-    vec.borrow().iter().for_each(f);
-}
-
 pub fn check_crate(krate: &ast::Crate,
                    sess: &ParseSess,
                    features: &Features,
@@ -2443,26 +2437,17 @@ pub fn check_crate(krate: &ast::Crate,
         plugin_attributes,
     };
 
-    for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
-        &ctx,
-        param_attrs,
-        *span,
-        "attributes on function parameters are unstable"
-    ));
-
-    for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
-        &ctx,
-        let_chains,
-        *span,
-        "`let` expressions in this position are experimental"
-    ));
-
-    for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
-        &ctx,
-        async_closure,
-        *span,
-        "async closures are unstable"
-    ));
+    macro_rules! gate_all {
+        ($spans:ident, $gate:ident, $msg:literal) => {
+            for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); }
+        }
+    }
+
+    gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable");
+    gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental");
+    gate_all!(async_closure_spans, async_closure, "async closures are unstable");
+    gate_all!(yield_spans, generators, "yield syntax is experimental");
+    gate_all!(or_pattern_spans, or_patterns, "or-patterns syntax is experimental");
 
     let visitor = &mut PostExpansionVisitor {
         context: &ctx,
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index acafe327640..9785f8e2de0 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -1050,7 +1050,6 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
                 vis.visit_span(span);
             };
         }
-        PatKind::Tuple(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)),
         PatKind::Box(inner) => vis.visit_pat(inner),
         PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner),
         PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => {
@@ -1058,7 +1057,9 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
             vis.visit_expr(e2);
             vis.visit_span(span);
         }
-        PatKind::Slice(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)),
+        PatKind::Tuple(elems)
+        | PatKind::Slice(elems)
+        | PatKind::Or(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)),
         PatKind::Paren(inner) => vis.visit_pat(inner),
         PatKind::Mac(mac) => vis.visit_mac(mac),
     }
@@ -1182,7 +1183,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
         }
         ExprKind::InlineAsm(asm) => {
             let InlineAsm { asm: _, asm_str_style: _, outputs, inputs, clobbers: _, volatile: _,
-                            alignstack: _, dialect: _, ctxt: _ } = asm.deref_mut();
+                            alignstack: _, dialect: _ } = asm.deref_mut();
             for out in outputs {
                 let InlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
                 vis.visit_expr(expr);
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index e86d4c7fde6..bdf468a52bb 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -4,13 +4,11 @@ use crate::symbol::{sym, Symbol};
 use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 use errors::{FatalError, DiagnosticBuilder};
-use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
+use syntax_pos::{BytePos, Pos, Span};
 use rustc_lexer::Base;
 use rustc_lexer::unescape;
 
-use std::borrow::Cow;
 use std::char;
-use std::iter;
 use std::convert::TryInto;
 use rustc_data_structures::sync::Lrc;
 use log::debug;
@@ -84,7 +82,7 @@ impl<'a> StringReader<'a> {
 
 
     fn mk_sp(&self, lo: BytePos, hi: BytePos) -> Span {
-        self.override_span.unwrap_or_else(|| Span::new(lo, hi, NO_EXPANSION))
+        self.override_span.unwrap_or_else(|| Span::with_root_ctxt(lo, hi))
     }
 
     /// Returns the next token, including trivia like whitespace or comments.
@@ -181,18 +179,7 @@ impl<'a> StringReader<'a> {
                 let string = self.str_from(start);
                 // comments with only more "/"s are not doc comments
                 let tok = if is_doc_comment(string) {
-                    let mut idx = 0;
-                    loop {
-                        idx = match string[idx..].find('\r') {
-                            None => break,
-                            Some(it) => idx + it + 1
-                        };
-                        if string[idx..].chars().next() != Some('\n') {
-                            self.err_span_(start + BytePos(idx as u32 - 1),
-                                            start + BytePos(idx as u32),
-                                            "bare CR not allowed in doc-comment");
-                        }
-                    }
+                    self.forbid_bare_cr(start, string, "bare CR not allowed in doc-comment");
                     token::DocComment(Symbol::intern(string))
                 } else {
                     token::Comment
@@ -217,15 +204,10 @@ impl<'a> StringReader<'a> {
                 }
 
                 let tok = if is_doc_comment {
-                    let has_cr = string.contains('\r');
-                    let string = if has_cr {
-                        self.translate_crlf(start,
-                                            string,
-                                            "bare CR not allowed in block doc-comment")
-                    } else {
-                        string.into()
-                    };
-                    token::DocComment(Symbol::intern(&string[..]))
+                    self.forbid_bare_cr(start,
+                                        string,
+                                        "bare CR not allowed in block doc-comment");
+                    token::DocComment(Symbol::intern(string))
                 } else {
                     token::Comment
                 };
@@ -516,49 +498,16 @@ impl<'a> StringReader<'a> {
         &self.src[self.src_index(start)..self.src_index(end)]
     }
 
-    /// Converts CRLF to LF in the given string, raising an error on bare CR.
-    fn translate_crlf<'b>(&self, start: BytePos, s: &'b str, errmsg: &'b str) -> Cow<'b, str> {
-        let mut chars = s.char_indices().peekable();
-        while let Some((i, ch)) = chars.next() {
-            if ch == '\r' {
-                if let Some((lf_idx, '\n')) = chars.peek() {
-                    return translate_crlf_(self, start, s, *lf_idx, chars, errmsg).into();
-                }
-                let pos = start + BytePos(i as u32);
-                let end_pos = start + BytePos((i + ch.len_utf8()) as u32);
-                self.err_span_(pos, end_pos, errmsg);
-            }
-        }
-        return s.into();
-
-        fn translate_crlf_(rdr: &StringReader<'_>,
-                           start: BytePos,
-                           s: &str,
-                           mut j: usize,
-                           mut chars: iter::Peekable<impl Iterator<Item = (usize, char)>>,
-                           errmsg: &str)
-                           -> String {
-            let mut buf = String::with_capacity(s.len());
-            // Skip first CR
-            buf.push_str(&s[.. j - 1]);
-            while let Some((i, ch)) = chars.next() {
-                if ch == '\r' {
-                    if j < i {
-                        buf.push_str(&s[j..i]);
-                    }
-                    let next = i + ch.len_utf8();
-                    j = next;
-                    if chars.peek().map(|(_, ch)| *ch) != Some('\n') {
-                        let pos = start + BytePos(i as u32);
-                        let end_pos = start + BytePos(next as u32);
-                        rdr.err_span_(pos, end_pos, errmsg);
-                    }
-                }
-            }
-            if j < s.len() {
-                buf.push_str(&s[j..]);
-            }
-            buf
+    fn forbid_bare_cr(&self, start: BytePos, s: &str, errmsg: &str) {
+        let mut idx = 0;
+        loop {
+            idx = match s[idx..].find('\r') {
+                None => break,
+                Some(it) => idx + it + 1
+            };
+            self.err_span_(start + BytePos(idx as u32 - 1),
+                           start + BytePos(idx as u32),
+                           errmsg);
         }
     }
 
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index fc47e4f0b18..94570140996 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -1,41 +1,17 @@
 use super::*;
 
-use crate::ast::CrateConfig;
 use crate::symbol::Symbol;
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::feature_gate::UnstableFeatures;
 use crate::parse::token;
-use crate::diagnostics::plugin::ErrorMap;
 use crate::with_default_globals;
 use std::io;
 use std::path::PathBuf;
-use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition};
-use rustc_data_structures::fx::{FxHashSet, FxHashMap};
-use rustc_data_structures::sync::{Lock, Once};
+use errors::{Handler, emitter::EmitterWriter};
+use syntax_pos::{BytePos, Span};
 
 fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
-    let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()),
-                                                        Some(sm.clone()),
-                                                        false,
-                                                        false,
-                                                        false);
-    ParseSess {
-        span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)),
-        unstable_features: UnstableFeatures::from_environment(),
-        config: CrateConfig::default(),
-        included_mod_stack: Lock::new(Vec::new()),
-        source_map: sm,
-        missing_fragment_specifiers: Lock::new(FxHashSet::default()),
-        raw_identifier_spans: Lock::new(Vec::new()),
-        registered_diagnostics: Lock::new(ErrorMap::new()),
-        buffered_lints: Lock::new(vec![]),
-        edition: Edition::from_session(),
-        ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
-        param_attr_spans: Lock::new(Vec::new()),
-        let_chains_spans: Lock::new(Vec::new()),
-        async_closure_spans: Lock::new(Vec::new()),
-        injected_crate_name: Once::new(),
-    }
+    let emitter = EmitterWriter::new(Box::new(io::sink()), Some(sm.clone()), false, false, false);
+    ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
 }
 
 // open a string reader for the given string
@@ -61,7 +37,7 @@ fn t1() {
         let tok1 = string_reader.next_token();
         let tok2 = Token::new(
             mk_ident("fn"),
-            Span::new(BytePos(21), BytePos(23), NO_EXPANSION),
+            Span::with_root_ctxt(BytePos(21), BytePos(23)),
         );
         assert_eq!(tok1.kind, tok2.kind);
         assert_eq!(tok1.span, tok2.span);
@@ -71,7 +47,7 @@ fn t1() {
         assert_eq!(string_reader.pos.clone(), BytePos(28));
         let tok4 = Token::new(
             mk_ident("main"),
-            Span::new(BytePos(24), BytePos(28), NO_EXPANSION),
+            Span::with_root_ctxt(BytePos(24), BytePos(28)),
         );
         assert_eq!(tok3.kind, tok4.kind);
         assert_eq!(tok3.span, tok4.span);
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index eaa736c6a35..525b4215aff 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -3,7 +3,7 @@
 
 use super::StringReader;
 use errors::{Applicability, DiagnosticBuilder};
-use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION, symbol::kw};
+use syntax_pos::{BytePos, Pos, Span, symbol::kw};
 use crate::parse::token;
 
 #[rustfmt::skip] // for line breaks
@@ -343,7 +343,7 @@ crate fn check_for_substitution<'a>(
         None => return None,
     };
 
-    let span = Span::new(pos, pos + Pos::from_usize(ch.len_utf8()), NO_EXPANSION);
+    let span = Span::with_root_ctxt(pos, pos + Pos::from_usize(ch.len_utf8()));
 
     let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) {
         Some((_ascii_char, ascii_name, token)) => (ascii_name, token),
@@ -362,10 +362,9 @@ crate fn check_for_substitution<'a>(
             ascii_char, ascii_name
         );
         err.span_suggestion(
-            Span::new(
+            Span::with_root_ctxt(
                 pos,
                 pos + Pos::from_usize('“'.len_utf8() + s.len() + '”'.len_utf8()),
-                NO_EXPANSION,
             ),
             &msg,
             format!("\"{}\"", s),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 80aa7a35266..b1f3612a839 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -16,6 +16,7 @@ use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic,
 use rustc_data_structures::sync::{Lrc, Lock, Once};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
 use syntax_pos::edition::Edition;
+use syntax_pos::hygiene::ExpnId;
 
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use std::borrow::Cow;
@@ -62,7 +63,11 @@ pub struct ParseSess {
     pub let_chains_spans: Lock<Vec<Span>>,
     // Places where `async || ..` exprs were used and should be feature gated.
     pub async_closure_spans: Lock<Vec<Span>>,
+    // Places where `yield e?` exprs were used and should be feature gated.
+    pub yield_spans: Lock<Vec<Span>>,
     pub injected_crate_name: Once<Symbol>,
+    // Places where or-patterns e.g. `Some(Foo | Bar)` were used and should be feature gated.
+    pub or_pattern_spans: Lock<Vec<Span>>,
 }
 
 impl ParseSess {
@@ -86,12 +91,14 @@ impl ParseSess {
             included_mod_stack: Lock::new(vec![]),
             source_map,
             buffered_lints: Lock::new(vec![]),
-            edition: Edition::from_session(),
+            edition: ExpnId::root().expn_data().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             param_attr_spans: Lock::new(Vec::new()),
             let_chains_spans: Lock::new(Vec::new()),
             async_closure_spans: Lock::new(Vec::new()),
+            yield_spans: Lock::new(Vec::new()),
             injected_crate_name: Once::new(),
+            or_pattern_spans: Lock::new(Vec::new()),
         }
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 2286e74e633..89725d8b339 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -13,7 +13,6 @@ mod generics;
 use crate::ast::{self, AttrStyle, Attribute, Arg, BindingMode, StrStyle, SelfKind};
 use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind};
 use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar};
-use crate::ext::hygiene::SyntaxContext;
 use crate::source_map::{self, respan};
 use crate::parse::{SeqSep, literal, token};
 use crate::parse::lexer::UnmatchedBrace;
@@ -1101,7 +1100,7 @@ impl<'a> Parser<'a> {
 
     crate fn process_potential_macro_variable(&mut self) {
         self.token = match self.token.kind {
-            token::Dollar if self.token.span.ctxt() != SyntaxContext::empty() &&
+            token::Dollar if self.token.span.from_expansion() &&
                              self.look_ahead(1, |t| t.is_ident()) => {
                 self.bump();
                 let name = match self.token.kind {
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index f4b6a926734..ccc6bd15067 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -997,6 +997,9 @@ impl<'a> Parser<'a> {
                     } else {
                         ex = ExprKind::Yield(None);
                     }
+
+                    let span = lo.to(hi);
+                    self.sess.yield_spans.borrow_mut().push(span);
                 } else if self.eat_keyword(kw::Let) {
                     return self.parse_let_expr(attrs);
                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
diff --git a/src/libsyntax/parse/parser/module.rs b/src/libsyntax/parse/parser/module.rs
index 58a7ffba948..3f6f87b1c44 100644
--- a/src/libsyntax/parse/parser/module.rs
+++ b/src/libsyntax/parse/parser/module.rs
@@ -60,7 +60,7 @@ impl<'a> Parser<'a> {
                 // Record that we fetched the mod from an external file
                 if warn {
                     let attr = attr::mk_attr_outer(
-                        attr::mk_word_item(Ident::with_empty_ctxt(sym::warn_directory_ownership)));
+                        attr::mk_word_item(Ident::with_dummy_span(sym::warn_directory_ownership)));
                     attr::mark_known(&attr);
                     attrs.push(attr);
                 }
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index c3079d2da0c..fd458aec743 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -14,7 +14,10 @@ use errors::{Applicability, DiagnosticBuilder};
 
 impl<'a> Parser<'a> {
     /// Parses a pattern.
-    pub fn parse_pat(&mut self, expected: Option<&'static str>) -> PResult<'a, P<Pat>> {
+    pub fn parse_pat(
+        &mut self,
+        expected: Option<&'static str>
+    ) -> PResult<'a, P<Pat>> {
         self.parse_pat_with_range_pat(true, expected)
     }
 
@@ -97,6 +100,34 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
+    /// Parses a pattern, that may be a or-pattern (e.g. `Some(Foo | Bar)`).
+    fn parse_pat_with_or(&mut self, expected: Option<&'static str>) -> PResult<'a, P<Pat>> {
+        // Parse the first pattern.
+        let first_pat = self.parse_pat(expected)?;
+
+        // If the next token is not a `|`, this is not an or-pattern and
+        // we should exit here.
+        if !self.check(&token::BinOp(token::Or)) {
+            return Ok(first_pat)
+        }
+
+        let lo = first_pat.span;
+
+        let mut pats = vec![first_pat];
+
+        while self.eat(&token::BinOp(token::Or)) {
+            pats.push(self.parse_pat_with_range_pat(
+                true, expected
+            )?);
+        }
+
+        let or_pattern_span = lo.to(self.prev_span);
+
+        self.sess.or_pattern_spans.borrow_mut().push(or_pattern_span);
+
+        Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
+    }
+
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
     /// allowed).
     fn parse_pat_with_range_pat(
@@ -240,7 +271,9 @@ impl<'a> Parser<'a> {
 
     /// Parse a tuple or parenthesis pattern.
     fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
-        let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| p.parse_pat(None))?;
+        let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
+            p.parse_pat_with_or(None)
+        })?;
 
         // Here, `(pat,)` is a tuple pattern.
         // For backward compatibility, `(..)` is a tuple pattern as well.
@@ -483,7 +516,7 @@ impl<'a> Parser<'a> {
             err.span_label(self.token.span, msg);
             return Err(err);
         }
-        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat(None))?;
+        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None))?;
         Ok(PatKind::TupleStruct(path, fields))
     }
 
@@ -627,7 +660,7 @@ impl<'a> Parser<'a> {
             // Parsing a pattern of the form "fieldname: pat"
             let fieldname = self.parse_field_name()?;
             self.bump();
-            let pat = self.parse_pat(None)?;
+            let pat = self.parse_pat_with_or(None)?;
             hi = pat.span;
             (pat, fieldname, false)
         } else {
diff --git a/src/libsyntax/parse/tests.rs b/src/libsyntax/parse/tests.rs
index 9edc83a3594..6a789ef99d6 100644
--- a/src/libsyntax/parse/tests.rs
+++ b/src/libsyntax/parse/tests.rs
@@ -12,7 +12,7 @@ use crate::symbol::{kw, sym};
 use crate::tests::{matches_codepattern, string_to_stream, with_error_checking_parse};
 use crate::tokenstream::{DelimSpan, TokenTree, TokenStream};
 use crate::with_default_globals;
-use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION};
+use syntax_pos::{Span, BytePos, Pos};
 
 use std::path::PathBuf;
 
@@ -27,7 +27,7 @@ fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess)
 
 // produce a syntax_pos::span
 fn sp(a: u32, b: u32) -> Span {
-    Span::new(BytePos(a), BytePos(b), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(a), BytePos(b))
 }
 
 /// Parse a string, return an expr
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 5955b913842..4dc00af4860 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -123,13 +123,13 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
         // of the feature gate, so we fake them up here.
 
         // #![feature(prelude_import)]
-        let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import));
-        let list = attr::mk_list_item(ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
+        let pi_nested = attr::mk_nested_word_item(ast::Ident::with_dummy_span(sym::prelude_import));
+        let list = attr::mk_list_item(ast::Ident::with_dummy_span(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
         // #![no_std]
-        let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std));
+        let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
         let fake_attr = attr::mk_attr_inner(no_std_meta);
         s.print_attribute(&fake_attr);
     }
@@ -436,18 +436,30 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
     fn print_ident(&mut self, ident: ast::Ident);
     fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool);
 
-    fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F)
+    fn strsep<T, F>(&mut self, sep: &'static str, space_before: bool,
+                    b: Breaks, elts: &[T], mut op: F)
         where F: FnMut(&mut Self, &T),
     {
         self.rbox(0, b);
-        let mut first = true;
-        for elt in elts {
-            if first { first = false; } else { self.word_space(","); }
-            op(self, elt);
+        if let Some((first, rest)) = elts.split_first() {
+            op(self, first);
+            for elt in rest {
+                if space_before {
+                    self.space();
+                }
+                self.word_space(sep);
+                op(self, elt);
+            }
         }
         self.end();
     }
 
+    fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], op: F)
+        where F: FnMut(&mut Self, &T),
+    {
+        self.strsep(",", false, b, elts, op)
+    }
+
     fn maybe_print_comment(&mut self, pos: BytePos) {
         while let Some(ref cmnt) = self.next_comment() {
             if cmnt.pos < pos {
@@ -2353,6 +2365,9 @@ impl<'a> State<'a> {
                 self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p));
                 self.pclose();
             }
+            PatKind::Or(ref pats) => {
+                self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(p));
+            }
             PatKind::Path(None, ref path) => {
                 self.print_path(path, true, 0);
             }
@@ -2429,16 +2444,7 @@ impl<'a> State<'a> {
     }
 
     fn print_pats(&mut self, pats: &[P<ast::Pat>]) {
-        let mut first = true;
-        for p in pats {
-            if first {
-                first = false;
-            } else {
-                self.s.space();
-                self.word_space("|");
-            }
-            self.print_pat(p);
-        }
+        self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
     }
 
     fn print_arm(&mut self, arm: &ast::Arm) {
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 74cab00d3c1..7190cfd72a9 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -8,7 +8,7 @@
 //! information, source code snippets, etc.
 
 pub use syntax_pos::*;
-pub use syntax_pos::hygiene::{ExpnKind, ExpnInfo};
+pub use syntax_pos::hygiene::{ExpnKind, ExpnData};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::StableHasher;
@@ -29,14 +29,15 @@ mod tests;
 
 /// Returns the span itself if it doesn't come from a macro expansion,
 /// otherwise return the call site span up to the `enclosing_sp` by
-/// following the `expn_info` chain.
+/// following the `expn_data` chain.
 pub fn original_sp(sp: Span, enclosing_sp: Span) -> Span {
-    let call_site1 = sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
-    let call_site2 = enclosing_sp.ctxt().outer_expn_info().map(|ei| ei.call_site);
-    match (call_site1, call_site2) {
-        (None, _) => sp,
-        (Some(call_site1), Some(call_site2)) if call_site1 == call_site2 => sp,
-        (Some(call_site1), _) => original_sp(call_site1, enclosing_sp),
+    let expn_data1 = sp.ctxt().outer_expn_data();
+    let expn_data2 = enclosing_sp.ctxt().outer_expn_data();
+    if expn_data1.is_root() ||
+       !expn_data2.is_root() && expn_data1.call_site == expn_data2.call_site {
+        sp
+    } else {
+        original_sp(expn_data1.call_site, enclosing_sp)
     }
 }
 
@@ -170,6 +171,26 @@ impl SourceMap {
         Ok(self.new_source_file(filename, src))
     }
 
+    /// Loads source file as a binary blob.
+    ///
+    /// Unlike `load_file`, guarantees that no normalization like BOM-removal
+    /// takes place.
+    pub fn load_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
+        // Ideally, this should use `self.file_loader`, but it can't
+        // deal with binary files yet.
+        let bytes = fs::read(path)?;
+
+        // We need to add file to the `SourceMap`, so that it is present
+        // in dep-info. There's also an edge case that file might be both
+        // loaded as a binary via `include_bytes!` and as proper `SourceFile`
+        // via `mod`, so we try to use real file contents and not just an
+        // empty string.
+        let text = std::str::from_utf8(&bytes).unwrap_or("")
+            .to_string();
+        self.new_source_file(path.to_owned().into(), text);
+        Ok(bytes)
+    }
+
     pub fn files(&self) -> MappedLockGuard<'_, Vec<Lrc<SourceFile>>> {
         LockGuard::map(self.files.borrow(), |files| &mut files.source_files)
     }
diff --git a/src/libsyntax/source_map/tests.rs b/src/libsyntax/source_map/tests.rs
index 427e86b56e1..c7b8332c53e 100644
--- a/src/libsyntax/source_map/tests.rs
+++ b/src/libsyntax/source_map/tests.rs
@@ -91,7 +91,7 @@ fn t6() {
 fn t7() {
     // Test span_to_lines for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let file_lines = sm.span_to_lines(span).unwrap();
 
     assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into());
@@ -107,7 +107,7 @@ fn span_from_selection(input: &str, selection: &str) -> Span {
     assert_eq!(input.len(), selection.len());
     let left_index = selection.find('~').unwrap() as u32;
     let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
-    Span::new(BytePos(left_index), BytePos(right_index + 1), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1))
 }
 
 /// Tests span_to_snippet and span_to_lines for a span converting 3
@@ -137,7 +137,7 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() {
 fn t8() {
     // Test span_to_snippet for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let snippet = sm.span_to_snippet(span);
 
     assert_eq!(snippet, Ok("second line".to_string()));
@@ -147,7 +147,7 @@ fn t8() {
 fn t9() {
     // Test span_to_str for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let sstr =  sm.span_to_string(span);
 
     assert_eq!(sstr, "blork.rs:2:1: 2:12");
@@ -198,10 +198,9 @@ impl SourceMapExtension for SourceMap {
             let lo = hi + offset;
             hi = lo + substring.len();
             if i == n {
-                let span = Span::new(
+                let span = Span::with_root_ctxt(
                     BytePos(lo as u32 + file.start_pos.0),
                     BytePos(hi as u32 + file.start_pos.0),
-                    NO_EXPANSION,
                 );
                 assert_eq!(&self.span_to_snippet(span).unwrap()[..],
                         substring);
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index cff034fdeb1..4c0e1e3704d 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -9,7 +9,7 @@ use crate::with_default_globals;
 use errors::emitter::EmitterWriter;
 use errors::Handler;
 use rustc_data_structures::sync::Lrc;
-use syntax_pos::{BytePos, NO_EXPANSION, Span, MultiSpan};
+use syntax_pos::{BytePos, Span, MultiSpan};
 
 use std::io;
 use std::io::prelude::*;
@@ -169,7 +169,7 @@ fn make_span(file_text: &str, start: &Position, end: &Position) -> Span {
     let start = make_pos(file_text, start);
     let end = make_pos(file_text, end) + end.string.len(); // just after matching thing ends
     assert!(start <= end);
-    Span::new(BytePos(start as u32), BytePos(end as u32), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(start as u32), BytePos(end as u32))
 }
 
 fn make_pos(file_text: &str, pos: &Position) -> usize {
diff --git a/src/libsyntax/tokenstream/tests.rs b/src/libsyntax/tokenstream/tests.rs
index 72e22a49876..5017e5f5424 100644
--- a/src/libsyntax/tokenstream/tests.rs
+++ b/src/libsyntax/tokenstream/tests.rs
@@ -3,14 +3,14 @@ use super::*;
 use crate::ast::Name;
 use crate::with_default_globals;
 use crate::tests::string_to_stream;
-use syntax_pos::{Span, BytePos, NO_EXPANSION};
+use syntax_pos::{Span, BytePos};
 
 fn string_to_ts(string: &str) -> TokenStream {
     string_to_stream(string.to_owned())
 }
 
 fn sp(a: u32, b: u32) -> Span {
-    Span::new(BytePos(a), BytePos(b), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(a), BytePos(b))
 }
 
 #[test]
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 6648347d4ae..91b92d84a81 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -447,9 +447,6 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
                 visitor.visit_pat(&field.pat)
             }
         }
-        PatKind::Tuple(ref elems) => {
-            walk_list!(visitor, visit_pat, elems);
-        }
         PatKind::Box(ref subpattern) |
         PatKind::Ref(ref subpattern, _) |
         PatKind::Paren(ref subpattern) => {
@@ -465,7 +462,9 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
             visitor.visit_expr(upper_bound);
         }
         PatKind::Wild | PatKind::Rest => {},
-        PatKind::Slice(ref elems) => {
+        PatKind::Tuple(ref elems)
+        | PatKind::Slice(ref elems)
+        | PatKind::Or(ref elems) => {
             walk_list!(visitor, visit_pat, elems);
         }
         PatKind::Mac(ref mac) => visitor.visit_mac(mac),
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 950166f9260..644a44f1989 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -63,7 +63,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
     MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprKind::InlineAsm(P(inline_asm)),
-        span: sp,
+        span: sp.with_ctxt(cx.backtrace()),
         attrs: ThinVec::new(),
     }))
 }
@@ -277,6 +277,5 @@ fn parse_inline_asm<'a>(
         volatile,
         alignstack,
         dialect,
-        ctxt: cx.backtrace(),
     }))
 }
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index d80da566185..d030ea4a56e 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -35,7 +35,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
             match annitem.node {
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
-                    let container_id = cx.current_expansion.id.parent();
+                    let container_id = cx.current_expansion.id.expn_data().parent;
                     if cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
                         !params.iter().any(|param| match param.kind {
                             ast::GenericParamKind::Type { .. } => true,
@@ -129,7 +129,7 @@ fn cs_clone_shallow(name: &str,
     if is_union {
         // let _: AssertParamIsCopy<Self>;
         let self_ty =
-            cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_empty_ctxt(kw::SelfUpper)));
+            cx.ty_path(cx.path_ident(trait_span, ast::Ident::with_dummy_span(kw::SelfUpper)));
         assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy");
     } else {
         match *substr.fields {
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 5d7c4a84389..54027c600b4 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -13,7 +13,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
                           mitem: &MetaItem,
                           item: &Annotatable,
                           push: &mut dyn FnMut(Annotatable)) {
-    cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::EQ);
+    cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::EQ);
 
     let inline = cx.meta_word(span, sym::inline);
     let hidden = cx.meta_list_item_word(span, sym::hidden);
diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs
index 885cfee3565..55687c3175b 100644
--- a/src/libsyntax_ext/deriving/cmp/ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/ord.rs
@@ -43,17 +43,18 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>,
 }
 
 
-pub fn ordering_collapsed(cx: &mut ExtCtxt<'_>,
-                          span: Span,
-                          self_arg_tags: &[ast::Ident])
-                          -> P<ast::Expr> {
+pub fn ordering_collapsed(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    self_arg_tags: &[ast::Ident],
+) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
-    cx.expr_method_call(span, lft, cx.ident_of("cmp"), vec![rgt])
+    cx.expr_method_call(span, lft, ast::Ident::new(sym::cmp, span), vec![rgt])
 }
 
 pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let test_id = cx.ident_of("cmp").gensym();
+    let test_id = ast::Ident::new(sym::cmp, span);
     let equals_path = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
 
     let cmp_path = cx.std_path(&[sym::cmp, sym::Ord, sym::cmp]);
@@ -75,34 +76,34 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<
             // as the outermost one, and the last as the innermost.
             false,
             |cx, span, old, self_f, other_fs| {
-        // match new {
-        //     ::std::cmp::Ordering::Equal => old,
-        //     cmp => cmp
-        // }
+                // match new {
+                //     ::std::cmp::Ordering::Equal => old,
+                //     cmp => cmp
+                // }
 
-        let new = {
-            let other_f = match other_fs {
-                [o_f] => o_f,
-                _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
-            };
+                let new = {
+                    let other_f = match other_fs {
+                        [o_f] => o_f,
+                        _ => cx.span_bug(span, "not exactly 2 arguments in `derive(Ord)`"),
+                    };
 
-            let args = vec![
-                    cx.expr_addr_of(span, self_f),
-                    cx.expr_addr_of(span, other_f.clone()),
-                ];
+                    let args = vec![
+                            cx.expr_addr_of(span, self_f),
+                            cx.expr_addr_of(span, other_f.clone()),
+                        ];
 
-            cx.expr_call_global(span, cmp_path.clone(), args)
-        };
+                    cx.expr_call_global(span, cmp_path.clone(), args)
+                };
 
-        let eq_arm = cx.arm(span,
-                            vec![cx.pat_path(span, equals_path.clone())],
-                            old);
-        let neq_arm = cx.arm(span,
-                             vec![cx.pat_ident(span, test_id)],
-                             cx.expr_ident(span, test_id));
+                let eq_arm = cx.arm(span,
+                                    vec![cx.pat_path(span, equals_path.clone())],
+                                    old);
+                let neq_arm = cx.arm(span,
+                                     vec![cx.pat_ident(span, test_id)],
+                                     cx.expr_ident(span, test_id));
 
-        cx.expr_match(span, new, vec![eq_arm, neq_arm])
-    },
+                cx.expr_match(span, new, vec![eq_arm, neq_arm])
+            },
             cx.expr_path(equals_path.clone()),
             Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
         if self_args.len() != 2 {
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 7d7c4ae22a8..91e1e80e4fb 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -13,7 +13,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>,
                                   mitem: &MetaItem,
                                   item: &Annotatable,
                                   push: &mut dyn FnMut(Annotatable)) {
-    cx.resolver.add_derives(cx.current_expansion.id.parent(), SpecialDerives::PARTIAL_EQ);
+    cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::PARTIAL_EQ);
 
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 0ec30f5924f..740b92a9b79 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -94,11 +94,12 @@ pub enum OrderingOp {
     GeOp,
 }
 
-pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
-                               span: Span,
-                               op: OrderingOp,
-                               self_arg_tags: &[ast::Ident])
-                               -> P<ast::Expr> {
+pub fn some_ordering_collapsed(
+    cx: &mut ExtCtxt<'_>,
+    span: Span,
+    op: OrderingOp,
+    self_arg_tags: &[ast::Ident],
+) -> P<ast::Expr> {
     let lft = cx.expr_ident(span, self_arg_tags[0]);
     let rgt = cx.expr_addr_of(span, cx.expr_ident(span, self_arg_tags[1]));
     let op_str = match op {
@@ -108,11 +109,11 @@ pub fn some_ordering_collapsed(cx: &mut ExtCtxt<'_>,
         GtOp => "gt",
         GeOp => "ge",
     };
-    cx.expr_method_call(span, lft, cx.ident_of(op_str), vec![rgt])
+    cx.expr_method_call(span, lft, ast::Ident::from_str_and_span(op_str, span), vec![rgt])
 }
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
-    let test_id = cx.ident_of("cmp").gensym();
+    let test_id = ast::Ident::new(sym::cmp, span);
     let ordering = cx.path_global(span, cx.std_path(&[sym::cmp, sym::Ordering, sym::Equal]));
     let ordering_expr = cx.expr_path(ordering.clone());
     let equals_expr = cx.expr_some(span, ordering_expr);
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 15e93f2843a..44153541048 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
     // We want to make sure we have the ctxt set so that we can use unstable methods
     let span = span.with_ctxt(cx.backtrace());
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
-    let builder = Ident::from_str("debug_trait_builder").gensym();
+    let builder = Ident::from_str_and_span("debug_trait_builder", span);
     let builder_expr = cx.expr_ident(span, builder.clone());
 
     let fmt = substr.nonself_args[0].clone();
@@ -73,7 +73,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
             // tuple struct/"normal" variant
             let expr =
                 cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
-            stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
+            stmts.push(cx.stmt_let(span, true, builder, expr));
 
             for field in fields {
                 // Use double indirection to make sure this works for unsized types
@@ -82,7 +82,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
 
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::with_empty_ctxt(sym::field),
+                                                Ident::new(sym::field, span),
                                                 vec![field]);
 
                 // Use `let _ = expr;` to avoid triggering the
@@ -106,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
                 let field = cx.expr_addr_of(field.span, field);
                 let expr = cx.expr_method_call(span,
                                                 builder_expr.clone(),
-                                                Ident::with_empty_ctxt(sym::field),
+                                                Ident::new(sym::field, span),
                                                 vec![name, field]);
                 stmts.push(stmt_let_undescore(cx, span, expr));
             }
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index 293c5a1e7e7..9b6f8518de0 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -1,6 +1,6 @@
-//! The compiler code necessary for `#[derive(Decodable)]`. See encodable.rs for more.
+//! The compiler code necessary for `#[derive(RustcDecodable)]`. See encodable.rs for more.
 
-use crate::deriving::{self, pathvec_std};
+use crate::deriving::pathvec_std;
 use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
@@ -17,7 +17,7 @@ pub fn expand_deriving_rustc_decodable(cx: &mut ExtCtxt<'_>,
                                        item: &Annotatable,
                                        push: &mut dyn FnMut(Annotatable)) {
     let krate = "rustc_serialize";
-    let typaram = &*deriving::hygienic_type_parameter(item, "__D");
+    let typaram = "__D";
 
     let trait_def = TraitDef {
         span,
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 52e74a7c57e..8b18fb25e90 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -1,11 +1,12 @@
-//! The compiler code necessary to implement the `#[derive(Encodable)]`
-//! (and `Decodable`, in `decodable.rs`) extension. The idea here is that
-//! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
+//! The compiler code necessary to implement the `#[derive(RustcEncodable)]`
+//! (and `RustcDecodable`, in `decodable.rs`) extension. The idea here is that
+//! type-defining items may be tagged with
+//! `#[derive(RustcEncodable, RustcDecodable)]`.
 //!
 //! For example, a type like:
 //!
 //! ```
-//! #[derive(Encodable, Decodable)]
+//! #[derive(RustcEncodable, RustcDecodable)]
 //! struct Node { id: usize }
 //! ```
 //!
@@ -40,15 +41,17 @@
 //! references other non-built-in types. A type definition like:
 //!
 //! ```
-//! # #[derive(Encodable, Decodable)] struct Span;
-//! #[derive(Encodable, Decodable)]
+//! # #[derive(RustcEncodable, RustcDecodable)]
+//! # struct Span;
+//! #[derive(RustcEncodable, RustcDecodable)]
 //! struct Spanned<T> { node: T, span: Span }
 //! ```
 //!
 //! would yield functions like:
 //!
 //! ```
-//! # #[derive(Encodable, Decodable)] struct Span;
+//! # #[derive(RustcEncodable, RustcDecodable)]
+//! # struct Span;
 //! # struct Spanned<T> { node: T, span: Span }
 //! impl<
 //!     S: Encoder<E>,
@@ -82,7 +85,7 @@
 //! }
 //! ```
 
-use crate::deriving::{self, pathvec_std};
+use crate::deriving::pathvec_std;
 use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
@@ -98,7 +101,7 @@ pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt<'_>,
                                        item: &Annotatable,
                                        push: &mut dyn FnMut(Annotatable)) {
     let krate = "rustc_serialize";
-    let typaram = &*deriving::hygienic_type_parameter(item, "__S");
+    let typaram = "__S";
 
     let trait_def = TraitDef {
         span,
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index d080dc37a92..1475bac0688 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -425,7 +425,7 @@ impl<'a> TraitDef<'a> {
                         return;
                     }
                 };
-                let container_id = cx.current_expansion.id.parent();
+                let container_id = cx.current_expansion.id.expn_data().parent;
                 let is_always_copy =
                     cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
                     has_no_type_params;
@@ -890,7 +890,7 @@ impl<'a> MethodDef<'a> {
 
         for (ty, name) in self.args.iter() {
             let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
-            let ident = cx.ident_of(name).gensym();
+            let ident = ast::Ident::from_str_and_span(name, trait_.span);
             arg_tys.push((ident, ast_ty));
 
             let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -928,7 +928,7 @@ impl<'a> MethodDef<'a> {
 
         let args = {
             let self_args = explicit_self.map(|explicit_self| {
-                let ident = Ident::with_empty_ctxt(kw::SelfLower).with_span_pos(trait_.span);
+                let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(trait_.span);
                 ast::Arg::from_self(ThinVec::default(), explicit_self, ident)
             });
             let nonself_args = arg_types.into_iter()
@@ -1210,7 +1210,7 @@ impl<'a> MethodDef<'a> {
         let vi_idents = self_arg_names.iter()
             .map(|name| {
                 let vi_suffix = format!("{}_vi", &name[..]);
-                cx.ident_of(&vi_suffix[..]).gensym()
+                ast::Ident::from_str_and_span(&vi_suffix[..], trait_.span)
             })
             .collect::<Vec<ast::Ident>>();
 
@@ -1387,7 +1387,10 @@ impl<'a> MethodDef<'a> {
                 let variant_value =
                     deriving::call_intrinsic(cx, sp, "discriminant_value", vec![self_addr]);
 
-                let target_ty = cx.ty_ident(sp, cx.ident_of(target_type_name));
+                let target_ty = cx.ty_ident(
+                    sp,
+                    ast::Ident::from_str_and_span(target_type_name, sp),
+                );
                 let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
                 let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
                 index_let_stmts.push(let_stmt);
@@ -1588,7 +1591,7 @@ impl<'a> TraitDef<'a> {
         let mut ident_exprs = Vec::new();
         for (i, struct_field) in struct_def.fields().iter().enumerate() {
             let sp = struct_field.span.with_ctxt(self.span.ctxt());
-            let ident = cx.ident_of(&format!("{}_{}", prefix, i)).gensym();
+            let ident = ast::Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
             paths.push(ident.with_span_pos(sp));
             let val = cx.expr_path(cx.path_ident(sp, ident));
             let val = if use_temporaries {
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 399829eaefd..7fcf036fc81 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -72,7 +72,7 @@ impl<'a> Path<'a> {
                    self_ty: Ident,
                    self_generics: &Generics)
                    -> ast::Path {
-        let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
+        let mut idents = self.path.iter().map(|s| Ident::from_str_and_span(*s, span)).collect();
         let lt = mk_lifetimes(cx, span, &self.lifetime);
         let tys: Vec<P<ast::Ty>> =
             self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
@@ -209,7 +209,7 @@ fn mk_ty_param(cx: &ExtCtxt<'_>,
             cx.trait_bound(path)
         })
         .collect();
-    cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
+    cx.typaram(span, ast::Ident::from_str_and_span(name, span), attrs.to_owned(), bounds, None)
 }
 
 fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs
index 9787722e81d..2fc594abd70 100644
--- a/src/libsyntax_ext/deriving/hash.rs
+++ b/src/libsyntax_ext/deriving/hash.rs
@@ -16,7 +16,7 @@ pub fn expand_deriving_hash(cx: &mut ExtCtxt<'_>,
 
     let path = Path::new_(pathvec_std!(cx, hash::Hash), None, vec![], PathKind::Std);
 
-    let typaram = &*deriving::hygienic_type_parameter(item, "__H");
+    let typaram = "__H";
 
     let arg = Path::new_local(typaram);
     let hash_trait_def = TraitDef {
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index 8cd2853e538..da68eea0c50 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -54,33 +54,6 @@ impl MultiItemModifier for BuiltinDerive {
     }
 }
 
-/// Construct a name for the inner type parameter that can't collide with any type parameters of
-/// the item. This is achieved by starting with a base and then concatenating the names of all
-/// other type parameters.
-// FIXME(aburka): use real hygiene when that becomes possible
-fn hygienic_type_parameter(item: &Annotatable, base: &str) -> String {
-    let mut typaram = String::from(base);
-    if let Annotatable::Item(ref item) = *item {
-        match item.node {
-            ast::ItemKind::Struct(_, ast::Generics { ref params, .. }) |
-            ast::ItemKind::Enum(_, ast::Generics { ref params, .. }) => {
-                for param in params {
-                    match param.kind {
-                        ast::GenericParamKind::Type { .. } => {
-                            typaram.push_str(&param.ident.as_str());
-                        }
-                        _ => {}
-                    }
-                }
-            }
-
-            _ => {}
-        }
-    }
-
-    typaram
-}
-
 /// Constructs an expression that calls an intrinsic
 fn call_intrinsic(cx: &ExtCtxt<'_>,
                   span: Span,
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 442f27c7821..9834130fa23 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -23,13 +23,13 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
     let sp = sp.apply_mark(cx.current_expansion.id);
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
-            let lt = cx.lifetime(sp, Ident::with_empty_ctxt(kw::StaticLifetime));
+            let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
             cx.expr_path(cx.path_all(sp,
                                      true,
                                      cx.std_path(&[sym::option, sym::Option, sym::None]),
                                      vec![GenericArg::Type(cx.ty_rptr(sp,
                                                      cx.ty_ident(sp,
-                                                                 Ident::with_empty_ctxt(sym::str)),
+                                                                 Ident::with_dummy_span(sym::str)),
                                                      Some(lt),
                                                      ast::Mutability::Immutable))],
                                      vec![]))
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index f788b513804..d2121abe3b4 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -29,7 +29,7 @@ pub fn expand(
     };
 
     // Generate a bunch of new items using the AllocFnFactory
-    let span = item.span.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id));
+    let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
     let f = AllocFnFactory {
         span,
         kind: AllocatorKind::Global,
@@ -44,7 +44,7 @@ pub fn expand(
     let const_ty = ecx.ty(span, TyKind::Tup(Vec::new()));
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item =
-        ecx.item_const(span, Ident::with_empty_ctxt(kw::Underscore), const_ty, const_body);
+        ecx.item_const(span, Ident::with_dummy_span(kw::Underscore), const_ty, const_body);
 
     // Return the original item and the new methods.
     vec![Annotatable::Item(item), Annotatable::Item(const_item)]
@@ -120,7 +120,7 @@ impl AllocFnFactory<'_, '_> {
     ) -> P<Expr> {
         match *ty {
             AllocatorTy::Layout => {
-                let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize));
+                let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize));
                 let ty_usize = self.cx.ty_path(usize);
                 let size = ident();
                 let align = ident();
@@ -178,12 +178,12 @@ impl AllocFnFactory<'_, '_> {
     }
 
     fn usize(&self) -> P<Ty> {
-        let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize));
+        let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize));
         self.cx.ty_path(usize)
     }
 
     fn ptr_u8(&self) -> P<Ty> {
-        let u8 = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::u8));
+        let u8 = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::u8));
         let ty_u8 = self.cx.ty_path(u8);
         self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable)
     }
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 112192fac5d..73ebeaec454 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 id: ast::DUMMY_NODE_ID,
                 node: ast::ItemKind::GlobalAsm(P(global_asm)),
                 vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                span: sp,
+                span: sp.with_ctxt(cx.backtrace()),
                 tokens: None,
             })])
         }
@@ -61,8 +61,5 @@ fn parse_global_asm<'a>(
         None => return Ok(None),
     };
 
-    Ok(Some(ast::GlobalAsm {
-        asm,
-        ctxt: cx.backtrace(),
-    }))
+    Ok(Some(ast::GlobalAsm { asm }))
 }
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 0f3f5c0cd0e..4add2261c6c 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -42,7 +42,7 @@ pub mod test_harness;
 
 pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, edition: Edition) {
     let mut register = |name, kind| resolver.register_builtin_macro(
-        Ident::with_empty_ctxt(name), SyntaxExtension {
+        Ident::with_dummy_span(name), SyntaxExtension {
             is_builtin: true, ..SyntaxExtension::default(kind, edition)
         },
     );
@@ -57,7 +57,6 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
     }
 
     register_bang! {
-        __rust_unstable_column: source_util::expand_column,
         asm: asm::expand_asm,
         assert: assert::expand_assert,
         cfg: cfg::expand_cfg,
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index a725f5e46ad..dbfd8fe98f3 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -11,7 +11,7 @@ use syntax::source_map::respan;
 use syntax::symbol::sym;
 use syntax::tokenstream::*;
 use syntax_pos::{Span, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind};
+use syntax_pos::hygiene::{ExpnData, ExpnKind, MacroKind};
 
 use std::mem;
 
@@ -43,12 +43,12 @@ pub fn inject(
 ) {
     if !named_exts.is_empty() {
         let mut extra_items = Vec::new();
-        let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+        let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
             ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition,
             [sym::rustc_attrs][..].into(),
         ));
         for (name, ext) in named_exts {
-            resolver.register_builtin_macro(Ident::with_empty_ctxt(name), ext);
+            resolver.register_builtin_macro(Ident::with_dummy_span(name), ext);
             extra_items.push(plugin_macro_def(name, span));
         }
         // The `macro_rules` items must be inserted before any other items.
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 70325539f30..e772eaf8349 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -3,10 +3,9 @@ use std::mem;
 use smallvec::smallvec;
 use syntax::ast::{self, Ident};
 use syntax::attr;
-use syntax::source_map::{ExpnInfo, ExpnKind, respan};
+use syntax::source_map::{ExpnData, ExpnKind, respan};
 use syntax::ext::base::{ExtCtxt, MacroKind};
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
-use syntax::ext::hygiene::ExpnId;
 use syntax::ext::proc_macro::is_proc_macro_attr;
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
@@ -328,7 +327,7 @@ fn mk_decls(
     custom_attrs: &[ProcMacroDef],
     custom_macros: &[ProcMacroDef],
 ) -> P<ast::Item> {
-    let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+    let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition,
         [sym::rustc_attrs, sym::proc_macro_internals][..].into(),
     ));
@@ -337,7 +336,7 @@ fn mk_decls(
     let doc = cx.meta_list(span, sym::doc, vec![hidden]);
     let doc_hidden = cx.attribute(doc);
 
-    let proc_macro = Ident::with_empty_ctxt(sym::proc_macro);
+    let proc_macro = Ident::with_dummy_span(sym::proc_macro);
     let krate = cx.item(span,
                         proc_macro,
                         Vec::new(),
@@ -349,7 +348,7 @@ fn mk_decls(
     let custom_derive = Ident::from_str("custom_derive");
     let attr = Ident::from_str("attr");
     let bang = Ident::from_str("bang");
-    let crate_kw = Ident::with_empty_ctxt(kw::Crate);
+    let crate_kw = Ident::with_dummy_span(kw::Crate);
 
     let decls = {
         let local_path = |sp: Span, name| {
diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs
index cbc01b48afd..e008ed710e4 100644
--- a/src/libsyntax_ext/source_util.rs
+++ b/src/libsyntax_ext/source_util.rs
@@ -9,8 +9,6 @@ use syntax::tokenstream;
 use smallvec::SmallVec;
 use syntax_pos::{self, Pos, Span};
 
-use std::fs;
-use std::io::ErrorKind;
 use rustc_data_structures::sync::Lrc;
 
 // These macros all relate to the file system; they either return
@@ -114,20 +112,17 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To
         None => return DummyResult::any(sp)
     };
     let file = cx.resolve_path(file, sp);
-    match fs::read_to_string(&file) {
-        Ok(src) => {
-            let interned_src = Symbol::intern(&src);
-
-            // Add this input file to the code map to make it available as
-            // dependency information
-            cx.source_map().new_source_file(file.into(), src);
-
-            base::MacEager::expr(cx.expr_str(sp, interned_src))
+    match cx.source_map().load_binary_file(&file) {
+        Ok(bytes) => match std::str::from_utf8(&bytes) {
+            Ok(src) => {
+                let interned_src = Symbol::intern(&src);
+                base::MacEager::expr(cx.expr_str(sp, interned_src))
+            }
+            Err(_) => {
+                cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
+                DummyResult::any(sp)
+            }
         },
-        Err(ref e) if e.kind() == ErrorKind::InvalidData => {
-            cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
-            DummyResult::any(sp)
-        }
         Err(e) => {
             cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
             DummyResult::any(sp)
@@ -142,18 +137,8 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::
         None => return DummyResult::any(sp)
     };
     let file = cx.resolve_path(file, sp);
-    match fs::read(&file) {
+    match cx.source_map().load_binary_file(&file) {
         Ok(bytes) => {
-            // Add the contents to the source map if it contains UTF-8.
-            let (contents, bytes) = match String::from_utf8(bytes) {
-                Ok(s) => {
-                    let bytes = s.as_bytes().to_owned();
-                    (s, bytes)
-                },
-                Err(e) => (String::new(), e.into_bytes()),
-            };
-            cx.source_map().new_source_file(file.into(), contents);
-
             base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
         },
         Err(e) => {
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index 68b13bdd171..8ca376341fc 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -1,8 +1,8 @@
 use syntax::{ast, attr};
 use syntax::edition::Edition;
-use syntax::ext::hygiene::{ExpnId, MacroKind};
+use syntax::ext::hygiene::MacroKind;
 use syntax::ptr::P;
-use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan};
+use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned, respan};
 use syntax::symbol::{Ident, Symbol, kw, sym};
 use syntax_pos::DUMMY_SP;
 
@@ -32,7 +32,7 @@ pub fn inject(
         // HACK(eddyb) gensym the injected crates on the Rust 2018 edition,
         // so they don't accidentally interfere with the new import paths.
         let orig_name_sym = Symbol::intern(orig_name_str);
-        let orig_name_ident = Ident::with_empty_ctxt(orig_name_sym);
+        let orig_name_ident = Ident::with_dummy_span(orig_name_sym);
         let (rename, orig_name) = if rust_2018 {
             (orig_name_ident.gensym(), Some(orig_name_sym))
         } else {
@@ -40,7 +40,7 @@ pub fn inject(
         };
         krate.module.items.insert(0, P(ast::Item {
             attrs: vec![attr::mk_attr_outer(
-                attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::macro_use))
+                attr::mk_word_item(ast::Ident::with_dummy_span(sym::macro_use))
             )],
             vis: dummy_spanned(ast::VisibilityKind::Inherited),
             node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)),
@@ -55,7 +55,7 @@ pub fn inject(
     // the prelude.
     let name = names[0];
 
-    let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+    let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition,
         [sym::prelude_import][..].into(),
     ));
@@ -66,7 +66,7 @@ pub fn inject(
         vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
         node: ast::ItemKind::Use(P(ast::UseTree {
             prefix: ast::Path {
-                segments: iter::once(ast::Ident::with_empty_ctxt(kw::PathRoot))
+                segments: iter::once(ast::Ident::with_dummy_span(kw::PathRoot))
                     .chain(
                         [name, "prelude", "v1"].iter().cloned()
                             .map(ast::Ident::from_str)
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 993ef257527..08582e714cc 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -29,7 +29,7 @@ pub fn expand_test_case(
 
     if !ecx.ecfg.should_test { return vec![]; }
 
-    let sp = attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(ecx.current_expansion.id));
+    let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
     let mut item = anno_item.expect_item();
     item = item.map(|mut item| {
         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
@@ -93,7 +93,7 @@ pub fn expand_test_or_bench(
         return vec![Annotatable::Item(item)];
     }
 
-    let ctxt = SyntaxContext::empty().apply_mark(cx.current_expansion.id);
+    let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id);
     let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt));
 
     // Gensym "test" so we can extern crate without conflicting with any local names
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 0267637e540..4a6ea0ebf85 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -5,14 +5,13 @@ use smallvec::{smallvec, SmallVec};
 use syntax::ast::{self, Ident};
 use syntax::attr;
 use syntax::entry::{self, EntryPointType};
-use syntax::ext::base::{ExtCtxt, Resolver};
+use syntax::ext::base::{ExtCtxt, MacroKind, Resolver};
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
-use syntax::ext::hygiene::{ExpnId, MacroKind};
 use syntax::feature_gate::Features;
 use syntax::mut_visit::{*, ExpectOne};
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
-use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned};
+use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned};
 use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::{Span, DUMMY_SP};
 
@@ -150,7 +149,7 @@ impl MutVisitor for EntryPointCleaner {
             EntryPointType::MainAttr |
             EntryPointType::Start =>
                 item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| {
-                    let allow_ident = Ident::with_empty_ctxt(sym::allow);
+                    let allow_ident = Ident::with_dummy_span(sym::allow);
                     let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code"));
                     let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
                     let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
@@ -191,7 +190,7 @@ fn mk_reexport_mod(cx: &mut TestCtxt<'_>,
                    tests: Vec<Ident>,
                    tested_submods: Vec<(Ident, Ident)>)
                    -> (P<ast::Item>, Ident) {
-    let super_ = Ident::with_empty_ctxt(kw::Super);
+    let super_ = Ident::with_dummy_span(kw::Super);
 
     let items = tests.into_iter().map(|r| {
         cx.ext_cx.item_use_simple(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
@@ -269,12 +268,12 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     //            #![main]
     //            test::test_main_static(&[..tests]);
     //        }
-    let sp = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+    let sp = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
         ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition,
         [sym::main, sym::test, sym::rustc_attrs][..].into(),
     ));
     let ecx = &cx.ext_cx;
-    let test_id = Ident::with_empty_ctxt(sym::test);
+    let test_id = Ident::with_dummy_span(sym::test);
 
     // test::test_main_static(...)
     let mut test_runner = cx.test_runner.clone().unwrap_or(
diff --git a/src/libsyntax_pos/edition.rs b/src/libsyntax_pos/edition.rs
index 20216568426..00cd00f2837 100644
--- a/src/libsyntax_pos/edition.rs
+++ b/src/libsyntax_pos/edition.rs
@@ -1,7 +1,6 @@
 use crate::symbol::{Symbol, sym};
 use std::fmt;
 use std::str::FromStr;
-use crate::GLOBALS;
 
 /// The edition of the compiler (RFC 2052)
 #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)]
@@ -39,10 +38,6 @@ impl fmt::Display for Edition {
 }
 
 impl Edition {
-    pub fn from_session() -> Edition {
-        GLOBALS.with(|globals| globals.edition)
-    }
-
     pub fn lint_name(&self) -> &'static str {
         match *self {
             Edition::Edition2015 => "rust_2015_compatibility",
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index f91a2291544..ebfb0764fa2 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -13,8 +13,8 @@
 //
 // This explains why `HygieneData`, `SyntaxContext` and `ExpnId` have interfaces
 // with a certain amount of redundancy in them. For example,
-// `SyntaxContext::outer_expn_info` combines `SyntaxContext::outer` and
-// `ExpnId::expn_info` so that two `HygieneData` accesses can be performed within
+// `SyntaxContext::outer_expn_data` combines `SyntaxContext::outer` and
+// `ExpnId::expn_data` so that two `HygieneData` accesses can be performed within
 // a single `HygieneData::with` call.
 //
 // It also explains why many functions appear in `HygieneData` and again in
@@ -56,16 +56,6 @@ struct SyntaxContextData {
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct ExpnId(u32);
 
-// FIXME: Find a way to merge this with `ExpnInfo`.
-#[derive(Debug)]
-struct InternalExpnData {
-    parent: ExpnId,
-    /// Each expansion should have an associated expansion info, but sometimes there's a delay
-    /// between creation of an expansion ID and obtaining its info (e.g. macros are collected
-    /// first and then resolved later), so we use an `Option` here.
-    expn_info: Option<ExpnInfo>,
-}
-
 /// A property of a macro expansion that determines how identifiers
 /// produced by that expansion are resolved.
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)]
@@ -86,8 +76,8 @@ pub enum Transparency {
 }
 
 impl ExpnId {
-    pub fn fresh(parent: ExpnId, expn_info: Option<ExpnInfo>) -> Self {
-        HygieneData::with(|data| data.fresh_expn(parent, expn_info))
+    pub fn fresh(expn_data: Option<ExpnData>) -> Self {
+        HygieneData::with(|data| data.fresh_expn(expn_data))
     }
 
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
@@ -107,21 +97,16 @@ impl ExpnId {
     }
 
     #[inline]
-    pub fn parent(self) -> ExpnId {
-        HygieneData::with(|data| data.parent_expn(self))
-    }
-
-    #[inline]
-    pub fn expn_info(self) -> Option<ExpnInfo> {
-        HygieneData::with(|data| data.expn_info(self).cloned())
+    pub fn expn_data(self) -> ExpnData {
+        HygieneData::with(|data| data.expn_data(self).clone())
     }
 
     #[inline]
-    pub fn set_expn_info(self, info: ExpnInfo) {
+    pub fn set_expn_data(self, expn_data: ExpnData) {
         HygieneData::with(|data| {
-            let old_info = &mut data.expn_data[self.0 as usize].expn_info;
-            assert!(old_info.is_none(), "expansion info is reset for an expansion ID");
-            *old_info = Some(info);
+            let old_expn_data = &mut data.expn_data[self.0 as usize];
+            assert!(old_expn_data.is_none(), "expansion data is reset for an expansion ID");
+            *old_expn_data = Some(expn_data);
         })
     }
 
@@ -139,12 +124,9 @@ impl ExpnId {
     #[inline]
     pub fn looks_like_proc_macro_derive(self) -> bool {
         HygieneData::with(|data| {
-            if data.default_transparency(self) == Transparency::Opaque {
-                if let Some(expn_info) = data.expn_info(self) {
-                    if let ExpnKind::Macro(MacroKind::Derive, _) = expn_info.kind {
-                        return true;
-                    }
-                }
+            let expn_data = data.expn_data(self);
+            if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind {
+                return expn_data.default_transparency == Transparency::Opaque;
             }
             false
         })
@@ -153,7 +135,10 @@ impl ExpnId {
 
 #[derive(Debug)]
 crate struct HygieneData {
-    expn_data: Vec<InternalExpnData>,
+    /// Each expansion should have an associated expansion data, but sometimes there's a delay
+    /// between creation of an expansion ID and obtaining its data (e.g. macros are collected
+    /// first and then resolved later), so we use an `Option` here.
+    expn_data: Vec<Option<ExpnData>>,
     syntax_context_data: Vec<SyntaxContextData>,
     syntax_context_map: FxHashMap<(SyntaxContext, ExpnId, Transparency), SyntaxContext>,
 }
@@ -161,10 +146,7 @@ crate struct HygieneData {
 impl HygieneData {
     crate fn new(edition: Edition) -> Self {
         HygieneData {
-            expn_data: vec![InternalExpnData {
-                parent: ExpnId::root(),
-                expn_info: Some(ExpnInfo::default(ExpnKind::Root, DUMMY_SP, edition)),
-            }],
+            expn_data: vec![Some(ExpnData::default(ExpnKind::Root, DUMMY_SP, edition))],
             syntax_context_data: vec![SyntaxContextData {
                 outer_expn: ExpnId::root(),
                 outer_transparency: Transparency::Opaque,
@@ -181,25 +163,14 @@ impl HygieneData {
         GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
     }
 
-    fn fresh_expn(&mut self, parent: ExpnId, expn_info: Option<ExpnInfo>) -> ExpnId {
-        self.expn_data.push(InternalExpnData { parent, expn_info });
+    fn fresh_expn(&mut self, expn_data: Option<ExpnData>) -> ExpnId {
+        self.expn_data.push(expn_data);
         ExpnId(self.expn_data.len() as u32 - 1)
     }
 
-    fn parent_expn(&self, expn_id: ExpnId) -> ExpnId {
-        self.expn_data[expn_id.0 as usize].parent
-    }
-
-    fn expn_info(&self, expn_id: ExpnId) -> Option<&ExpnInfo> {
-        if expn_id != ExpnId::root() {
-            Some(self.expn_data[expn_id.0 as usize].expn_info.as_ref()
-                     .expect("no expansion info for an expansion ID"))
-        } else {
-            // FIXME: Some code relies on `expn_info().is_none()` meaning "no expansion".
-            // Introduce a method for checking for "no expansion" instead and always return
-            // `ExpnInfo` from this function instead of the `Option`.
-            None
-        }
+    fn expn_data(&self, expn_id: ExpnId) -> &ExpnData {
+        self.expn_data[expn_id.0 as usize].as_ref()
+            .expect("no expansion data for an expansion ID")
     }
 
     fn is_descendant_of(&self, mut expn_id: ExpnId, ancestor: ExpnId) -> bool {
@@ -207,17 +178,11 @@ impl HygieneData {
             if expn_id == ExpnId::root() {
                 return false;
             }
-            expn_id = self.parent_expn(expn_id);
+            expn_id = self.expn_data(expn_id).parent;
         }
         true
     }
 
-    fn default_transparency(&self, expn_id: ExpnId) -> Transparency {
-        self.expn_info(expn_id).map_or(
-            Transparency::SemiTransparent, |einfo| einfo.default_transparency
-        )
-    }
-
     fn modern(&self, ctxt: SyntaxContext) -> SyntaxContext {
         self.syntax_context_data[ctxt.0 as usize].opaque
     }
@@ -246,7 +211,7 @@ impl HygieneData {
 
     fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
         let mut marks = Vec::new();
-        while ctxt != SyntaxContext::empty() {
+        while ctxt != SyntaxContext::root() {
             marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt)));
             ctxt = self.parent_ctxt(ctxt);
         }
@@ -255,12 +220,8 @@ impl HygieneData {
     }
 
     fn walk_chain(&self, mut span: Span, to: SyntaxContext) -> Span {
-        while span.ctxt() != crate::NO_EXPANSION && span.ctxt() != to {
-            if let Some(info) = self.expn_info(self.outer_expn(span.ctxt())) {
-                span = info.call_site;
-            } else {
-                break;
-            }
+        while span.from_expansion() && span.ctxt() != to {
+            span = self.expn_data(self.outer_expn(span.ctxt())).call_site;
         }
         span
     }
@@ -275,7 +236,9 @@ impl HygieneData {
 
     fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
         assert_ne!(expn_id, ExpnId::root());
-        self.apply_mark_with_transparency(ctxt, expn_id, self.default_transparency(expn_id))
+        self.apply_mark_with_transparency(
+            ctxt, expn_id, self.expn_data(expn_id).default_transparency
+        )
     }
 
     fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId,
@@ -285,15 +248,14 @@ impl HygieneData {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
-        let call_site_ctxt =
-            self.expn_info(expn_id).map_or(SyntaxContext::empty(), |info| info.call_site.ctxt());
+        let call_site_ctxt = self.expn_data(expn_id).call_site.ctxt();
         let mut call_site_ctxt = if transparency == Transparency::SemiTransparent {
             self.modern(call_site_ctxt)
         } else {
             self.modern_and_legacy(call_site_ctxt)
         };
 
-        if call_site_ctxt == SyntaxContext::empty() {
+        if call_site_ctxt == SyntaxContext::root() {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
         }
 
@@ -400,7 +362,7 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb
 
 impl SyntaxContext {
     #[inline]
-    pub const fn empty() -> Self {
+    pub const fn root() -> Self {
         SyntaxContext(0)
     }
 
@@ -578,20 +540,20 @@ impl SyntaxContext {
         HygieneData::with(|data| data.outer_expn(self))
     }
 
-    /// `ctxt.outer_expn_info()` is equivalent to but faster than
-    /// `ctxt.outer_expn().expn_info()`.
+    /// `ctxt.outer_expn_data()` is equivalent to but faster than
+    /// `ctxt.outer_expn().expn_data()`.
     #[inline]
-    pub fn outer_expn_info(self) -> Option<ExpnInfo> {
-        HygieneData::with(|data| data.expn_info(data.outer_expn(self)).cloned())
+    pub fn outer_expn_data(self) -> ExpnData {
+        HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
     }
 
-    /// `ctxt.outer_expn_with_info()` is equivalent to but faster than
-    /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_info()) }`.
+    /// `ctxt.outer_expn_with_data()` is equivalent to but faster than
+    /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`.
     #[inline]
-    pub fn outer_expn_with_info(self) -> (ExpnId, Option<ExpnInfo>) {
+    pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) {
         HygieneData::with(|data| {
             let outer = data.outer_expn(self);
-            (outer, data.expn_info(outer).cloned())
+            (outer, data.expn_data(outer).clone())
         })
     }
 
@@ -612,10 +574,10 @@ impl Span {
     /// other compiler-generated code to set per-span properties like allowed unstable features.
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
-    pub fn fresh_expansion(self, parent: ExpnId, expn_info: ExpnInfo) -> Span {
+    pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
         HygieneData::with(|data| {
-            let expn_id = data.fresh_expn(parent, Some(expn_info));
-            self.with_ctxt(data.apply_mark(SyntaxContext::empty(), expn_id))
+            let expn_id = data.fresh_expn(Some(expn_data));
+            self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
         })
     }
 }
@@ -623,8 +585,12 @@ impl Span {
 /// A subset of properties from both macro definition and macro call available through global data.
 /// Avoid using this if you have access to the original definition or call structures.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-pub struct ExpnInfo {
+pub struct ExpnData {
     // --- The part unique to each expansion.
+    /// The kind of this expansion - macro or compiler desugaring.
+    pub kind: ExpnKind,
+    /// The expansion that produced this expansion.
+    pub parent: ExpnId,
     /// The location of the actual macro invocation or syntax sugar , e.g.
     /// `let x = foo!();` or `if let Some(y) = x {}`
     ///
@@ -632,18 +598,18 @@ pub struct ExpnInfo {
     /// `foo!()` invoked `bar!()` internally, and there was an
     /// expression inside `bar!`; the call_site of the expression in
     /// the expansion would point to the `bar!` invocation; that
-    /// call_site span would have its own ExpnInfo, with the call_site
+    /// call_site span would have its own ExpnData, with the call_site
     /// pointing to the `foo!` invocation.
     pub call_site: Span,
-    /// The kind of this expansion - macro or compiler desugaring.
-    pub kind: ExpnKind,
 
     // --- The part specific to the macro/desugaring definition.
-    // --- FIXME: Share it between expansions with the same definition.
+    // --- It may be reasonable to share this part between expansions with the same definition,
+    // --- but such sharing is known to bring some minor inconveniences without also bringing
+    // --- noticeable perf improvements (PR #62898).
     /// The span of the macro definition (possibly dummy).
     /// This span serves only informational purpose and is not used for resolution.
     pub def_site: Span,
-    /// Transparency used by `apply_mark` for the expansion with this expansion info by default.
+    /// Transparency used by `apply_mark` for the expansion with this expansion data by default.
     pub default_transparency: Transparency,
     /// List of #[unstable]/feature-gated features that the macro is allowed to use
     /// internally without forcing the whole crate to opt-in
@@ -659,12 +625,13 @@ pub struct ExpnInfo {
     pub edition: Edition,
 }
 
-impl ExpnInfo {
-    /// Constructs an expansion info with default properties.
-    pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnInfo {
-        ExpnInfo {
-            call_site,
+impl ExpnData {
+    /// Constructs expansion data with default properties.
+    pub fn default(kind: ExpnKind, call_site: Span, edition: Edition) -> ExpnData {
+        ExpnData {
             kind,
+            parent: ExpnId::root(),
+            call_site,
             def_site: DUMMY_SP,
             default_transparency: Transparency::SemiTransparent,
             allow_internal_unstable: None,
@@ -675,12 +642,17 @@ impl ExpnInfo {
     }
 
     pub fn allow_unstable(kind: ExpnKind, call_site: Span, edition: Edition,
-                          allow_internal_unstable: Lrc<[Symbol]>) -> ExpnInfo {
-        ExpnInfo {
+                          allow_internal_unstable: Lrc<[Symbol]>) -> ExpnData {
+        ExpnData {
             allow_internal_unstable: Some(allow_internal_unstable),
-            ..ExpnInfo::default(kind, call_site, edition)
+            ..ExpnData::default(kind, call_site, edition)
         }
     }
+
+    #[inline]
+    pub fn is_root(&self) -> bool {
+        if let ExpnKind::Root = self.kind { true } else { false }
+    }
 }
 
 /// Expansion kind.
@@ -767,14 +739,14 @@ impl DesugaringKind {
     }
 }
 
-impl Encodable for SyntaxContext {
+impl Encodable for ExpnId {
     fn encode<E: Encoder>(&self, _: &mut E) -> Result<(), E::Error> {
         Ok(()) // FIXME(jseyfried) intercrate hygiene
     }
 }
 
-impl Decodable for SyntaxContext {
-    fn decode<D: Decoder>(_: &mut D) -> Result<SyntaxContext, D::Error> {
-        Ok(SyntaxContext::empty()) // FIXME(jseyfried) intercrate hygiene
+impl Decodable for ExpnId {
+    fn decode<D: Decoder>(_: &mut D) -> Result<Self, D::Error> {
+        Ok(ExpnId::root()) // FIXME(jseyfried) intercrate hygiene
     }
 }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 02a7433d946..a17cd7625fb 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -21,7 +21,7 @@ use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
 pub mod edition;
 use edition::Edition;
 pub mod hygiene;
-pub use hygiene::{ExpnId, SyntaxContext, ExpnInfo, ExpnKind, MacroKind, DesugaringKind};
+pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind};
 
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -49,7 +49,6 @@ pub struct Globals {
     symbol_interner: Lock<symbol::Interner>,
     span_interner: Lock<span_encoding::SpanInterner>,
     hygiene_data: Lock<hygiene::HygieneData>,
-    edition: Edition,
 }
 
 impl Globals {
@@ -58,7 +57,6 @@ impl Globals {
             symbol_interner: Lock::new(symbol::Interner::fresh()),
             span_interner: Lock::new(span_encoding::SpanInterner::default()),
             hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
-            edition,
         }
     }
 }
@@ -288,6 +286,17 @@ impl Span {
         span.lo.0 == 0 && span.hi.0 == 0
     }
 
+    /// Returns `true` if this span comes from a macro or desugaring.
+    #[inline]
+    pub fn from_expansion(self) -> bool {
+        self.ctxt() != SyntaxContext::root()
+    }
+
+    #[inline]
+    pub fn with_root_ctxt(lo: BytePos, hi: BytePos) -> Span {
+        Span::new(lo, hi, SyntaxContext::root())
+    }
+
     /// Returns a new span representing an empty span at the beginning of this span
     #[inline]
     pub fn shrink_to_lo(self) -> Span {
@@ -344,20 +353,20 @@ impl Span {
     /// Returns the source span -- this is either the supplied span, or the span for
     /// the macro callsite that expanded to it.
     pub fn source_callsite(self) -> Span {
-        self.ctxt().outer_expn_info().map(|info| info.call_site.source_callsite()).unwrap_or(self)
+        let expn_data = self.ctxt().outer_expn_data();
+        if !expn_data.is_root() { expn_data.call_site.source_callsite() } else { self }
     }
 
     /// The `Span` for the tokens in the previous macro expansion from which `self` was generated,
     /// if any.
     pub fn parent(self) -> Option<Span> {
-        self.ctxt().outer_expn_info().map(|i| i.call_site)
+        let expn_data = self.ctxt().outer_expn_data();
+        if !expn_data.is_root() { Some(expn_data.call_site) } else { None }
     }
 
     /// Edition of the crate from which this span came.
     pub fn edition(self) -> edition::Edition {
-        self.ctxt().outer_expn_info().map_or_else(|| {
-            Edition::from_session()
-        }, |einfo| einfo.edition)
+        self.ctxt().outer_expn_data().edition
     }
 
     #[inline]
@@ -373,52 +382,42 @@ impl Span {
     /// Returns the source callee.
     ///
     /// Returns `None` if the supplied span has no expansion trace,
-    /// else returns the `ExpnInfo` for the macro definition
+    /// else returns the `ExpnData` for the macro definition
     /// corresponding to the source callsite.
-    pub fn source_callee(self) -> Option<ExpnInfo> {
-        fn source_callee(info: ExpnInfo) -> ExpnInfo {
-            match info.call_site.ctxt().outer_expn_info() {
-                Some(info) => source_callee(info),
-                None => info,
-            }
+    pub fn source_callee(self) -> Option<ExpnData> {
+        fn source_callee(expn_data: ExpnData) -> ExpnData {
+            let next_expn_data = expn_data.call_site.ctxt().outer_expn_data();
+            if !next_expn_data.is_root() { source_callee(next_expn_data) } else { expn_data }
         }
-        self.ctxt().outer_expn_info().map(source_callee)
+        let expn_data = self.ctxt().outer_expn_data();
+        if !expn_data.is_root() { Some(source_callee(expn_data)) } else { None }
     }
 
     /// Checks if a span is "internal" to a macro in which `#[unstable]`
     /// items can be used (that is, a macro marked with
     /// `#[allow_internal_unstable]`).
     pub fn allows_unstable(&self, feature: Symbol) -> bool {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => info
-                .allow_internal_unstable
-                .map_or(false, |features| features.iter().any(|&f|
-                    f == feature || f == sym::allow_internal_unstable_backcompat_hack
-                )),
-            None => false,
-        }
+        self.ctxt().outer_expn_data().allow_internal_unstable.map_or(false, |features| {
+            features.iter().any(|&f| {
+                f == feature || f == sym::allow_internal_unstable_backcompat_hack
+            })
+        })
     }
 
     /// Checks if this span arises from a compiler desugaring of kind `kind`.
     pub fn is_desugaring(&self, kind: DesugaringKind) -> bool {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => match info.kind {
-                ExpnKind::Desugaring(k) => k == kind,
-                _ => false,
-            },
-            None => false,
+        match self.ctxt().outer_expn_data().kind {
+            ExpnKind::Desugaring(k) => k == kind,
+            _ => false,
         }
     }
 
     /// Returns the compiler desugaring that created this span, or `None`
     /// if this span is not from a desugaring.
     pub fn desugaring_kind(&self) -> Option<DesugaringKind> {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => match info.kind {
-                ExpnKind::Desugaring(k) => Some(k),
-                _ => None
-            },
-            None => None
+        match self.ctxt().outer_expn_data().kind {
+            ExpnKind::Desugaring(k) => Some(k),
+            _ => None
         }
     }
 
@@ -426,19 +425,20 @@ impl Span {
     /// can be used without triggering the `unsafe_code` lint
     //  (that is, a macro marked with `#[allow_internal_unsafe]`).
     pub fn allows_unsafe(&self) -> bool {
-        match self.ctxt().outer_expn_info() {
-            Some(info) => info.allow_internal_unsafe,
-            None => false,
-        }
+        self.ctxt().outer_expn_data().allow_internal_unsafe
     }
 
     pub fn macro_backtrace(mut self) -> Vec<MacroBacktrace> {
         let mut prev_span = DUMMY_SP;
         let mut result = vec![];
-        while let Some(info) = self.ctxt().outer_expn_info() {
+        loop {
+            let expn_data = self.ctxt().outer_expn_data();
+            if expn_data.is_root() {
+                break;
+            }
             // Don't print recursive invocations.
-            if !info.call_site.source_equal(&prev_span) {
-                let (pre, post) = match info.kind {
+            if !expn_data.call_site.source_equal(&prev_span) {
+                let (pre, post) = match expn_data.kind {
                     ExpnKind::Root => break,
                     ExpnKind::Desugaring(..) => ("desugaring of ", ""),
                     ExpnKind::Macro(macro_kind, _) => match macro_kind {
@@ -448,14 +448,14 @@ impl Span {
                     }
                 };
                 result.push(MacroBacktrace {
-                    call_site: info.call_site,
-                    macro_decl_name: format!("{}{}{}", pre, info.kind.descr(), post),
-                    def_site_span: info.def_site,
+                    call_site: expn_data.call_site,
+                    macro_decl_name: format!("{}{}{}", pre, expn_data.kind.descr(), post),
+                    def_site_span: expn_data.def_site,
                 });
             }
 
             prev_span = self;
-            self = info.call_site;
+            self = expn_data.call_site;
         }
         result
     }
@@ -468,9 +468,9 @@ impl Span {
         // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
         // have an incomplete span than a completely nonsensical one.
         if span_data.ctxt != end_data.ctxt {
-            if span_data.ctxt == SyntaxContext::empty() {
+            if span_data.ctxt == SyntaxContext::root() {
                 return end;
-            } else if end_data.ctxt == SyntaxContext::empty() {
+            } else if end_data.ctxt == SyntaxContext::root() {
                 return self;
             }
             // Both spans fall within a macro.
@@ -479,7 +479,7 @@ impl Span {
         Span::new(
             cmp::min(span_data.lo, end_data.lo),
             cmp::max(span_data.hi, end_data.hi),
-            if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt },
+            if span_data.ctxt == SyntaxContext::root() { end_data.ctxt } else { span_data.ctxt },
         )
     }
 
@@ -490,7 +490,7 @@ impl Span {
         Span::new(
             span.hi,
             end.lo,
-            if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
+            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
         )
     }
 
@@ -501,7 +501,7 @@ impl Span {
         Span::new(
             span.lo,
             end.lo,
-            if end.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
+            if end.ctxt == SyntaxContext::root() { end.ctxt } else { span.ctxt },
         )
     }
 
@@ -611,7 +611,7 @@ impl rustc_serialize::UseSpecializedDecodable for Span {
         d.read_struct("Span", 2, |d| {
             let lo = d.read_struct_field("lo", 0, Decodable::decode)?;
             let hi = d.read_struct_field("hi", 1, Decodable::decode)?;
-            Ok(Span::new(lo, hi, NO_EXPANSION))
+            Ok(Span::with_root_ctxt(lo, hi))
         })
     }
 }
@@ -755,8 +755,6 @@ impl From<Vec<Span>> for MultiSpan {
     }
 }
 
-pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty();
-
 /// Identifies an offset of a multi-byte character in a `SourceFile`.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Eq, PartialEq, Debug)]
 pub struct MultiByteChar {
@@ -1045,6 +1043,7 @@ impl SourceFile {
                mut src: String,
                start_pos: BytePos) -> Result<SourceFile, OffsetOverflowError> {
         remove_bom(&mut src);
+        normalize_newlines(&mut src);
 
         let src_hash = {
             let mut hasher: StableHasher<u128> = StableHasher::new();
@@ -1212,6 +1211,61 @@ fn remove_bom(src: &mut String) {
     }
 }
 
+
+/// Replaces `\r\n` with `\n` in-place in `src`.
+///
+/// Returns error if there's a lone `\r` in the string
+fn normalize_newlines(src: &mut String) {
+    if !src.as_bytes().contains(&b'\r') {
+        return;
+    }
+
+    // We replace `\r\n` with `\n` in-place, which doesn't break utf-8 encoding.
+    // While we *can* call `as_mut_vec` and do surgery on the live string
+    // directly, let's rather steal the contents of `src`. This makes the code
+    // safe even if a panic occurs.
+
+    let mut buf = std::mem::replace(src, String::new()).into_bytes();
+    let mut gap_len = 0;
+    let mut tail = buf.as_mut_slice();
+    loop {
+        let idx = match find_crlf(&tail[gap_len..]) {
+            None => tail.len(),
+            Some(idx) => idx + gap_len,
+        };
+        tail.copy_within(gap_len..idx, 0);
+        tail = &mut tail[idx - gap_len..];
+        if tail.len() == gap_len {
+            break;
+        }
+        gap_len += 1;
+    }
+
+    // Account for removed `\r`.
+    // After `set_len`, `buf` is guaranteed to contain utf-8 again.
+    let new_len = buf.len() - gap_len;
+    unsafe {
+        buf.set_len(new_len);
+        *src = String::from_utf8_unchecked(buf);
+    }
+
+    fn find_crlf(src: &[u8]) -> Option<usize> {
+        let mut search_idx = 0;
+        while let Some(idx) = find_cr(&src[search_idx..]) {
+            if src[search_idx..].get(idx + 1) != Some(&b'\n') {
+                search_idx += idx + 1;
+                continue;
+            }
+            return Some(search_idx + idx);
+        }
+        None
+    }
+
+    fn find_cr(src: &[u8]) -> Option<usize> {
+        src.iter().position(|&b| b == b'\r')
+    }
+}
+
 // _____________________________________________________________________________
 // Pos, BytePos, CharPos
 //
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 2d9556233d1..0b8f16bbc3b 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -8,13 +8,13 @@ use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::newtype_index;
 use rustc_macros::symbols;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};
 
 use std::cmp::{PartialEq, Ordering, PartialOrd, Ord};
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::str;
 
-use crate::hygiene::SyntaxContext;
 use crate::{Span, DUMMY_SP, GLOBALS};
 
 #[cfg(test)]
@@ -470,6 +470,7 @@ symbols! {
         option_env,
         opt_out_copy,
         or,
+        or_patterns,
         Ord,
         Ordering,
         Output,
@@ -610,7 +611,6 @@ symbols! {
         rust_eh_personality,
         rust_eh_unwind_resume,
         rust_oom,
-        __rust_unstable_column,
         rvalue_static_promotion,
         sanitizer_runtime,
         _Self,
@@ -745,25 +745,25 @@ impl Ident {
         Ident { name, span }
     }
 
-    /// Constructs a new identifier with an empty syntax context.
+    /// Constructs a new identifier with a dummy span.
     #[inline]
-    pub const fn with_empty_ctxt(name: Symbol) -> Ident {
+    pub const fn with_dummy_span(name: Symbol) -> Ident {
         Ident::new(name, DUMMY_SP)
     }
 
     #[inline]
     pub fn invalid() -> Ident {
-        Ident::with_empty_ctxt(kw::Invalid)
+        Ident::with_dummy_span(kw::Invalid)
     }
 
     /// Maps an interned string to an identifier with an empty syntax context.
     pub fn from_interned_str(string: InternedString) -> Ident {
-        Ident::with_empty_ctxt(string.as_symbol())
+        Ident::with_dummy_span(string.as_symbol())
     }
 
     /// Maps a string to an identifier with an empty span.
     pub fn from_str(string: &str) -> Ident {
-        Ident::with_empty_ctxt(Symbol::intern(string))
+        Ident::with_dummy_span(Symbol::intern(string))
     }
 
     /// Maps a string and a span to an identifier.
@@ -849,28 +849,9 @@ impl fmt::Display for Ident {
     }
 }
 
-impl Encodable for Ident {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        if self.span.ctxt().modern() == SyntaxContext::empty() {
-            s.emit_str(&self.as_str())
-        } else { // FIXME(jseyfried): intercrate hygiene
-            let mut string = "#".to_owned();
-            string.push_str(&self.as_str());
-            s.emit_str(&string)
-        }
-    }
-}
+impl UseSpecializedEncodable for Ident {}
 
-impl Decodable for Ident {
-    fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        let string = d.read_str()?;
-        Ok(if !string.starts_with('#') {
-            Ident::from_str(&string)
-        } else { // FIXME(jseyfried): intercrate hygiene
-            Ident::from_str(&string[1..]).gensym()
-        })
-    }
-}
+impl UseSpecializedDecodable for Ident {}
 
 /// A symbol is an interned or gensymed string. A gensym is a symbol that is
 /// never equal to any other symbol.
diff --git a/src/libsyntax_pos/tests.rs b/src/libsyntax_pos/tests.rs
index 78c4e18e6ae..6bd6016020a 100644
--- a/src/libsyntax_pos/tests.rs
+++ b/src/libsyntax_pos/tests.rs
@@ -16,3 +16,23 @@ fn test_lookup_line() {
     assert_eq!(lookup_line(lines, BytePos(28)), 2);
     assert_eq!(lookup_line(lines, BytePos(29)), 2);
 }
+
+#[test]
+fn test_normalize_newlines() {
+    fn check(before: &str, after: &str) {
+        let mut actual = before.to_string();
+        normalize_newlines(&mut actual);
+        assert_eq!(actual.as_str(), after);
+    }
+    check("", "");
+    check("\n", "\n");
+    check("\r", "\r");
+    check("\r\r", "\r\r");
+    check("\r\n", "\n");
+    check("hello world", "hello world");
+    check("hello\nworld", "hello\nworld");
+    check("hello\r\nworld", "hello\nworld");
+    check("\r\nhello\r\nworld\r\n", "\nhello\nworld\n");
+    check("\r\r\n", "\r\n");
+    check("hello\rworld", "hello\rworld");
+}
diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
index f0f1bab425d..f10df8c85ba 100644
--- a/src/libunwind/Cargo.toml
+++ b/src/libunwind/Cargo.toml
@@ -22,7 +22,7 @@ compiler_builtins = "0.1.0"
 cfg-if = "0.1.8"
 
 [build-dependencies]
-cc = { optional = true, version = "1.0.1" }
+cc = { version = "1.0.1" }
 
 [features]
-llvm-libunwind = ["cc"]
+llvm-libunwind = []
diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs
index c1b0dbc0881..f24d957d67b 100644
--- a/src/libunwind/build.rs
+++ b/src/libunwind/build.rs
@@ -5,14 +5,14 @@ fn main() {
     let target = env::var("TARGET").expect("TARGET was not set");
 
     if cfg!(feature = "llvm-libunwind") &&
-        (target.contains("linux") ||
+        ((target.contains("linux") && !target.contains("musl")) ||
          target.contains("fuchsia")) {
         // Build the unwinding from libunwind C/C++ source code.
-        #[cfg(feature = "llvm-libunwind")]
         llvm_libunwind::compile();
     } else if target.contains("linux") {
         if target.contains("musl") {
-            // musl is handled in lib.rs
+            // linking for musl is handled in lib.rs
+            llvm_libunwind::compile();
         } else if !target.contains("android") {
             println!("cargo:rustc-link-lib=gcc_s");
         }
@@ -23,7 +23,11 @@ fn main() {
     } else if target.contains("netbsd") {
         println!("cargo:rustc-link-lib=gcc_s");
     } else if target.contains("openbsd") {
-        println!("cargo:rustc-link-lib=c++abi");
+        if target.contains("sparc64") {
+            println!("cargo:rustc-link-lib=gcc");
+        } else {
+            println!("cargo:rustc-link-lib=c++abi");
+        }
     } else if target.contains("solaris") {
         println!("cargo:rustc-link-lib=gcc_s");
     } else if target.contains("dragonfly") {
@@ -44,7 +48,6 @@ fn main() {
     }
 }
 
-#[cfg(feature = "llvm-libunwind")]
 mod llvm_libunwind {
     use std::env;
     use std::path::Path;
@@ -96,6 +99,15 @@ mod llvm_libunwind {
             cfg.file(root.join("src").join(src));
         }
 
+        if target_env == "musl" {
+            // use the same C compiler command to compile C++ code so we do not need to setup the
+            // C++ compiler env variables on the builders
+            cfg.cpp(false);
+            // linking for musl is handled in lib.rs
+            cfg.cargo_metadata(false);
+            println!("cargo:rustc-link-search=native={}", env::var("OUT_DIR").unwrap());
+        }
+
         cfg.compile("unwind");
     }
 }
diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs
index 02d93238dd6..619cce685d7 100644
--- a/src/test/pretty/stmt_expr_attributes.rs
+++ b/src/test/pretty/stmt_expr_attributes.rs
@@ -259,8 +259,6 @@ fn _12() {
     }
 }
 
-/////////////////
-
 fn foo() { }
 fn foo3(_: i32, _: (), _: ()) { }
 fn qux(_: i32) { }
diff --git a/src/test/run-make-fulldeps/reproducible-build-2/Makefile b/src/test/run-make-fulldeps/reproducible-build-2/Makefile
index b96954fea0d..45c9a742723 100644
--- a/src/test/run-make-fulldeps/reproducible-build-2/Makefile
+++ b/src/test/run-make-fulldeps/reproducible-build-2/Makefile
@@ -5,7 +5,8 @@
 # Objects are reproducible but their path is not.
 
 all:  \
-	fat_lto
+	fat_lto \
+	sysroot
 
 fat_lto:
 	rm -rf $(TMPDIR) && mkdir $(TMPDIR)
@@ -14,3 +15,12 @@ fat_lto:
 	cp $(TMPDIR)/reproducible-build $(TMPDIR)/reproducible-build-a
 	$(RUSTC) reproducible-build.rs -C lto=fat
 	cmp "$(TMPDIR)/reproducible-build-a" "$(TMPDIR)/reproducible-build" || exit 1
+
+sysroot:
+	rm -rf $(TMPDIR) && mkdir $(TMPDIR)
+	$(RUSTC) reproducible-build-aux.rs
+	$(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(shell $(RUSTC) --print sysroot) --remap-path-prefix=$(shell $(RUSTC) --print sysroot)=/sysroot
+	cp -r $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot
+	cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
+	$(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(TMPDIR)/sysroot --remap-path-prefix=$(TMPDIR)/sysroot=/sysroot
+	cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
diff --git a/src/test/ui/.gitattributes b/src/test/ui/.gitattributes
index b62ade73aa9..489dc8ad111 100644
--- a/src/test/ui/.gitattributes
+++ b/src/test/ui/.gitattributes
@@ -1,2 +1,3 @@
 lexer-crlf-line-endings-string-literal-doc-comment.rs -text
 trailing-carriage-return-in-string.rs -text
+*.bin -text
diff --git a/src/test/ui/abi-sysv64-arg-passing.rs b/src/test/ui/abi/abi-sysv64-arg-passing.rs
index d40006eb9b6..d40006eb9b6 100644
--- a/src/test/ui/abi-sysv64-arg-passing.rs
+++ b/src/test/ui/abi/abi-sysv64-arg-passing.rs
diff --git a/src/test/ui/abi-sysv64-register-usage.rs b/src/test/ui/abi/abi-sysv64-register-usage.rs
index 0c7e2d906b7..0c7e2d906b7 100644
--- a/src/test/ui/abi-sysv64-register-usage.rs
+++ b/src/test/ui/abi/abi-sysv64-register-usage.rs
diff --git a/src/test/ui/abort-on-c-abi.rs b/src/test/ui/abi/abort-on-c-abi.rs
index cd7dd1b6a45..cd7dd1b6a45 100644
--- a/src/test/ui/abort-on-c-abi.rs
+++ b/src/test/ui/abi/abort-on-c-abi.rs
diff --git a/src/test/ui/anon-extern-mod.rs b/src/test/ui/abi/anon-extern-mod.rs
index 37a67876c91..37a67876c91 100644
--- a/src/test/ui/anon-extern-mod.rs
+++ b/src/test/ui/abi/anon-extern-mod.rs
diff --git a/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
index 948b5e688eb..948b5e688eb 100644
--- a/src/test/ui/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/src/test/ui/abi/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/ui/auxiliary/foreign_lib.rs b/src/test/ui/abi/auxiliary/foreign_lib.rs
index de6b0e2118a..de6b0e2118a 100644
--- a/src/test/ui/auxiliary/foreign_lib.rs
+++ b/src/test/ui/abi/auxiliary/foreign_lib.rs
diff --git a/src/test/ui/c-stack-as-value.rs b/src/test/ui/abi/c-stack-as-value.rs
index 7595b76fb3f..7595b76fb3f 100644
--- a/src/test/ui/c-stack-as-value.rs
+++ b/src/test/ui/abi/c-stack-as-value.rs
diff --git a/src/test/ui/cabi-int-widening.rs b/src/test/ui/abi/cabi-int-widening.rs
index 240eaebf3d6..240eaebf3d6 100644
--- a/src/test/ui/cabi-int-widening.rs
+++ b/src/test/ui/abi/cabi-int-widening.rs
diff --git a/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
index 948b5e688eb..948b5e688eb 100644
--- a/src/test/ui/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/src/test/ui/abi/consts/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs b/src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
index 77168be5374..77168be5374 100644
--- a/src/test/ui/cross-crate/anon-extern-mod-cross-crate-2.rs
+++ b/src/test/ui/abi/cross-crate/anon-extern-mod-cross-crate-2.rs
diff --git a/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
index 948b5e688eb..948b5e688eb 100644
--- a/src/test/ui/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
+++ b/src/test/ui/abi/cross-crate/auxiliary/anon-extern-mod-cross-crate-1.rs
diff --git a/src/test/ui/duplicated-external-mods.rs b/src/test/ui/abi/duplicated-external-mods.rs
index 05a279a3014..05a279a3014 100644
--- a/src/test/ui/duplicated-external-mods.rs
+++ b/src/test/ui/abi/duplicated-external-mods.rs
diff --git a/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs b/src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs
index d4568d38e25..d4568d38e25 100644
--- a/src/test/ui/extern/auxiliary/extern-crosscrate-source.rs
+++ b/src/test/ui/abi/extern/auxiliary/extern-crosscrate-source.rs
diff --git a/src/test/ui/extern/extern-call-deep.rs b/src/test/ui/abi/extern/extern-call-deep.rs
index 81f884dada9..81f884dada9 100644
--- a/src/test/ui/extern/extern-call-deep.rs
+++ b/src/test/ui/abi/extern/extern-call-deep.rs
diff --git a/src/test/ui/extern/extern-call-deep2.rs b/src/test/ui/abi/extern/extern-call-deep2.rs
index b31489b1e10..b31489b1e10 100644
--- a/src/test/ui/extern/extern-call-deep2.rs
+++ b/src/test/ui/abi/extern/extern-call-deep2.rs
diff --git a/src/test/ui/extern/extern-call-direct.rs b/src/test/ui/abi/extern/extern-call-direct.rs
index 72041764215..72041764215 100644
--- a/src/test/ui/extern/extern-call-direct.rs
+++ b/src/test/ui/abi/extern/extern-call-direct.rs
diff --git a/src/test/ui/extern/extern-call-indirect.rs b/src/test/ui/abi/extern/extern-call-indirect.rs
index 158b54e4b8c..158b54e4b8c 100644
--- a/src/test/ui/extern/extern-call-indirect.rs
+++ b/src/test/ui/abi/extern/extern-call-indirect.rs
diff --git a/src/test/ui/extern/extern-call-scrub.rs b/src/test/ui/abi/extern/extern-call-scrub.rs
index a7b1065c9e1..a7b1065c9e1 100644
--- a/src/test/ui/extern/extern-call-scrub.rs
+++ b/src/test/ui/abi/extern/extern-call-scrub.rs
diff --git a/src/test/ui/extern/extern-crosscrate.rs b/src/test/ui/abi/extern/extern-crosscrate.rs
index 123ce20ca26..123ce20ca26 100644
--- a/src/test/ui/extern/extern-crosscrate.rs
+++ b/src/test/ui/abi/extern/extern-crosscrate.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU16s.rs b/src/test/ui/abi/extern/extern-pass-TwoU16s.rs
index 285bce2e19c..285bce2e19c 100644
--- a/src/test/ui/extern/extern-pass-TwoU16s.rs
+++ b/src/test/ui/abi/extern/extern-pass-TwoU16s.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU32s.rs b/src/test/ui/abi/extern/extern-pass-TwoU32s.rs
index fb18aa8d22f..fb18aa8d22f 100644
--- a/src/test/ui/extern/extern-pass-TwoU32s.rs
+++ b/src/test/ui/abi/extern/extern-pass-TwoU32s.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU64s.rs b/src/test/ui/abi/extern/extern-pass-TwoU64s.rs
index 419648263aa..419648263aa 100644
--- a/src/test/ui/extern/extern-pass-TwoU64s.rs
+++ b/src/test/ui/abi/extern/extern-pass-TwoU64s.rs
diff --git a/src/test/ui/extern/extern-pass-TwoU8s.rs b/src/test/ui/abi/extern/extern-pass-TwoU8s.rs
index 53a6a0f29f8..53a6a0f29f8 100644
--- a/src/test/ui/extern/extern-pass-TwoU8s.rs
+++ b/src/test/ui/abi/extern/extern-pass-TwoU8s.rs
diff --git a/src/test/ui/extern/extern-pass-char.rs b/src/test/ui/abi/extern/extern-pass-char.rs
index 22f841b4552..22f841b4552 100644
--- a/src/test/ui/extern/extern-pass-char.rs
+++ b/src/test/ui/abi/extern/extern-pass-char.rs
diff --git a/src/test/ui/extern/extern-pass-double.rs b/src/test/ui/abi/extern/extern-pass-double.rs
index dbd0a2dfa48..dbd0a2dfa48 100644
--- a/src/test/ui/extern/extern-pass-double.rs
+++ b/src/test/ui/abi/extern/extern-pass-double.rs
diff --git a/src/test/ui/extern/extern-pass-empty.rs b/src/test/ui/abi/extern/extern-pass-empty.rs
index 07099a24204..07099a24204 100644
--- a/src/test/ui/extern/extern-pass-empty.rs
+++ b/src/test/ui/abi/extern/extern-pass-empty.rs
diff --git a/src/test/ui/extern/extern-pass-u32.rs b/src/test/ui/abi/extern/extern-pass-u32.rs
index f2efdb7d366..f2efdb7d366 100644
--- a/src/test/ui/extern/extern-pass-u32.rs
+++ b/src/test/ui/abi/extern/extern-pass-u32.rs
diff --git a/src/test/ui/extern/extern-pass-u64.rs b/src/test/ui/abi/extern/extern-pass-u64.rs
index 975446d430c..975446d430c 100644
--- a/src/test/ui/extern/extern-pass-u64.rs
+++ b/src/test/ui/abi/extern/extern-pass-u64.rs
diff --git a/src/test/ui/extern/extern-return-TwoU16s.rs b/src/test/ui/abi/extern/extern-return-TwoU16s.rs
index dd884ee77fe..dd884ee77fe 100644
--- a/src/test/ui/extern/extern-return-TwoU16s.rs
+++ b/src/test/ui/abi/extern/extern-return-TwoU16s.rs
diff --git a/src/test/ui/extern/extern-return-TwoU32s.rs b/src/test/ui/abi/extern/extern-return-TwoU32s.rs
index d6aaf5c9eaf..d6aaf5c9eaf 100644
--- a/src/test/ui/extern/extern-return-TwoU32s.rs
+++ b/src/test/ui/abi/extern/extern-return-TwoU32s.rs
diff --git a/src/test/ui/extern/extern-return-TwoU64s.rs b/src/test/ui/abi/extern/extern-return-TwoU64s.rs
index c5e4ebadc18..c5e4ebadc18 100644
--- a/src/test/ui/extern/extern-return-TwoU64s.rs
+++ b/src/test/ui/abi/extern/extern-return-TwoU64s.rs
diff --git a/src/test/ui/extern/extern-return-TwoU8s.rs b/src/test/ui/abi/extern/extern-return-TwoU8s.rs
index a7cd21b2073..a7cd21b2073 100644
--- a/src/test/ui/extern/extern-return-TwoU8s.rs
+++ b/src/test/ui/abi/extern/extern-return-TwoU8s.rs
diff --git a/src/test/ui/foreign/auxiliary/foreign_lib.rs b/src/test/ui/abi/foreign/auxiliary/foreign_lib.rs
index de6b0e2118a..de6b0e2118a 100644
--- a/src/test/ui/foreign/auxiliary/foreign_lib.rs
+++ b/src/test/ui/abi/foreign/auxiliary/foreign_lib.rs
diff --git a/src/test/ui/foreign/foreign-call-no-runtime.rs b/src/test/ui/abi/foreign/foreign-call-no-runtime.rs
index c6afa07ad05..c6afa07ad05 100644
--- a/src/test/ui/foreign/foreign-call-no-runtime.rs
+++ b/src/test/ui/abi/foreign/foreign-call-no-runtime.rs
diff --git a/src/test/ui/foreign/foreign-dupe.rs b/src/test/ui/abi/foreign/foreign-dupe.rs
index 3c9f0f583d4..3c9f0f583d4 100644
--- a/src/test/ui/foreign/foreign-dupe.rs
+++ b/src/test/ui/abi/foreign/foreign-dupe.rs
diff --git a/src/test/ui/foreign/foreign-fn-with-byval.rs b/src/test/ui/abi/foreign/foreign-fn-with-byval.rs
index 3a35599aa57..3a35599aa57 100644
--- a/src/test/ui/foreign/foreign-fn-with-byval.rs
+++ b/src/test/ui/abi/foreign/foreign-fn-with-byval.rs
diff --git a/src/test/ui/foreign/foreign-no-abi.rs b/src/test/ui/abi/foreign/foreign-no-abi.rs
index 2f33fb47656..2f33fb47656 100644
--- a/src/test/ui/foreign/foreign-no-abi.rs
+++ b/src/test/ui/abi/foreign/foreign-no-abi.rs
diff --git a/src/test/ui/invoke-external-foreign.rs b/src/test/ui/abi/invoke-external-foreign.rs
index dbd2b4ad865..dbd2b4ad865 100644
--- a/src/test/ui/invoke-external-foreign.rs
+++ b/src/test/ui/abi/invoke-external-foreign.rs
diff --git a/src/test/ui/lib-defaults.rs b/src/test/ui/abi/lib-defaults.rs
index cd0b0bb2321..cd0b0bb2321 100644
--- a/src/test/ui/lib-defaults.rs
+++ b/src/test/ui/abi/lib-defaults.rs
diff --git a/src/test/ui/macros/macros-in-extern.rs b/src/test/ui/abi/macros/macros-in-extern.rs
index bba8b15cdb0..bba8b15cdb0 100644
--- a/src/test/ui/macros/macros-in-extern.rs
+++ b/src/test/ui/abi/macros/macros-in-extern.rs
diff --git a/src/test/ui/macros/macros-in-extern.stderr b/src/test/ui/abi/macros/macros-in-extern.stderr
index 6ee33f4ab61..6ee33f4ab61 100644
--- a/src/test/ui/macros/macros-in-extern.stderr
+++ b/src/test/ui/abi/macros/macros-in-extern.stderr
diff --git a/src/test/ui/mir/mir_codegen_calls_variadic.rs b/src/test/ui/abi/mir/mir_codegen_calls_variadic.rs
index dc9fee03b77..dc9fee03b77 100644
--- a/src/test/ui/mir/mir_codegen_calls_variadic.rs
+++ b/src/test/ui/abi/mir/mir_codegen_calls_variadic.rs
diff --git a/src/test/ui/numbers-arithmetic/i128-ffi.rs b/src/test/ui/abi/numbers-arithmetic/i128-ffi.rs
index 19edf9779f3..19edf9779f3 100644
--- a/src/test/ui/numbers-arithmetic/i128-ffi.rs
+++ b/src/test/ui/abi/numbers-arithmetic/i128-ffi.rs
diff --git a/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
new file mode 100644
index 00000000000..27efa44f980
--- /dev/null
+++ b/src/test/ui/abi/proc-macro/auxiliary/test-macros.rs
@@ -0,0 +1,112 @@
+// force-host
+// no-prefer-dynamic
+
+// Proc macros commonly used by tests.
+// `panic`/`print` -> `panic_bang`/`print_bang` to avoid conflicts with standard macros.
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+// Macro that return empty token stream.
+
+#[proc_macro]
+pub fn empty(_: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+#[proc_macro_attribute]
+pub fn empty_attr(_: TokenStream, _: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+#[proc_macro_derive(Empty, attributes(empty_helper))]
+pub fn empty_derive(_: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
+
+// Macro that panics.
+
+#[proc_macro]
+pub fn panic_bang(_: TokenStream) -> TokenStream {
+    panic!("panic-bang");
+}
+
+#[proc_macro_attribute]
+pub fn panic_attr(_: TokenStream, _: TokenStream) -> TokenStream {
+    panic!("panic-attr");
+}
+
+#[proc_macro_derive(Panic, attributes(panic_helper))]
+pub fn panic_derive(_: TokenStream) -> TokenStream {
+    panic!("panic-derive");
+}
+
+// Macros that return the input stream.
+
+#[proc_macro]
+pub fn identity(input: TokenStream) -> TokenStream {
+    input
+}
+
+#[proc_macro_attribute]
+pub fn identity_attr(_: TokenStream, input: TokenStream) -> TokenStream {
+    input
+}
+
+#[proc_macro_derive(Identity, attributes(identity_helper))]
+pub fn identity_derive(input: TokenStream) -> TokenStream {
+    input
+}
+
+// Macros that iterate and re-collect the input stream.
+
+#[proc_macro]
+pub fn recollect(input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
+
+#[proc_macro_attribute]
+pub fn recollect_attr(_: TokenStream, input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
+
+#[proc_macro_derive(Recollect, attributes(recollect_helper))]
+pub fn recollect_derive(input: TokenStream) -> TokenStream {
+    input.into_iter().collect()
+}
+
+// Macros that print their input in the original and re-collected forms (if they differ).
+
+fn print_helper(input: TokenStream, kind: &str) -> TokenStream {
+    let input_display = format!("{}", input);
+    let input_debug = format!("{:#?}", input);
+    let recollected = input.into_iter().collect();
+    let recollected_display = format!("{}", recollected);
+    let recollected_debug = format!("{:#?}", recollected);
+    println!("PRINT-{} INPUT (DISPLAY): {}", kind, input_display);
+    if recollected_display != input_display {
+        println!("PRINT-{} RE-COLLECTED (DISPLAY): {}", kind, recollected_display);
+    }
+    println!("PRINT-{} INPUT (DEBUG): {}", kind, input_debug);
+    if recollected_debug != input_debug {
+        println!("PRINT-{} RE-COLLECTED (DEBUG): {}", kind, recollected_debug);
+    }
+    recollected
+}
+
+#[proc_macro]
+pub fn print_bang(input: TokenStream) -> TokenStream {
+    print_helper(input, "BANG")
+}
+
+#[proc_macro_attribute]
+pub fn print_attr(_: TokenStream, input: TokenStream) -> TokenStream {
+    print_helper(input, "ATTR")
+}
+
+#[proc_macro_derive(Print, attributes(print_helper))]
+pub fn print_derive(input: TokenStream) -> TokenStream {
+    print_helper(input, "DERIVE")
+}
diff --git a/src/test/ui/proc-macro/macros-in-extern.rs b/src/test/ui/abi/proc-macro/macros-in-extern.rs
index 0477b5c48ec..0477b5c48ec 100644
--- a/src/test/ui/proc-macro/macros-in-extern.rs
+++ b/src/test/ui/abi/proc-macro/macros-in-extern.rs
diff --git a/src/test/ui/proc-macro/macros-in-extern.stderr b/src/test/ui/abi/proc-macro/macros-in-extern.stderr
index 6049c2aa448..6049c2aa448 100644
--- a/src/test/ui/proc-macro/macros-in-extern.stderr
+++ b/src/test/ui/abi/proc-macro/macros-in-extern.stderr
diff --git a/src/test/ui/segfault-no-out-of-stack.rs b/src/test/ui/abi/segfault-no-out-of-stack.rs
index 626de4ed5b6..626de4ed5b6 100644
--- a/src/test/ui/segfault-no-out-of-stack.rs
+++ b/src/test/ui/abi/segfault-no-out-of-stack.rs
diff --git a/src/test/ui/stack-probes-lto.rs b/src/test/ui/abi/stack-probes-lto.rs
index 9018ff4bfc2..9018ff4bfc2 100644
--- a/src/test/ui/stack-probes-lto.rs
+++ b/src/test/ui/abi/stack-probes-lto.rs
diff --git a/src/test/ui/stack-probes.rs b/src/test/ui/abi/stack-probes.rs
index 1ab1d6df66d..1ab1d6df66d 100644
--- a/src/test/ui/stack-probes.rs
+++ b/src/test/ui/abi/stack-probes.rs
diff --git a/src/test/ui/statics/static-mut-foreign.rs b/src/test/ui/abi/statics/static-mut-foreign.rs
index 5d6fa416b98..5d6fa416b98 100644
--- a/src/test/ui/statics/static-mut-foreign.rs
+++ b/src/test/ui/abi/statics/static-mut-foreign.rs
diff --git a/src/test/ui/structs-enums/struct-return.rs b/src/test/ui/abi/struct-enums/struct-return.rs
index 5930fc4acbb..5930fc4acbb 100644
--- a/src/test/ui/structs-enums/struct-return.rs
+++ b/src/test/ui/abi/struct-enums/struct-return.rs
diff --git a/src/test/ui/union/union-c-interop.rs b/src/test/ui/abi/union/union-c-interop.rs
index 00f04d5b7ff..00f04d5b7ff 100644
--- a/src/test/ui/union/union-c-interop.rs
+++ b/src/test/ui/abi/union/union-c-interop.rs
diff --git a/src/test/ui/variadic-ffi.rs b/src/test/ui/abi/variadic-ffi.rs
index 3232a11d726..3232a11d726 100644
--- a/src/test/ui/variadic-ffi.rs
+++ b/src/test/ui/abi/variadic-ffi.rs
diff --git a/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs b/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs
index 06dfe490b8b..7e05bcd309a 100644
--- a/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs
+++ b/src/test/ui/associated-type/associated-type-projection-from-supertrait.rs
@@ -12,30 +12,22 @@ pub trait Car : Vehicle {
     fn chip_paint(&self, c: Self::Color) { }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct Black;
 struct ModelT;
 impl Vehicle for ModelT { type Color = Black; }
 impl Car for ModelT { }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct Blue;
 struct ModelU;
 impl Vehicle for ModelU { type Color = Blue; }
 impl Car for ModelU { }
 
-///////////////////////////////////////////////////////////////////////////
-
 fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
 fn a() { dent(ModelT, Black); }
 fn b() { dent(ModelT, Blue); } //~ ERROR mismatched types
 fn c() { dent(ModelU, Black); } //~ ERROR mismatched types
 fn d() { dent(ModelU, Blue); }
 
-///////////////////////////////////////////////////////////////////////////
-
 fn e() { ModelT.chip_paint(Black); }
 fn f() { ModelT.chip_paint(Blue); } //~ ERROR mismatched types
 fn g() { ModelU.chip_paint(Black); } //~ ERROR mismatched types
diff --git a/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr b/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr
index 06f1a1cc64c..4ba4925ef1b 100644
--- a/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr
+++ b/src/test/ui/associated-type/associated-type-projection-from-supertrait.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/associated-type-projection-from-supertrait.rs:33:23
+  --> $DIR/associated-type-projection-from-supertrait.rs:27:23
    |
 LL | fn b() { dent(ModelT, Blue); }
    |                       ^^^^ expected struct `Black`, found struct `Blue`
@@ -8,7 +8,7 @@ LL | fn b() { dent(ModelT, Blue); }
               found type `Blue`
 
 error[E0308]: mismatched types
-  --> $DIR/associated-type-projection-from-supertrait.rs:34:23
+  --> $DIR/associated-type-projection-from-supertrait.rs:28:23
    |
 LL | fn c() { dent(ModelU, Black); }
    |                       ^^^^^ expected struct `Blue`, found struct `Black`
@@ -17,7 +17,7 @@ LL | fn c() { dent(ModelU, Black); }
               found type `Black`
 
 error[E0308]: mismatched types
-  --> $DIR/associated-type-projection-from-supertrait.rs:40:28
+  --> $DIR/associated-type-projection-from-supertrait.rs:32:28
    |
 LL | fn f() { ModelT.chip_paint(Blue); }
    |                            ^^^^ expected struct `Black`, found struct `Blue`
@@ -26,7 +26,7 @@ LL | fn f() { ModelT.chip_paint(Blue); }
               found type `Blue`
 
 error[E0308]: mismatched types
-  --> $DIR/associated-type-projection-from-supertrait.rs:41:28
+  --> $DIR/associated-type-projection-from-supertrait.rs:33:28
    |
 LL | fn g() { ModelU.chip_paint(Black); }
    |                            ^^^^^ expected struct `Blue`, found struct `Black`
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
index 653130843c8..6b2bbbe2e4f 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.rs
@@ -11,22 +11,16 @@ pub trait Car : Vehicle {
     fn honk(&self) { }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct Black;
 struct ModelT;
 impl Vehicle for ModelT { type Color = Black; }
 impl Car for ModelT { }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct Blue;
 struct ModelU;
 impl Vehicle for ModelU { type Color = Blue; }
 impl Car for ModelU { }
 
-///////////////////////////////////////////////////////////////////////////
-
 fn black_car<C:Car<Color=Black>>(c: C) {
 }
 
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
index 4b548604983..89c48d50cdb 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:37:10
+  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
    |
 LL | fn b() { blue_car(ModelT); }
    |          ^^^^^^^^ expected struct `Black`, found struct `Blue`
@@ -7,13 +7,13 @@ LL | fn b() { blue_car(ModelT); }
    = note: expected type `Black`
               found type `Blue`
 note: required by `blue_car`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:33:1
+  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:27:1
    |
 LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:38:10
+  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
    |
 LL | fn c() { black_car(ModelU); }
    |          ^^^^^^^^^ expected struct `Blue`, found struct `Black`
@@ -21,7 +21,7 @@ LL | fn c() { black_car(ModelU); }
    = note: expected type `Blue`
               found type `Black`
 note: required by `black_car`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:30:1
+  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:24:1
    |
 LL | fn black_car<C:Car<Color=Black>>(c: C) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/associated-types/associated-types-ref-from-struct.rs b/src/test/ui/associated-types/associated-types-ref-from-struct.rs
index 3ccba289e4b..c89f6046e6b 100644
--- a/src/test/ui/associated-types/associated-types-ref-from-struct.rs
+++ b/src/test/ui/associated-types/associated-types-ref-from-struct.rs
@@ -9,8 +9,6 @@ trait Test {
     fn test(&self, value: &Self::V) -> bool;
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct TesterPair<T:Test> {
     tester: T,
     value: T::V,
@@ -26,8 +24,6 @@ impl<T:Test> TesterPair<T> {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct EqU32(u32);
 impl Test for EqU32 {
     type V = u32;
diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
index fab5892dae1..64fd1a4a78d 100644
--- a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     ) -> &dyn Foo
    |          ^^^^^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#27r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#22r
 
 error: lifetime may not live long enough
   --> $DIR/issue-63388-1.rs:15:5
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.rs b/src/test/ui/async-await/suggest-switching-edition-on-await.rs
new file mode 100644
index 00000000000..1402f1ca92b
--- /dev/null
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await.rs
@@ -0,0 +1,45 @@
+use std::pin::Pin;
+use std::future::Future;
+
+fn main() {}
+
+fn await_on_struct_missing() {
+    struct S;
+    let x = S;
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE unknown field
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_struct_similar() {
+    struct S {
+        awai: u8,
+    }
+    let x = S { awai: 42 };
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| HELP a field with a similar name exists
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE unknown field
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
+
+fn await_on_apit(x: impl Future<Output = ()>) {
+    x.await;
+    //~^ ERROR no field `await` on type
+    //~| NOTE to `.await` a `Future`, switch to Rust 2018
+    //~| HELP set `edition = "2018"` in `Cargo.toml`
+    //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
+}
diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
new file mode 100644
index 00000000000..f623511c0eb
--- /dev/null
+++ b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr
@@ -0,0 +1,43 @@
+error[E0609]: no field `await` on type `await_on_struct_missing::S`
+  --> $DIR/suggest-switching-edition-on-await.rs:9:7
+   |
+LL |     x.await;
+   |       ^^^^^ unknown field
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `await_on_struct_similar::S`
+  --> $DIR/suggest-switching-edition-on-await.rs:22:7
+   |
+LL |     x.await;
+   |       ^^^^^ help: a field with a similar name exists: `awai`
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `std::pin::Pin<&mut dyn std::future::Future<Output = ()>>`
+  --> $DIR/suggest-switching-edition-on-await.rs:31:7
+   |
+LL |     x.await;
+   |       ^^^^^ unknown field
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error[E0609]: no field `await` on type `impl Future<Output = ()>`
+  --> $DIR/suggest-switching-edition-on-await.rs:40:7
+   |
+LL |     x.await;
+   |       ^^^^^
+   |
+   = note: to `.await` a `Future`, switch to Rust 2018
+   = help: set `edition = "2018"` in `Cargo.toml`
+   = note: for more on editions, read https://doc.rust-lang.org/edition-guide
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs
index 431ff356ade..9edae1965ce 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.rs
+++ b/src/test/ui/consts/const-eval/ub-nonnull.rs
@@ -1,5 +1,5 @@
 #![feature(rustc_attrs, const_transmute)]
-#![allow(const_err)] // make sure we cannot allow away the errors tested here
+#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here
 
 use std::mem;
 use std::ptr::NonNull;
diff --git a/src/test/ui/consts/const-eval/ub-ref.rs b/src/test/ui/consts/const-eval/ub-ref.rs
index 0d8f30159b3..bbab85c2121 100644
--- a/src/test/ui/consts/const-eval/ub-ref.rs
+++ b/src/test/ui/consts/const-eval/ub-ref.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 #![feature(const_transmute)]
-#![allow(const_err)] // make sure we cannot allow away the errors tested here
+#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here
 
 use std::mem;
 
diff --git a/src/test/ui/consts/const-eval/ub-upvars.rs b/src/test/ui/consts/const-eval/ub-upvars.rs
index 0a427cd8857..baab14dc161 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.rs
+++ b/src/test/ui/consts/const-eval/ub-upvars.rs
@@ -1,5 +1,5 @@
 #![feature(const_transmute)]
-#![allow(const_err)] // make sure we cannot allow away the errors tested here
+#![allow(const_err, invalid_value)] // make sure we cannot allow away the errors tested here
 
 use std::mem;
 
diff --git a/src/test/ui/derives/derive-hygiene.rs b/src/test/ui/derives/derive-hygiene.rs
new file mode 100644
index 00000000000..4fa83c49038
--- /dev/null
+++ b/src/test/ui/derives/derive-hygiene.rs
@@ -0,0 +1,121 @@
+// Make sure that built-in derives don't rely on the user not declaring certain
+// names to work properly.
+
+// check-pass
+
+#![allow(nonstandard_style)]
+#![feature(decl_macro)]
+
+use std::prelude::v1::test as inline;
+
+static f: () = ();
+static cmp: () = ();
+static other: () = ();
+static state: () = ();
+static __self_0_0: () = ();
+static __self_1_0: () = ();
+static __self_vi: () = ();
+static __arg_1_0: () = ();
+static debug_trait_builder: () = ();
+
+struct isize;
+trait i16 {}
+
+trait MethodsInDerives: Sized {
+    fn debug_tuple(self) {}
+    fn debug_struct(self) {}
+    fn field(self) {}
+    fn finish(self) {}
+    fn clone(self) {}
+    fn cmp(self) {}
+    fn partial_cmp(self) {}
+    fn eq(self) {}
+    fn ne(self) {}
+    fn le(self) {}
+    fn lt(self) {}
+    fn ge(self) {}
+    fn gt(self) {}
+    fn hash(self) {}
+}
+
+trait GenericAny<T, U> {}
+impl<S, T, U> GenericAny<T, U> for S {}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum __H { V(i32), }
+
+#[repr(i16)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum W { A, B }
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+struct X<A: GenericAny<A, self::X<i32>>> {
+    A: A,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+struct Y<B>(B)
+where
+    B: From<B>;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+enum Z<C> {
+    C(C),
+    B { C: C },
+}
+
+// Make sure that we aren't using `self::` in paths, since it doesn't work in
+// non-module scopes.
+const NON_MODULE: () = {
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum __H { V(i32), }
+
+    #[repr(i16)]
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum W { A, B }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct X<A: Fn(A) -> self::X<i32>> {
+        A: A,
+    }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct Y<B>(B)
+    where
+        B: From<B>;
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum Z<C> {
+        C(C),
+        B { C: C },
+    }
+};
+
+macro m() {
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum __H { V(i32), }
+
+    #[repr(i16)]
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum W { A, B }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct X<A: GenericAny<A, self::X<i32>>> {
+        A: A,
+    }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)]
+    struct Y<B>(B)
+    where
+        B: From<B>;
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+    enum Z<C> {
+        C(C),
+        B { C: C },
+    }
+}
+
+m!();
+
+fn main() {}
diff --git a/src/test/ui/dropck/dropck_trait_cycle_checked.stderr b/src/test/ui/dropck/dropck_trait_cycle_checked.stderr
index 1e779208e58..dc3fbed593b 100644
--- a/src/test/ui/dropck/dropck_trait_cycle_checked.stderr
+++ b/src/test/ui/dropck/dropck_trait_cycle_checked.stderr
@@ -2,7 +2,7 @@ error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:111:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                               -------- cast requires that `o2` is borrowed for `'static`
+   |                                                                     -------- cast requires that `o2` is borrowed for `'static`
 LL |     o1.set0(&o2);
    |             ^^^ borrowed value does not live long enough
 ...
@@ -13,7 +13,7 @@ error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:112:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                                         -------- cast requires that `o3` is borrowed for `'static`
+   |                                                                     -------- cast requires that `o3` is borrowed for `'static`
 LL |     o1.set0(&o2);
 LL |     o1.set1(&o3);
    |             ^^^ borrowed value does not live long enough
@@ -37,7 +37,7 @@ error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:114:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                                         -------- cast requires that `o3` is borrowed for `'static`
+   |                                                                               -------- cast requires that `o3` is borrowed for `'static`
 ...
 LL |     o2.set1(&o3);
    |             ^^^ borrowed value does not live long enough
@@ -49,7 +49,7 @@ error[E0597]: `o1` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:115:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                     -------- cast requires that `o1` is borrowed for `'static`
+   |                                                                                         -------- cast requires that `o1` is borrowed for `'static`
 ...
 LL |     o3.set0(&o1);
    |             ^^^ borrowed value does not live long enough
@@ -61,7 +61,7 @@ error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:116:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                               -------- cast requires that `o2` is borrowed for `'static`
+   |                                                                                         -------- cast requires that `o2` is borrowed for `'static`
 ...
 LL |     o3.set1(&o2);
    |             ^^^ borrowed value does not live long enough
diff --git a/src/test/ui/duplicate/duplicate-type-parameter.stderr b/src/test/ui/duplicate/duplicate-type-parameter.stderr
index 8606479ff68..6754574f0b9 100644
--- a/src/test/ui/duplicate/duplicate-type-parameter.stderr
+++ b/src/test/ui/duplicate/duplicate-type-parameter.stderr
@@ -1,4 +1,4 @@
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:1:12
    |
 LL | type Foo<T,T> = Option<T>;
@@ -6,7 +6,7 @@ LL | type Foo<T,T> = Option<T>;
    |          |
    |          first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:4:14
    |
 LL | struct Bar<T,T>(T);
@@ -14,7 +14,7 @@ LL | struct Bar<T,T>(T);
    |            |
    |            first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:7:14
    |
 LL | struct Baz<T,T> {
@@ -22,7 +22,7 @@ LL | struct Baz<T,T> {
    |            |
    |            first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:12:12
    |
 LL | enum Boo<T,T> {
@@ -30,7 +30,7 @@ LL | enum Boo<T,T> {
    |          |
    |          first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:18:11
    |
 LL | fn quux<T,T>(x: T) {}
@@ -38,7 +38,7 @@ LL | fn quux<T,T>(x: T) {}
    |         |
    |         first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:21:13
    |
 LL | trait Qux<T,T> {}
@@ -46,7 +46,7 @@ LL | trait Qux<T,T> {}
    |           |
    |           first use of `T`
 
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/duplicate-type-parameter.rs:24:8
    |
 LL | impl<T,T> Qux<T,T> for Option<T> {}
diff --git a/src/test/ui/error-codes/E0194.rs b/src/test/ui/error-codes/E0194.rs
index 71eff0e7465..8a43f38fcfd 100644
--- a/src/test/ui/error-codes/E0194.rs
+++ b/src/test/ui/error-codes/E0194.rs
@@ -1,7 +1,7 @@
 trait Foo<T> {
     fn do_something(&self) -> T;
     fn do_something_else<T: Clone>(&self, bar: T);
-    //~^ ERROR E0194
+    //~^ ERROR E0403
 }
 
 fn main() {
diff --git a/src/test/ui/error-codes/E0194.stderr b/src/test/ui/error-codes/E0194.stderr
index ab4918a4e27..f2c908eea0b 100644
--- a/src/test/ui/error-codes/E0194.stderr
+++ b/src/test/ui/error-codes/E0194.stderr
@@ -1,12 +1,12 @@
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/E0194.rs:3:26
    |
 LL | trait Foo<T> {
-   |           - first `T` declared here
+   |           - first use of `T`
 LL |     fn do_something(&self) -> T;
 LL |     fn do_something_else<T: Clone>(&self, bar: T);
-   |                          ^ shadows another type parameter
+   |                          ^ already used
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0194`.
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/error-codes/E0403.stderr b/src/test/ui/error-codes/E0403.stderr
index 2bd7de6c246..d76a58a7c80 100644
--- a/src/test/ui/error-codes/E0403.stderr
+++ b/src/test/ui/error-codes/E0403.stderr
@@ -1,4 +1,4 @@
-error[E0403]: the name `T` is already used for a generic parameter in this list of generic parameters
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/E0403.rs:1:11
    |
 LL | fn foo<T, T>(s: T, u: T) {}
diff --git a/src/test/ui/feature-gate/feature-gate-or_patterns.rs b/src/test/ui/feature-gate/feature-gate-or_patterns.rs
new file mode 100644
index 00000000000..036a6095965
--- /dev/null
+++ b/src/test/ui/feature-gate/feature-gate-or_patterns.rs
@@ -0,0 +1,9 @@
+#![crate_type="lib"]
+
+pub fn example(x: Option<usize>) {
+    match x {
+        Some(0 | 1 | 2) => {}
+        //~^ ERROR: or-patterns syntax is experimental
+        _ => {}
+    }
+}
diff --git a/src/test/ui/feature-gate/feature-gate-or_patterns.stderr b/src/test/ui/feature-gate/feature-gate-or_patterns.stderr
new file mode 100644
index 00000000000..aaabb54c1f0
--- /dev/null
+++ b/src/test/ui/feature-gate/feature-gate-or_patterns.stderr
@@ -0,0 +1,12 @@
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:5:14
+   |
+LL |         Some(0 | 1 | 2) => {}
+   |              ^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-generators.rs b/src/test/ui/feature-gates/feature-gate-generators.rs
index cee930fd785..382d891feed 100644
--- a/src/test/ui/feature-gates/feature-gate-generators.rs
+++ b/src/test/ui/feature-gates/feature-gate-generators.rs
@@ -2,3 +2,9 @@ fn main() {
     yield true; //~ ERROR yield syntax is experimental
                 //~^ ERROR yield statement outside of generator literal
 }
+
+#[cfg(FALSE)]
+fn foo() {
+    yield; //~ ERROR yield syntax is experimental
+    yield 0; //~ ERROR yield syntax is experimental
+}
diff --git a/src/test/ui/feature-gates/feature-gate-generators.stderr b/src/test/ui/feature-gates/feature-gate-generators.stderr
index cdb05601254..24b814b410c 100644
--- a/src/test/ui/feature-gates/feature-gate-generators.stderr
+++ b/src/test/ui/feature-gates/feature-gate-generators.stderr
@@ -7,12 +7,30 @@ LL |     yield true;
    = note: for more information, see https://github.com/rust-lang/rust/issues/43122
    = help: add `#![feature(generators)]` to the crate attributes to enable
 
+error[E0658]: yield syntax is experimental
+  --> $DIR/feature-gate-generators.rs:8:5
+   |
+LL |     yield;
+   |     ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/43122
+   = help: add `#![feature(generators)]` to the crate attributes to enable
+
+error[E0658]: yield syntax is experimental
+  --> $DIR/feature-gate-generators.rs:9:5
+   |
+LL |     yield 0;
+   |     ^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/43122
+   = help: add `#![feature(generators)]` to the crate attributes to enable
+
 error[E0627]: yield statement outside of generator literal
   --> $DIR/feature-gate-generators.rs:2:5
    |
 LL |     yield true;
    |     ^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
index 478bc09f291..676b8b9f056 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
+++ b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
@@ -4,17 +4,17 @@ error: cannot find macro `__build_diagnostic_array!` in this scope
 LL | __build_diagnostic_array!(DIAGNOSTICS);
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: cannot find macro `__register_diagnostic!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1
-   |
-LL | __register_diagnostic!(E0001);
-   | ^^^^^^^^^^^^^^^^^^^^^
-
 error: cannot find macro `__diagnostic_used!` in this scope
   --> $DIR/feature-gate-rustc-diagnostic-macros.rs:8:5
    |
 LL |     __diagnostic_used!(E0001);
    |     ^^^^^^^^^^^^^^^^^
 
+error: cannot find macro `__register_diagnostic!` in this scope
+  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1
+   |
+LL | __register_diagnostic!(E0001);
+   | ^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
index a8f38180cc2..88d396101db 100644
--- a/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
+++ b/src/test/ui/higher-rank-trait-bounds/hrtb-type-outlives.rs
@@ -14,7 +14,6 @@ fn want_foo<T>()
 {
 }
 
-///////////////////////////////////////////////////////////////////////////
 // Expressed as a where clause
 
 struct SomeStruct<X> {
@@ -30,7 +29,6 @@ fn one() {
     want_foo::<SomeStruct<usize>>();
 }
 
-///////////////////////////////////////////////////////////////////////////
 // Expressed as shorthand
 
 struct AnotherStruct<X> {
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.rs b/src/test/ui/hrtb/hrtb-conflate-regions.rs
index 391303676d7..004d62ac513 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.rs
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.rs
@@ -15,7 +15,6 @@ fn want_foo1<T>()
 {
 }
 
-///////////////////////////////////////////////////////////////////////////
 // Expressed as a where clause
 
 struct SomeStruct;
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index 3fb6baa35e1..20265d66c6f 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
-  --> $DIR/hrtb-conflate-regions.rs:28:10
+  --> $DIR/hrtb-conflate-regions.rs:27:10
    |
 LL | fn b() { want_foo2::<SomeStruct>(); }
    |          ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
diff --git a/src/test/ui/hygiene/auxiliary/codegen-attrs.rs b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
new file mode 100644
index 00000000000..74afedbeb77
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
@@ -0,0 +1,10 @@
+#![feature(decl_macro)]
+
+macro m($f:ident) {
+    #[export_name = "export_function_name"]
+    pub fn $f() -> i32 {
+        2
+    }
+}
+
+m!(rust_function_name);
diff --git a/src/test/ui/hygiene/cross-crate-codegen-attrs.rs b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs
new file mode 100644
index 00000000000..af6b1334387
--- /dev/null
+++ b/src/test/ui/hygiene/cross-crate-codegen-attrs.rs
@@ -0,0 +1,12 @@
+// Make sure that macro expanded codegen attributes work across crates.
+// We used to gensym the identifiers in attributes, which stopped dependent
+// crates from seeing them, resulting in linker errors in cases like this one.
+
+// run-pass
+// aux-build:codegen-attrs.rs
+
+extern crate codegen_attrs;
+
+fn main() {
+    assert_eq!(codegen_attrs::rust_function_name(), 2);
+}
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index a89176fe690..643f803f620 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -1,3 +1,11 @@
+error: cannot find macro `panic!` in this scope
+  --> $DIR/no_implicit_prelude.rs:16:9
+   |
+LL |         assert_eq!(0, 0);
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
 error[E0433]: failed to resolve: use of undeclared type or module `Vec`
   --> $DIR/no_implicit_prelude.rs:11:9
    |
@@ -7,14 +15,6 @@ LL |     fn f() { ::bar::m!(); }
 LL |         Vec::new();
    |         ^^^ use of undeclared type or module `Vec`
 
-error: cannot find macro `panic!` in this scope
-  --> $DIR/no_implicit_prelude.rs:16:9
-   |
-LL |         assert_eq!(0, 0);
-   |         ^^^^^^^^^^^^^^^^^
-   |
-   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
-
 error[E0599]: no method named `clone` found for type `()` in the current scope
   --> $DIR/no_implicit_prelude.rs:12:12
    |
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs
index 9ba7c91fc72..ce1550568c1 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.rs
+++ b/src/test/ui/impl-trait/bound-normalization-fail.rs
@@ -8,7 +8,6 @@
 
 // See issue 60414
 
-/////////////////////////////////////////////
 // Reduction to `impl Trait`
 
 struct Foo<T>(T);
@@ -33,7 +32,6 @@ mod impl_trait {
     }
 }
 
-/////////////////////////////////////////////
 // Same with lifetimes in the trait
 
 mod lifetimes {
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index b5c8e078f0f..4811b1e0ff3 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:30:32
+  --> $DIR/bound-normalization-fail.rs:29:32
    |
 LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
@@ -17,13 +17,13 @@ LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    = note: the return type of a function must have a statically known size
 
 error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/bound-normalization-fail.rs:47:41
+  --> $DIR/bound-normalization-fail.rs:45:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:47:41
+  --> $DIR/bound-normalization-fail.rs:45:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
diff --git a/src/test/ui/impl-trait/bound-normalization-pass.rs b/src/test/ui/impl-trait/bound-normalization-pass.rs
index 5b634e3106e..b0ed4be54b8 100644
--- a/src/test/ui/impl-trait/bound-normalization-pass.rs
+++ b/src/test/ui/impl-trait/bound-normalization-pass.rs
@@ -8,7 +8,6 @@
 
 // See issue 60414
 
-/////////////////////////////////////////////
 // Reduction to `impl Trait`
 
 struct Foo<T>(T);
@@ -32,7 +31,6 @@ mod impl_trait {
     }
 }
 
-/////////////////////////////////////////////
 // Same with lifetimes in the trait
 
 mod lifetimes {
@@ -59,7 +57,6 @@ mod lifetimes {
     }
 }
 
-/////////////////////////////////////////////
 // Reduction using `impl Trait` in bindings
 
 mod impl_trait_in_bindings {
@@ -80,7 +77,6 @@ mod impl_trait_in_bindings {
     }
 }
 
-/////////////////////////////////////////////
 // The same applied to `type Foo = impl Bar`s
 
 mod opaque_types {
diff --git a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
index 5afdd8889ae..7d013828bd9 100644
--- a/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
+++ b/src/test/ui/imports/local-modularized-tricky-fail-1.stderr
@@ -21,25 +21,6 @@ LL | use inner1::*;
    |     ^^^^^^^^^
    = help: consider adding an explicit import of `exported` to disambiguate
 
-error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/local-modularized-tricky-fail-1.rs:46:1
-   |
-LL | include!();
-   | ^^^^^^^ ambiguous name
-   |
-   = note: `include` could refer to a macro from prelude
-note: `include` could also refer to the macro defined here
-  --> $DIR/local-modularized-tricky-fail-1.rs:17:5
-   |
-LL | /     macro_rules! include {
-LL | |         () => ()
-LL | |     }
-   | |_____^
-...
-LL |       define_include!();
-   |       ------------------ in this macro invocation
-   = help: use `crate::include` to refer to this macro unambiguously
-
 error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/local-modularized-tricky-fail-1.rs:35:5
    |
@@ -59,6 +40,25 @@ LL |       define_panic!();
    |       ---------------- in this macro invocation
    = help: use `crate::panic` to refer to this macro unambiguously
 
+error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
+  --> $DIR/local-modularized-tricky-fail-1.rs:46:1
+   |
+LL | include!();
+   | ^^^^^^^ ambiguous name
+   |
+   = note: `include` could refer to a macro from prelude
+note: `include` could also refer to the macro defined here
+  --> $DIR/local-modularized-tricky-fail-1.rs:17:5
+   |
+LL | /     macro_rules! include {
+LL | |         () => ()
+LL | |     }
+   | |_____^
+...
+LL |       define_include!();
+   |       ------------------ in this macro invocation
+   = help: use `crate::include` to refer to this macro unambiguously
+
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr
index c84226ef313..2f2ab20cdf0 100644
--- a/src/test/ui/imports/shadow_builtin_macros.stderr
+++ b/src/test/ui/imports/shadow_builtin_macros.stderr
@@ -14,20 +14,6 @@ LL |     use foo::*;
    = help: or use `self::panic` to refer to this macro unambiguously
 
 error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/shadow_builtin_macros.rs:20:14
-   |
-LL |     fn f() { panic!(); }
-   |              ^^^^^ ambiguous name
-   |
-   = note: `panic` could refer to a macro from prelude
-note: `panic` could also refer to the macro imported here
-  --> $DIR/shadow_builtin_macros.rs:19:26
-   |
-LL |     ::two_macros::m!(use foo::panic;);
-   |                          ^^^^^^^^^^
-   = help: use `self::panic` to refer to this macro unambiguously
-
-error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
   --> $DIR/shadow_builtin_macros.rs:33:5
    |
 LL |     panic!();
@@ -62,6 +48,20 @@ note: `n` could also refer to the macro imported here
 LL | #[macro_use(n)]
    |             ^
 
+error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
+  --> $DIR/shadow_builtin_macros.rs:20:14
+   |
+LL |     fn f() { panic!(); }
+   |              ^^^^^ ambiguous name
+   |
+   = note: `panic` could refer to a macro from prelude
+note: `panic` could also refer to the macro imported here
+  --> $DIR/shadow_builtin_macros.rs:19:26
+   |
+LL |     ::two_macros::m!(use foo::panic;);
+   |                          ^^^^^^^^^^
+   = help: use `self::panic` to refer to this macro unambiguously
+
 error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/include-macros/data.bin b/src/test/ui/include-macros/data.bin
new file mode 100644
index 00000000000..ce4e0b8311a
--- /dev/null
+++ b/src/test/ui/include-macros/data.bin
@@ -0,0 +1,2 @@
+This file starts with BOM.

+Lines are separated by \r\n.

diff --git a/src/test/ui/include-macros/normalization.rs b/src/test/ui/include-macros/normalization.rs
new file mode 100644
index 00000000000..889f08e606e
--- /dev/null
+++ b/src/test/ui/include-macros/normalization.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+fn main() {
+    assert_eq!(
+        &include_bytes!("data.bin")[..],
+        &b"\xEF\xBB\xBFThis file starts with BOM.\r\nLines are separated by \\r\\n.\r\n"[..],
+    );
+    assert_eq!(
+        include_str!("data.bin"),
+        "\u{FEFF}This file starts with BOM.\r\nLines are separated by \\r\\n.\r\n",
+    );
+}
diff --git a/src/test/ui/issues/issue-12028.rs b/src/test/ui/issues/issue-12028.rs
index d55354529a9..7c2b0d69c8b 100644
--- a/src/test/ui/issues/issue-12028.rs
+++ b/src/test/ui/issues/issue-12028.rs
@@ -17,8 +17,6 @@ trait StreamHasher {
     fn stream(&self) -> Self::S;
 }
 
-//////////////////////////////////////////////////////////////////////////////
-
 trait StreamHash<H: StreamHasher>: Hash<H> {
     fn input_stream(&self, stream: &mut H::S);
 }
diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr
index 64694c7a8d0..24aa88c3fa3 100644
--- a/src/test/ui/issues/issue-12028.stderr
+++ b/src/test/ui/issues/issue-12028.stderr
@@ -1,5 +1,5 @@
 error[E0284]: type annotations required: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
-  --> $DIR/issue-12028.rs:29:14
+  --> $DIR/issue-12028.rs:27:14
    |
 LL |         self.input_stream(&mut stream);
    |              ^^^^^^^^^^^^
diff --git a/src/test/ui/issues/issue-16739.rs b/src/test/ui/issues/issue-16739.rs
index 54ad8fd076e..94da2ca5cab 100644
--- a/src/test/ui/issues/issue-16739.rs
+++ b/src/test/ui/issues/issue-16739.rs
@@ -16,8 +16,6 @@ impl FnOnce<()> for Foo {
     extern "rust-call" fn call_once(mut self, _: ()) -> u32 { self.call_mut(()) }
 }
 
-/////////////////////////////////////////////////////////////////////////
-
 impl FnMut<(u32,)> for Foo {
     extern "rust-call" fn call_mut(&mut self, (x,): (u32,)) -> u32 { self.foo + x }
 }
@@ -27,8 +25,6 @@ impl FnOnce<(u32,)> for Foo {
     extern "rust-call" fn call_once(mut self, args: (u32,)) -> u32 { self.call_mut(args) }
 }
 
-/////////////////////////////////////////////////////////////////////////
-
 impl FnMut<(u32,u32)> for Foo {
     extern "rust-call" fn call_mut(&mut self, (x, y): (u32, u32)) -> u32 { self.foo + x + y }
 }
diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr
index c557255ab50..e0d3bb3ecc2 100644
--- a/src/test/ui/issues/issue-49074.stderr
+++ b/src/test/ui/issues/issue-49074.stderr
@@ -1,9 +1,3 @@
-error: cannot find attribute macro `marco_use` in this scope
-  --> $DIR/issue-49074.rs:3:3
-   |
-LL | #[marco_use] // typo
-   |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
-
 error: cannot find macro `bar!` in this scope
   --> $DIR/issue-49074.rs:12:4
    |
@@ -12,5 +6,11 @@ LL |    bar!();
    |
    = help: have you added the `#[macro_use]` on the module/import?
 
+error: cannot find attribute macro `marco_use` in this scope
+  --> $DIR/issue-49074.rs:3:3
+   |
+LL | #[marco_use] // typo
+   |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `macro_use`
+
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs
index d816479bbbb..5cf62b86912 100644
--- a/src/test/ui/lint/uninitialized-zeroed.rs
+++ b/src/test/ui/lint/uninitialized-zeroed.rs
@@ -2,11 +2,13 @@
 // This test checks that calling `mem::{uninitialized,zeroed}` with certain types results
 // in a lint.
 
-#![feature(never_type)]
+#![feature(never_type, rustc_attrs)]
 #![allow(deprecated)]
 #![deny(invalid_value)]
 
 use std::mem::{self, MaybeUninit};
+use std::ptr::NonNull;
+use std::num::NonZeroU32;
 
 enum Void {}
 
@@ -16,6 +18,11 @@ struct RefPair((&'static i32, i32));
 struct Wrap<T> { wrapped: T }
 enum WrapEnum<T> { Wrapped(T) }
 
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(128)]
+#[repr(transparent)]
+pub(crate) struct NonBig(u64);
+
 #[allow(unused)]
 fn generic<T: 'static>() {
     unsafe {
@@ -29,6 +36,7 @@ fn generic<T: 'static>() {
 
 fn main() {
     unsafe {
+        // Things that cannot even be zero.
         let _val: ! = mem::zeroed(); //~ ERROR: does not permit zero-initialization
         let _val: ! = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
 
@@ -56,11 +64,28 @@ fn main() {
         let _val: Wrap<(RefPair, i32)> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
         let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
 
-        // Some types that should work just fine.
+        let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        // Things that can be zero, but not uninit.
+        let _val: bool = mem::zeroed();
+        let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: Wrap<char> = mem::zeroed();
+        let _val: Wrap<char> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        let _val: NonBig = mem::zeroed();
+        let _val: NonBig = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
+        // Transmute-from-0
+        let _val: &'static i32 = mem::transmute(0usize); //~ ERROR: does not permit zero-initialization
+        let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
+        let _val: NonZeroU32 = mem::transmute(0); //~ ERROR: does not permit zero-initialization
+
+        // Some more types that should work just fine.
         let _val: Option<&'static i32> = mem::zeroed();
         let _val: Option<fn()> = mem::zeroed();
         let _val: MaybeUninit<&'static i32> = mem::zeroed();
-        let _val: bool = mem::zeroed();
         let _val: i32 = mem::zeroed();
     }
 }
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
index 1b15fc21525..a36a32a39a1 100644
--- a/src/test/ui/lint/uninitialized-zeroed.stderr
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -1,5 +1,5 @@
 error: the type `&'static T` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:22:32
+  --> $DIR/uninitialized-zeroed.rs:29:32
    |
 LL |         let _val: &'static T = mem::zeroed();
    |                                ^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | #![deny(invalid_value)]
    = note: References must be non-null
 
 error: the type `&'static T` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:23:32
+  --> $DIR/uninitialized-zeroed.rs:30:32
    |
 LL |         let _val: &'static T = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |         let _val: &'static T = mem::uninitialized();
    = note: References must be non-null
 
 error: the type `Wrap<&'static T>` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:25:38
+  --> $DIR/uninitialized-zeroed.rs:32:38
    |
 LL |         let _val: Wrap<&'static T> = mem::zeroed();
    |                                      ^^^^^^^^^^^^^
@@ -35,13 +35,13 @@ LL |         let _val: Wrap<&'static T> = mem::zeroed();
    |                                      help: use `MaybeUninit<T>` instead
    |
 note: References must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:16:18
+  --> $DIR/uninitialized-zeroed.rs:18:18
    |
 LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `Wrap<&'static T>` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:26:38
+  --> $DIR/uninitialized-zeroed.rs:33:38
    |
 LL |         let _val: Wrap<&'static T> = mem::uninitialized();
    |                                      ^^^^^^^^^^^^^^^^^^^^
@@ -50,13 +50,13 @@ LL |         let _val: Wrap<&'static T> = mem::uninitialized();
    |                                      help: use `MaybeUninit<T>` instead
    |
 note: References must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:16:18
+  --> $DIR/uninitialized-zeroed.rs:18:18
    |
 LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `!` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:32:23
+  --> $DIR/uninitialized-zeroed.rs:40:23
    |
 LL |         let _val: ! = mem::zeroed();
    |                       ^^^^^^^^^^^^^
@@ -67,7 +67,7 @@ LL |         let _val: ! = mem::zeroed();
    = note: The never type (`!`) has no valid value
 
 error: the type `!` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:33:23
+  --> $DIR/uninitialized-zeroed.rs:41:23
    |
 LL |         let _val: ! = mem::uninitialized();
    |                       ^^^^^^^^^^^^^^^^^^^^
@@ -78,7 +78,7 @@ LL |         let _val: ! = mem::uninitialized();
    = note: The never type (`!`) has no valid value
 
 error: the type `(i32, !)` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:35:30
+  --> $DIR/uninitialized-zeroed.rs:43:30
    |
 LL |         let _val: (i32, !) = mem::zeroed();
    |                              ^^^^^^^^^^^^^
@@ -89,7 +89,7 @@ LL |         let _val: (i32, !) = mem::zeroed();
    = note: The never type (`!`) has no valid value
 
 error: the type `(i32, !)` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:36:30
+  --> $DIR/uninitialized-zeroed.rs:44:30
    |
 LL |         let _val: (i32, !) = mem::uninitialized();
    |                              ^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@ LL |         let _val: (i32, !) = mem::uninitialized();
    = note: The never type (`!`) has no valid value
 
 error: the type `Void` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:38:26
+  --> $DIR/uninitialized-zeroed.rs:46:26
    |
 LL |         let _val: Void = mem::zeroed();
    |                          ^^^^^^^^^^^^^
@@ -111,7 +111,7 @@ LL |         let _val: Void = mem::zeroed();
    = note: 0-variant enums have no valid value
 
 error: the type `Void` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:39:26
+  --> $DIR/uninitialized-zeroed.rs:47:26
    |
 LL |         let _val: Void = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
@@ -122,7 +122,7 @@ LL |         let _val: Void = mem::uninitialized();
    = note: 0-variant enums have no valid value
 
 error: the type `&'static i32` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:41:34
+  --> $DIR/uninitialized-zeroed.rs:49:34
    |
 LL |         let _val: &'static i32 = mem::zeroed();
    |                                  ^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL |         let _val: &'static i32 = mem::zeroed();
    = note: References must be non-null
 
 error: the type `&'static i32` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:42:34
+  --> $DIR/uninitialized-zeroed.rs:50:34
    |
 LL |         let _val: &'static i32 = mem::uninitialized();
    |                                  ^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL |         let _val: &'static i32 = mem::uninitialized();
    = note: References must be non-null
 
 error: the type `Ref` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:44:25
+  --> $DIR/uninitialized-zeroed.rs:52:25
    |
 LL |         let _val: Ref = mem::zeroed();
    |                         ^^^^^^^^^^^^^
@@ -153,13 +153,13 @@ LL |         let _val: Ref = mem::zeroed();
    |                         help: use `MaybeUninit<T>` instead
    |
 note: References must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:13:12
+  --> $DIR/uninitialized-zeroed.rs:15:12
    |
 LL | struct Ref(&'static i32);
    |            ^^^^^^^^^^^^
 
 error: the type `Ref` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:45:25
+  --> $DIR/uninitialized-zeroed.rs:53:25
    |
 LL |         let _val: Ref = mem::uninitialized();
    |                         ^^^^^^^^^^^^^^^^^^^^
@@ -168,13 +168,13 @@ LL |         let _val: Ref = mem::uninitialized();
    |                         help: use `MaybeUninit<T>` instead
    |
 note: References must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:13:12
+  --> $DIR/uninitialized-zeroed.rs:15:12
    |
 LL | struct Ref(&'static i32);
    |            ^^^^^^^^^^^^
 
 error: the type `fn()` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:47:26
+  --> $DIR/uninitialized-zeroed.rs:55:26
    |
 LL |         let _val: fn() = mem::zeroed();
    |                          ^^^^^^^^^^^^^
@@ -185,7 +185,7 @@ LL |         let _val: fn() = mem::zeroed();
    = note: Function pointers must be non-null
 
 error: the type `fn()` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:48:26
+  --> $DIR/uninitialized-zeroed.rs:56:26
    |
 LL |         let _val: fn() = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
@@ -196,7 +196,7 @@ LL |         let _val: fn() = mem::uninitialized();
    = note: Function pointers must be non-null
 
 error: the type `Wrap<fn()>` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:50:32
+  --> $DIR/uninitialized-zeroed.rs:58:32
    |
 LL |         let _val: Wrap<fn()> = mem::zeroed();
    |                                ^^^^^^^^^^^^^
@@ -205,13 +205,13 @@ LL |         let _val: Wrap<fn()> = mem::zeroed();
    |                                help: use `MaybeUninit<T>` instead
    |
 note: Function pointers must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:16:18
+  --> $DIR/uninitialized-zeroed.rs:18:18
    |
 LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `Wrap<fn()>` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:51:32
+  --> $DIR/uninitialized-zeroed.rs:59:32
    |
 LL |         let _val: Wrap<fn()> = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
@@ -220,13 +220,13 @@ LL |         let _val: Wrap<fn()> = mem::uninitialized();
    |                                help: use `MaybeUninit<T>` instead
    |
 note: Function pointers must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:16:18
+  --> $DIR/uninitialized-zeroed.rs:18:18
    |
 LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `WrapEnum<fn()>` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:53:36
+  --> $DIR/uninitialized-zeroed.rs:61:36
    |
 LL |         let _val: WrapEnum<fn()> = mem::zeroed();
    |                                    ^^^^^^^^^^^^^
@@ -235,13 +235,13 @@ LL |         let _val: WrapEnum<fn()> = mem::zeroed();
    |                                    help: use `MaybeUninit<T>` instead
    |
 note: Function pointers must be non-null (in this enum field)
-  --> $DIR/uninitialized-zeroed.rs:17:28
+  --> $DIR/uninitialized-zeroed.rs:19:28
    |
 LL | enum WrapEnum<T> { Wrapped(T) }
    |                            ^
 
 error: the type `WrapEnum<fn()>` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:54:36
+  --> $DIR/uninitialized-zeroed.rs:62:36
    |
 LL |         let _val: WrapEnum<fn()> = mem::uninitialized();
    |                                    ^^^^^^^^^^^^^^^^^^^^
@@ -250,13 +250,13 @@ LL |         let _val: WrapEnum<fn()> = mem::uninitialized();
    |                                    help: use `MaybeUninit<T>` instead
    |
 note: Function pointers must be non-null (in this enum field)
-  --> $DIR/uninitialized-zeroed.rs:17:28
+  --> $DIR/uninitialized-zeroed.rs:19:28
    |
 LL | enum WrapEnum<T> { Wrapped(T) }
    |                            ^
 
 error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:56:42
+  --> $DIR/uninitialized-zeroed.rs:64:42
    |
 LL |         let _val: Wrap<(RefPair, i32)> = mem::zeroed();
    |                                          ^^^^^^^^^^^^^
@@ -265,13 +265,13 @@ LL |         let _val: Wrap<(RefPair, i32)> = mem::zeroed();
    |                                          help: use `MaybeUninit<T>` instead
    |
 note: References must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:14:16
+  --> $DIR/uninitialized-zeroed.rs:16:16
    |
 LL | struct RefPair((&'static i32, i32));
    |                ^^^^^^^^^^^^^^^^^^^
 
 error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:57:42
+  --> $DIR/uninitialized-zeroed.rs:65:42
    |
 LL |         let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
    |                                          ^^^^^^^^^^^^^^^^^^^^
@@ -280,10 +280,102 @@ LL |         let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
    |                                          help: use `MaybeUninit<T>` instead
    |
 note: References must be non-null (in this struct field)
-  --> $DIR/uninitialized-zeroed.rs:14:16
+  --> $DIR/uninitialized-zeroed.rs:16:16
    |
 LL | struct RefPair((&'static i32, i32));
    |                ^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 22 previous errors
+error: the type `std::ptr::NonNull<i32>` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:67:34
+   |
+LL |         let _val: NonNull<i32> = mem::zeroed();
+   |                                  ^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead
+   |
+   = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `std::ptr::NonNull<i32>` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:68:34
+   |
+LL |         let _val: NonNull<i32> = mem::uninitialized();
+   |                                  ^^^^^^^^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead
+   |
+   = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `bool` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:72:26
+   |
+LL |         let _val: bool = mem::uninitialized();
+   |                          ^^^^^^^^^^^^^^^^^^^^
+   |                          |
+   |                          this code causes undefined behavior when executed
+   |                          help: use `MaybeUninit<T>` instead
+   |
+   = note: Booleans must be `true` or `false`
+
+error: the type `Wrap<char>` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:75:32
+   |
+LL |         let _val: Wrap<char> = mem::uninitialized();
+   |                                ^^^^^^^^^^^^^^^^^^^^
+   |                                |
+   |                                this code causes undefined behavior when executed
+   |                                help: use `MaybeUninit<T>` instead
+   |
+note: Characters must be a valid unicode codepoint (in this struct field)
+  --> $DIR/uninitialized-zeroed.rs:18:18
+   |
+LL | struct Wrap<T> { wrapped: T }
+   |                  ^^^^^^^^^^
+
+error: the type `NonBig` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:78:28
+   |
+LL |         let _val: NonBig = mem::uninitialized();
+   |                            ^^^^^^^^^^^^^^^^^^^^
+   |                            |
+   |                            this code causes undefined behavior when executed
+   |                            help: use `MaybeUninit<T>` instead
+   |
+   = note: NonBig must be initialized inside its custom valid range
+
+error: the type `&'static i32` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:81:34
+   |
+LL |         let _val: &'static i32 = mem::transmute(0usize);
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead
+   |
+   = note: References must be non-null
+
+error: the type `&'static [i32]` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:82:36
+   |
+LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                    |
+   |                                    this code causes undefined behavior when executed
+   |                                    help: use `MaybeUninit<T>` instead
+   |
+   = note: References must be non-null
+
+error: the type `std::num::NonZeroU32` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:83:32
+   |
+LL |         let _val: NonZeroU32 = mem::transmute(0);
+   |                                ^^^^^^^^^^^^^^^^^
+   |                                |
+   |                                this code causes undefined behavior when executed
+   |                                help: use `MaybeUninit<T>` instead
+   |
+   = note: std::num::NonZeroU32 must be non-null
+
+error: aborting due to 30 previous errors
 
diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr
index aee1b4c9c5d..250773a1853 100644
--- a/src/test/ui/macros/same-sequence-span.stderr
+++ b/src/test/ui/macros/same-sequence-span.stderr
@@ -18,7 +18,10 @@ error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fra
   --> $DIR/same-sequence-span.rs:20:1
    |
 LL | proc_macro_sequence::make_foo!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | not allowed after `expr` fragments
+   | in this macro invocation
    |
    = note: allowed there are: `=>`, `,` or `;`
 
@@ -26,7 +29,10 @@ error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragmen
   --> $DIR/same-sequence-span.rs:20:1
    |
 LL | proc_macro_sequence::make_foo!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | not allowed after `expr` fragments
+   | in this macro invocation
    |
    = note: allowed there are: `=>`, `,` or `;`
 
diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr
index 287f7b297d5..202a9235adb 100644
--- a/src/test/ui/macros/trace-macro.stderr
+++ b/src/test/ui/macros/trace-macro.stderr
@@ -5,5 +5,5 @@ LL |     println!("Hello, World!");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expanding `println! { "Hello, World!" }`
-   = note: to `{ $crate :: io :: _print (format_args_nl ! ("Hello, World!")) ; }`
+   = note: to `{ $crate :: io :: _print ($crate :: format_args_nl ! ("Hello, World!")) ; }`
 
diff --git a/src/test/ui/methods/method-projection.rs b/src/test/ui/methods/method-projection.rs
index cf33d53968b..21d983f192a 100644
--- a/src/test/ui/methods/method-projection.rs
+++ b/src/test/ui/methods/method-projection.rs
@@ -2,9 +2,6 @@
 // Test that we can use method notation to call methods based on a
 // projection bound from a trait. Issue #20469.
 
-///////////////////////////////////////////////////////////////////////////
-
-
 trait MakeString {
     fn make_string(&self) -> String;
 }
@@ -21,8 +18,6 @@ impl MakeString for usize {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 trait Foo {
     type F: MakeString;
 
@@ -33,8 +28,6 @@ fn foo<F:Foo>(f: &F) -> String {
     f.get().make_string()
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct SomeStruct {
     field: isize,
 }
@@ -47,8 +40,6 @@ impl Foo for SomeStruct {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct SomeOtherStruct {
     field: usize,
 }
diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs
index 7b972183099..f27caa5d78c 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.rs
+++ b/src/test/ui/parser/pat-lt-bracket-6.rs
@@ -2,8 +2,9 @@ fn main() {
     struct Test(&'static u8, [u8; 0]);
     let x = Test(&0, []);
 
-    let Test(&desc[..]) = x; //~ ERROR: expected one of `)`, `,`, or `@`, found `[`
-    //~^ ERROR subslice patterns are unstable
+    let Test(&desc[..]) = x;
+    //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
+    //~^^ ERROR subslice patterns are unstable
 }
 
 const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
index 201465b2c85..6f08f0a9d95 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -1,8 +1,8 @@
-error: expected one of `)`, `,`, or `@`, found `[`
+error: expected one of `)`, `,`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-6.rs:5:19
    |
 LL |     let Test(&desc[..]) = x;
-   |                   ^ expected one of `)`, `,`, or `@` here
+   |                   ^ expected one of `)`, `,`, `@`, or `|` here
 
 error[E0658]: subslice patterns are unstable
   --> $DIR/pat-lt-bracket-6.rs:5:20
@@ -14,7 +14,7 @@ LL |     let Test(&desc[..]) = x;
    = help: add `#![feature(slice_patterns)]` to the crate attributes to enable
 
 error[E0308]: mismatched types
-  --> $DIR/pat-lt-bracket-6.rs:9:30
+  --> $DIR/pat-lt-bracket-6.rs:10:30
    |
 LL | const RECOVERY_WITNESS: () = 0;
    |                              ^ expected (), found integer
diff --git a/src/test/ui/parser/pat-lt-bracket-7.rs b/src/test/ui/parser/pat-lt-bracket-7.rs
index 020fdb845e8..327aef5ad15 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.rs
+++ b/src/test/ui/parser/pat-lt-bracket-7.rs
@@ -2,7 +2,8 @@ fn main() {
     struct Thing(u8, [u8; 0]);
     let foo = core::iter::empty();
 
-    for Thing(x[]) in foo {} //~ ERROR: expected one of `)`, `,`, or `@`, found `[`
+    for Thing(x[]) in foo {}
+    //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
 }
 
 const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr
index 17557efa49e..196f1c0ae91 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-7.stderr
@@ -1,11 +1,11 @@
-error: expected one of `)`, `,`, or `@`, found `[`
+error: expected one of `)`, `,`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-7.rs:5:16
    |
 LL |     for Thing(x[]) in foo {}
-   |                ^ expected one of `)`, `,`, or `@` here
+   |                ^ expected one of `)`, `,`, `@`, or `|` here
 
 error[E0308]: mismatched types
-  --> $DIR/pat-lt-bracket-7.rs:8:30
+  --> $DIR/pat-lt-bracket-7.rs:9:30
    |
 LL | const RECOVERY_WITNESS: () = 0;
    |                              ^ expected (), found integer
diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.rs b/src/test/ui/parser/recover-for-loop-parens-around-head.rs
index e6c59fcf22d..c6be2c90667 100644
--- a/src/test/ui/parser/recover-for-loop-parens-around-head.rs
+++ b/src/test/ui/parser/recover-for-loop-parens-around-head.rs
@@ -8,7 +8,7 @@ fn main() {
     let vec = vec![1, 2, 3];
 
     for ( elem in vec ) {
-        //~^ ERROR expected one of `)`, `,`, or `@`, found `in`
+        //~^ ERROR expected one of `)`, `,`, `@`, or `|`, found `in`
         //~| ERROR unexpected closing `)`
         const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
     }
diff --git a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
index c160e646c28..1b5b6cca092 100644
--- a/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
+++ b/src/test/ui/parser/recover-for-loop-parens-around-head.stderr
@@ -1,8 +1,8 @@
-error: expected one of `)`, `,`, or `@`, found `in`
+error: expected one of `)`, `,`, `@`, or `|`, found `in`
   --> $DIR/recover-for-loop-parens-around-head.rs:10:16
    |
 LL |     for ( elem in vec ) {
-   |                ^^ expected one of `)`, `,`, or `@` here
+   |                ^^ expected one of `)`, `,`, `@`, or `|` here
 
 error: unexpected closing `)`
   --> $DIR/recover-for-loop-parens-around-head.rs:10:23
diff --git a/src/test/ui/proc-macro/auxiliary/gen-macro-rules.rs b/src/test/ui/proc-macro/auxiliary/gen-macro-rules.rs
new file mode 100644
index 00000000000..d4b67d6b0b0
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/gen-macro-rules.rs
@@ -0,0 +1,12 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(repro)]
+pub fn proc_macro_hack_expr(_input: TokenStream) -> TokenStream {
+    "macro_rules! m {()=>{}}".parse().unwrap()
+}
diff --git a/src/test/ui/proc-macro/gen-macro-rules.rs b/src/test/ui/proc-macro/gen-macro-rules.rs
new file mode 100644
index 00000000000..13ad27f9372
--- /dev/null
+++ b/src/test/ui/proc-macro/gen-macro-rules.rs
@@ -0,0 +1,13 @@
+// Derive macros can generate `macro_rules` items, regression test for issue #63651.
+
+// check-pass
+// aux-build:gen-macro-rules.rs
+
+extern crate gen_macro_rules as repro;
+
+#[derive(repro::repro)]
+pub struct S;
+
+m!(); // OK
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr
index 51bbb23da75..829d8bf4c81 100644
--- a/src/test/ui/proc-macro/generate-mod.stderr
+++ b/src/test/ui/proc-macro/generate-mod.stderr
@@ -2,13 +2,19 @@ error[E0412]: cannot find type `FromOutside` in this scope
   --> $DIR/generate-mod.rs:9:1
    |
 LL | generate_mod::check!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | not found in this scope
+   | in this macro invocation
 
 error[E0412]: cannot find type `Outer` in this scope
   --> $DIR/generate-mod.rs:9:1
    |
 LL | generate_mod::check!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | not found in this scope
+   | in this macro invocation
 
 error[E0412]: cannot find type `FromOutside` in this scope
   --> $DIR/generate-mod.rs:12:1
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
index da2bf07a1a3..65e40172ef5 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
@@ -2,7 +2,10 @@ error: unexpected close delimiter: `)`
   --> $DIR/invalid-punct-ident-4.rs:6:1
    |
 LL | lexer_failure!();
-   | ^^^^^^^^^^^^^^^^^ unexpected close delimiter
+   | ^^^^^^^^^^^^^^^^^
+   | |
+   | unexpected close delimiter
+   | in this macro invocation
 
 error: proc macro panicked
   --> $DIR/invalid-punct-ident-4.rs:6:1
diff --git a/src/test/ui/proc-macro/lints_in_proc_macros.stderr b/src/test/ui/proc-macro/lints_in_proc_macros.stderr
index 2d97cd700be..f28b8c9fb73 100644
--- a/src/test/ui/proc-macro/lints_in_proc_macros.stderr
+++ b/src/test/ui/proc-macro/lints_in_proc_macros.stderr
@@ -2,7 +2,10 @@ error[E0425]: cannot find value `foobar2` in this scope
   --> $DIR/lints_in_proc_macros.rs:12:5
    |
 LL |     bang_proc_macro2!();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar`
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     help: a local variable with a similar name exists: `foobar`
+   |     in this macro invocation
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
index b2f12478828..0c863e91967 100644
--- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
@@ -88,18 +88,6 @@ error: expected derive macro, found macro `crate::my_macro`
 LL | #[derive(crate::my_macro)]
    |          ^^^^^^^^^^^^^^^ not a derive macro
 
-error: cannot find attribute macro `my_macro` in this scope
-  --> $DIR/macro-namespace-reserved-2.rs:38:3
-   |
-LL | #[my_macro]
-   |   ^^^^^^^^
-
-error: cannot find derive macro `my_macro` in this scope
-  --> $DIR/macro-namespace-reserved-2.rs:48:10
-   |
-LL | #[derive(my_macro)]
-   |          ^^^^^^^^
-
 error: cannot find macro `my_macro_attr!` in this scope
   --> $DIR/macro-namespace-reserved-2.rs:28:5
    |
@@ -112,5 +100,17 @@ error: cannot find macro `MyTrait!` in this scope
 LL |     MyTrait!();
    |     ^^^^^^^
 
+error: cannot find attribute macro `my_macro` in this scope
+  --> $DIR/macro-namespace-reserved-2.rs:38:3
+   |
+LL | #[my_macro]
+   |   ^^^^^^^^
+
+error: cannot find derive macro `my_macro` in this scope
+  --> $DIR/macro-namespace-reserved-2.rs:48:10
+   |
+LL | #[derive(my_macro)]
+   |          ^^^^^^^^
+
 error: aborting due to 19 previous errors
 
diff --git a/src/test/ui/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr
index 44af07a7942..a0c1f9cd5c0 100644
--- a/src/test/ui/proc-macro/multispan.stderr
+++ b/src/test/ui/proc-macro/multispan.stderr
@@ -2,7 +2,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:14:5
    |
 LL |     hello!(hi);
-   |     ^^^^^^^^^^^
+   |     ^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:14:12
@@ -14,7 +14,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:17:5
    |
 LL |     hello!(hi hi);
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:17:12
@@ -26,7 +26,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:20:5
    |
 LL |     hello!(hi hi hi);
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:20:12
@@ -38,7 +38,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:23:5
    |
 LL |     hello!(hi hey hi yo hi beep beep hi hi);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:23:12
@@ -50,7 +50,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:24:5
    |
 LL |     hello!(hi there, hi how are you? hi... hi.);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:24:12
@@ -62,7 +62,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:25:5
    |
 LL |     hello!(whoah. hi di hi di ho);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:25:19
@@ -74,7 +74,7 @@ error: hello to you, too!
   --> $DIR/multispan.rs:26:5
    |
 LL |     hello!(hi good hi and good bye);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:26:12
diff --git a/src/test/ui/proc-macro/subspan.stderr b/src/test/ui/proc-macro/subspan.stderr
index 5117dd6d32d..06715c197bc 100644
--- a/src/test/ui/proc-macro/subspan.stderr
+++ b/src/test/ui/proc-macro/subspan.stderr
@@ -2,7 +2,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:11:1
    |
 LL | subspan!("hi");
-   | ^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:11:11
@@ -14,7 +14,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:14:1
    |
 LL | subspan!("hihi");
-   | ^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:14:11
@@ -26,7 +26,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:17:1
    |
 LL | subspan!("hihihi");
-   | ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:17:11
@@ -38,7 +38,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:20:1
    |
 LL | subspan!("why I hide? hi!");
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:20:17
@@ -50,7 +50,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:21:1
    |
 LL | subspan!("hey, hi, hidy, hidy, hi hi");
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:21:16
@@ -62,7 +62,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:22:1
    |
 LL | subspan!("this is a hi, and this is another hi");
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:22:12
@@ -74,7 +74,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:23:1
    |
 LL | subspan!("how are you this evening");
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:23:24
@@ -86,7 +86,7 @@ error: found 'hi's
   --> $DIR/subspan.rs:24:1
    |
 LL | subspan!("this is highly eradic");
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
 note: here
   --> $DIR/subspan.rs:24:12
diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr
index f8dfa841d4f..0a6cbe13098 100644
--- a/src/test/ui/proc-macro/three-equals.stderr
+++ b/src/test/ui/proc-macro/three-equals.stderr
@@ -2,7 +2,7 @@ error: found 2 equal signs, need exactly 3
   --> $DIR/three-equals.rs:15:5
    |
 LL |     three_equals!(==);
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^ in this macro invocation
    |
    = help: input must be: `===`
 
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr
index 5028663ba6d..eed9934be12 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
@@ -10,7 +10,7 @@ LL |     let _: &'a WithHrAssoc<TheType<'b>> = loop { };
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
    |
 LL | fn with_assoc_sub<'a,'b>() {
    |                   -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
index d8330184008..ed5800940ee 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
@@ -1,33 +1,33 @@
 error[E0491]: in type `&'a WithHrAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
    |
 LL |     let _: &'a WithHrAssoc<TheType<'b>> = loop { };
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 32:15
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:32:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:27:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 32:18
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:32:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:27:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
 
 error[E0491]: in type `&'a WithHrAssocSub<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
    |
 LL |     let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 53:19
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:53:19
+note: the pointer is valid for the lifetime 'a as defined on the function body at 46:19
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:46:19
    |
 LL | fn with_assoc_sub<'a,'b>() {
    |                   ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 53:22
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:53:22
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 46:22
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:46:22
    |
 LL | fn with_assoc_sub<'a,'b>() {
    |                      ^^
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr
index 5028663ba6d..eed9934be12 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
@@ -10,7 +10,7 @@ LL |     let _: &'a WithHrAssoc<TheType<'b>> = loop { };
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+  --> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
    |
 LL | fn with_assoc_sub<'a,'b>() {
    |                   -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs b/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs
index 407a4fdf59b..cee741184ca 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.rs
@@ -6,9 +6,6 @@
 
 #![allow(dead_code)]
 
-
-///////////////////////////////////////////////////////////////////////////
-
 pub trait TheTrait<'b> {
     type TheAssocType;
 }
@@ -21,8 +18,6 @@ impl<'a,'b> TheTrait<'a> for TheType<'b> {
     type TheAssocType = &'b ();
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 pub struct WithHrAssoc<T>
     where for<'a> T : TheTrait<'a>
 {
@@ -37,8 +32,6 @@ fn with_assoc<'a,'b>() {
     //[nll]~^^ ERROR lifetime may not live long enough
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 pub trait TheSubTrait : for<'a> TheTrait<'a> {
 }
 
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr
index 880fe17b740..8c54d8da0a0 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+  --> $DIR/regions-outlives-projection-container-wc.rs:33:12
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
index 9e31065ca4e..152e6c5600c 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
@@ -1,16 +1,16 @@
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+  --> $DIR/regions-outlives-projection-container-wc.rs:33:12
    |
 LL |     let _: &'a WithAssoc<TheType<'b>> = loop { };
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 31:15
-  --> $DIR/regions-outlives-projection-container-wc.rs:31:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15
+  --> $DIR/regions-outlives-projection-container-wc.rs:27:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 31:18
-  --> $DIR/regions-outlives-projection-container-wc.rs:31:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18
+  --> $DIR/regions-outlives-projection-container-wc.rs:27:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
index 880fe17b740..8c54d8da0a0 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+  --> $DIR/regions-outlives-projection-container-wc.rs:33:12
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.rs b/src/test/ui/regions/regions-outlives-projection-container-wc.rs
index 5037ea536da..99965f33390 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.rs
@@ -8,8 +8,6 @@
 
 #![allow(dead_code)]
 
-///////////////////////////////////////////////////////////////////////////
-
 pub trait TheTrait {
     type TheAssocType;
 }
@@ -22,8 +20,6 @@ impl<'b> TheTrait for TheType<'b> {
     type TheAssocType = &'b ();
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 pub struct WithAssoc<T> where T : TheTrait {
     m: [T; 0]
 }
diff --git a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
index ef87d02ec08..2cf6e245d19 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container.rs:40:13
+  --> $DIR/regions-outlives-projection-container.rs:36:13
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
@@ -10,7 +10,7 @@ LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container.rs:58:13
+  --> $DIR/regions-outlives-projection-container.rs:54:13
    |
 LL | fn without_assoc<'a,'b>() {
    |                  -- -- lifetime `'b` defined here
@@ -21,7 +21,7 @@ LL |     let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container.rs:67:5
+  --> $DIR/regions-outlives-projection-container.rs:63:5
    |
 LL | fn call_with_assoc<'a,'b>() {
    |                    -- -- lifetime `'b` defined here
@@ -32,7 +32,7 @@ LL |     call::<&'a WithAssoc<TheType<'b>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
 
 error: lifetime may not live long enough
-  --> $DIR/regions-outlives-projection-container.rs:74:5
+  --> $DIR/regions-outlives-projection-container.rs:70:5
    |
 LL | fn call_without_assoc<'a,'b>() {
    |                       -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-outlives-projection-container.rs b/src/test/ui/regions/regions-outlives-projection-container.rs
index 78305c06939..3afc600becb 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.rs
+++ b/src/test/ui/regions/regions-outlives-projection-container.rs
@@ -5,8 +5,6 @@
 #![allow(dead_code)]
 #![feature(rustc_attrs)]
 
-///////////////////////////////////////////////////////////////////////////
-
 pub trait TheTrait {
     type TheAssocType;
 }
@@ -19,8 +17,6 @@ impl<'b> TheTrait for TheType<'b> {
     type TheAssocType = &'b ();
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 pub struct WithAssoc<T:TheTrait> {
     m: [T; 0]
 }
diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.stderr
index b50347ac964..3c1a98a3c01 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container.stderr
@@ -1,67 +1,67 @@
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:40:13
+  --> $DIR/regions-outlives-projection-container.rs:36:13
    |
 LL |     let _x: &'a WithAssoc<TheType<'b>> = loop { };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 32:15
-  --> $DIR/regions-outlives-projection-container.rs:32:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 28:15
+  --> $DIR/regions-outlives-projection-container.rs:28:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 32:18
-  --> $DIR/regions-outlives-projection-container.rs:32:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 28:18
+  --> $DIR/regions-outlives-projection-container.rs:28:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
 
 error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:58:13
+  --> $DIR/regions-outlives-projection-container.rs:54:13
    |
 LL |     let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 54:18
-  --> $DIR/regions-outlives-projection-container.rs:54:18
+note: the pointer is valid for the lifetime 'a as defined on the function body at 50:18
+  --> $DIR/regions-outlives-projection-container.rs:50:18
    |
 LL | fn without_assoc<'a,'b>() {
    |                  ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 54:21
-  --> $DIR/regions-outlives-projection-container.rs:54:21
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 50:21
+  --> $DIR/regions-outlives-projection-container.rs:50:21
    |
 LL | fn without_assoc<'a,'b>() {
    |                     ^^
 
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:67:12
+  --> $DIR/regions-outlives-projection-container.rs:63:12
    |
 LL |     call::<&'a WithAssoc<TheType<'b>>>();
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 62:20
-  --> $DIR/regions-outlives-projection-container.rs:62:20
+note: the pointer is valid for the lifetime 'a as defined on the function body at 58:20
+  --> $DIR/regions-outlives-projection-container.rs:58:20
    |
 LL | fn call_with_assoc<'a,'b>() {
    |                    ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 62:23
-  --> $DIR/regions-outlives-projection-container.rs:62:23
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 58:23
+  --> $DIR/regions-outlives-projection-container.rs:58:23
    |
 LL | fn call_with_assoc<'a,'b>() {
    |                       ^^
 
 error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-outlives-projection-container.rs:74:12
+  --> $DIR/regions-outlives-projection-container.rs:70:12
    |
 LL |     call::<&'a WithoutAssoc<TheType<'b>>>();
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 71:23
-  --> $DIR/regions-outlives-projection-container.rs:71:23
+note: the pointer is valid for the lifetime 'a as defined on the function body at 67:23
+  --> $DIR/regions-outlives-projection-container.rs:67:23
    |
 LL | fn call_without_assoc<'a,'b>() {
    |                       ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 71:26
-  --> $DIR/regions-outlives-projection-container.rs:71:26
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 67:26
+  --> $DIR/regions-outlives-projection-container.rs:67:26
    |
 LL | fn call_without_assoc<'a,'b>() {
    |                          ^^
diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr
index d4b97d290ea..856162b318d 100644
--- a/src/test/ui/reserved/reserved-attr-on-macro.stderr
+++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr
@@ -7,12 +7,6 @@ LL | #[rustc_attribute_should_be_reserved]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
-error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope
-  --> $DIR/reserved-attr-on-macro.rs:1:3
-   |
-LL | #[rustc_attribute_should_be_reserved]
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: cannot determine resolution for the macro `foo`
   --> $DIR/reserved-attr-on-macro.rs:10:5
    |
@@ -21,6 +15,12 @@ LL |     foo!();
    |
    = note: import resolution is stuck, try simplifying macro imports
 
+error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope
+  --> $DIR/reserved-attr-on-macro.rs:1:3
+   |
+LL | #[rustc_attribute_should_be_reserved]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
index 03492631cb7..f5197fd01bf 100644
--- a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.rs
@@ -1,12 +1,9 @@
+#![allow(incomplete_features)]
 #![feature(generic_associated_types)]
 
-//FIXME(#44265): The lifetime shadowing and type parameter shadowing
-// should cause an error. Now it compiles (erroneously) and this will be addressed
-// by a future PR. Then remove the following:
-// build-pass (FIXME(62277): could be check-pass?)
-
 trait Shadow<'a> {
-    type Bar<'a>; // Error: shadowed lifetime
+    //FIXME(#44265): The lifetime parameter shadowing should cause an error.
+    type Bar<'a>;
 }
 
 trait NoShadow<'a> {
@@ -14,11 +11,12 @@ trait NoShadow<'a> {
 }
 
 impl<'a> NoShadow<'a> for &'a u32 {
-    type Bar<'a> = i32; // Error: shadowed lifetime
+    //FIXME(#44265): The lifetime parameter shadowing should cause an error.
+    type Bar<'a> = i32;
 }
 
 trait ShadowT<T> {
-    type Bar<T>; // Error: shadowed type parameter
+    type Bar<T>; //~ ERROR the name `T` is already used
 }
 
 trait NoShadowT<T> {
@@ -26,7 +24,7 @@ trait NoShadowT<T> {
 }
 
 impl<T> NoShadowT<T> for Option<T> {
-    type Bar<T> = i32; // Error: shadowed type parameter
+    type Bar<T> = i32; //~ ERROR the name `T` is already used
 }
 
 fn main() {}
diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
index 9526df258c4..a06c6350845 100644
--- a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr
@@ -1,8 +1,19 @@
-warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
-  --> $DIR/shadowing.rs:1:12
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowing.rs:19:14
    |
-LL | #![feature(generic_associated_types)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+LL | trait ShadowT<T> {
+   |               - first use of `T`
+LL |     type Bar<T>;
+   |              ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowing.rs:27:14
    |
-   = note: `#[warn(incomplete_features)]` on by default
+LL | impl<T> NoShadowT<T> for Option<T> {
+   |      - first use of `T`
+LL |     type Bar<T> = i32;
+   |              ^ already used
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/rust-unstable-column-gated.rs b/src/test/ui/rust-unstable-column-gated.rs
deleted file mode 100644
index 053806ead2d..00000000000
--- a/src/test/ui/rust-unstable-column-gated.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-fn main() {
-    println!("{}", __rust_unstable_column!());
-    //~^ ERROR use of unstable library feature '__rust_unstable_column'
-}
diff --git a/src/test/ui/rust-unstable-column-gated.stderr b/src/test/ui/rust-unstable-column-gated.stderr
deleted file mode 100644
index 7db1b01fb0e..00000000000
--- a/src/test/ui/rust-unstable-column-gated.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: use of unstable library feature '__rust_unstable_column': internal implementation detail of the `panic` macro
-  --> $DIR/rust-unstable-column-gated.rs:2:20
-   |
-LL |     println!("{}", __rust_unstable_column!());
-   |                    ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(__rust_unstable_column)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
index 94646c2cfe0..e33001b9244 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                                             ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:50
@@ -30,7 +30,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    |                                                          ^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:62
diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
index 779b21e21a0..3e58c973019 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                                          ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:15:47
@@ -24,7 +24,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                                ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:21:53
@@ -44,7 +44,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:25:62
@@ -64,7 +64,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:29:62
@@ -84,7 +84,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:33:71
@@ -104,7 +104,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                              ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#28r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
   --> $DIR/lt-ref-self-async.rs:37:67
diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
index cfe91dde373..b8a53808810 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                                              ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:15:51
@@ -24,7 +24,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                                                    ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:21:57
@@ -44,7 +44,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                                             ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:25:66
@@ -64,7 +64,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                                             ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:29:66
@@ -84,7 +84,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:33:75
@@ -104,7 +104,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-self-async.rs:37:75
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
index 98fa5e25451..cee008de667 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                                                        ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:15:61
@@ -24,7 +24,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                                                 ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:19:70
@@ -44,7 +44,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                                                 ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:23:70
@@ -64,7 +64,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                                                          ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:27:79
@@ -84,7 +84,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                                                          ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-mut-struct-async.rs:31:79
diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr
index f991f6d9f7f..c3c15485b22 100644
--- a/src/test/ui/self/elision/ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                                          ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:24:47
@@ -24,7 +24,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                                ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:30:53
@@ -44,7 +44,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:34:62
@@ -64,7 +64,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:38:62
@@ -84,7 +84,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:42:71
@@ -104,7 +104,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:46:71
@@ -124,7 +124,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                                                     ^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-self-async.rs:50:73
diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr
index 437d403e044..ff50f6825bc 100644
--- a/src/test/ui/self/elision/ref-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr
@@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                                                    ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:15:57
@@ -24,7 +24,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                                             ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:19:66
@@ -44,7 +44,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                                             ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:23:66
@@ -64,7 +64,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:27:75
@@ -84,7 +84,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
    |
-   = note: hidden type `impl std::future::Future` captures lifetime '_#18r
+   = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
   --> $DIR/ref-struct-async.rs:31:71
diff --git a/src/test/ui/shadowed/shadowed-type-parameter.rs b/src/test/ui/shadowed/shadowed-type-parameter.rs
index ba9f3abcf7a..e74620f8900 100644
--- a/src/test/ui/shadowed/shadowed-type-parameter.rs
+++ b/src/test/ui/shadowed/shadowed-type-parameter.rs
@@ -6,7 +6,7 @@ struct Foo<T>(T);
 
 impl<T> Foo<T> {
     fn shadow_in_method<T>(&self) {}
-    //~^ ERROR type parameter `T` shadows another type parameter
+    //~^ ERROR the name `T` is already used
 
     fn not_shadow_in_item<U>(&self) {
         struct Bar<T, U>(T,U); // not a shadow, separate item
@@ -18,10 +18,10 @@ trait Bar<T> {
     fn dummy(&self) -> T;
 
     fn shadow_in_required<T>(&self);
-    //~^ ERROR type parameter `T` shadows another type parameter
+    //~^ ERROR the name `T` is already used
 
     fn shadow_in_provided<T>(&self) {}
-    //~^ ERROR type parameter `T` shadows another type parameter
+    //~^ ERROR the name `T` is already used
 
     fn not_shadow_in_required<U>(&self);
     fn not_shadow_in_provided<U>(&self) {}
diff --git a/src/test/ui/shadowed/shadowed-type-parameter.stderr b/src/test/ui/shadowed/shadowed-type-parameter.stderr
index 6b4d1fae3de..0ea82f983f1 100644
--- a/src/test/ui/shadowed/shadowed-type-parameter.stderr
+++ b/src/test/ui/shadowed/shadowed-type-parameter.stderr
@@ -1,29 +1,29 @@
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/shadowed-type-parameter.rs:8:25
+   |
+LL | impl<T> Foo<T> {
+   |      - first use of `T`
+LL |     fn shadow_in_method<T>(&self) {}
+   |                         ^ already used
+
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/shadowed-type-parameter.rs:20:27
    |
 LL | trait Bar<T> {
-   |           - first `T` declared here
+   |           - first use of `T`
 ...
 LL |     fn shadow_in_required<T>(&self);
-   |                           ^ shadows another type parameter
+   |                           ^ already used
 
-error[E0194]: type parameter `T` shadows another type parameter of the same name
+error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
   --> $DIR/shadowed-type-parameter.rs:23:27
    |
 LL | trait Bar<T> {
-   |           - first `T` declared here
+   |           - first use of `T`
 ...
 LL |     fn shadow_in_provided<T>(&self) {}
-   |                           ^ shadows another type parameter
-
-error[E0194]: type parameter `T` shadows another type parameter of the same name
-  --> $DIR/shadowed-type-parameter.rs:8:25
-   |
-LL | impl<T> Foo<T> {
-   |      - first `T` declared here
-LL |     fn shadow_in_method<T>(&self) {}
-   |                         ^ shadows another type parameter
+   |                           ^ already used
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0194`.
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.rs b/src/test/ui/specialization/defaultimpl/specialization-no-default.rs
index 7ea79a9a7bf..37005f839d4 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-no-default.rs
+++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.rs
@@ -3,9 +3,7 @@
 // Check a number of scenarios in which one impl tries to override another,
 // without correctly using `default`.
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 1: one layer of specialization, multiple methods, missing `default`
-////////////////////////////////////////////////////////////////////////////////
 
 trait Foo {
     fn foo(&self);
@@ -25,9 +23,7 @@ impl Foo for u32 {
     fn bar(&self) {} //~ ERROR E0520
 }
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 2: one layer of specialization, missing `default` on associated type
-////////////////////////////////////////////////////////////////////////////////
 
 trait Bar {
     type T;
@@ -41,9 +37,7 @@ impl Bar for u8 {
     type T = (); //~ ERROR E0520
 }
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 3a: multiple layers of specialization, missing interior `default`
-////////////////////////////////////////////////////////////////////////////////
 
 trait Baz {
     fn baz(&self);
@@ -61,10 +55,8 @@ impl Baz for i32 {
     fn baz(&self) {} //~ ERROR E0520
 }
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 3b: multiple layers of specialization, missing interior `default`,
 // redundant `default` in bottom layer.
-////////////////////////////////////////////////////////////////////////////////
 
 trait Redundant {
     fn redundant(&self);
diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
index 91690f64d94..13636b28b12 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr
@@ -1,5 +1,5 @@
 error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:22:5
+  --> $DIR/specialization-no-default.rs:20:5
    |
 LL | / impl<T> Foo for T {
 LL | |     fn foo(&self) {}
@@ -13,7 +13,7 @@ LL |       fn foo(&self) {}
    = note: to specialize, `foo` in the parent `impl` must be marked `default`
 
 error[E0520]: `bar` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:25:5
+  --> $DIR/specialization-no-default.rs:23:5
    |
 LL | / impl<T> Foo for T {
 LL | |     fn foo(&self) {}
@@ -27,7 +27,7 @@ LL |       fn bar(&self) {}
    = note: to specialize, `bar` in the parent `impl` must be marked `default`
 
 error[E0520]: `T` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:41:5
+  --> $DIR/specialization-no-default.rs:37:5
    |
 LL | / impl<T> Bar for T {
 LL | |     type T = u8;
@@ -40,7 +40,7 @@ LL |       type T = ();
    = note: to specialize, `T` in the parent `impl` must be marked `default`
 
 error[E0520]: `baz` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:61:5
+  --> $DIR/specialization-no-default.rs:55:5
    |
 LL | / impl<T: Clone> Baz for T {
 LL | |     fn baz(&self) {}
@@ -53,7 +53,7 @@ LL |       fn baz(&self) {}
    = note: to specialize, `baz` in the parent `impl` must be marked `default`
 
 error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:82:5
+  --> $DIR/specialization-no-default.rs:74:5
    |
 LL | / impl<T: Clone> Redundant for T {
 LL | |     fn redundant(&self) {}
diff --git a/src/test/ui/specialization/specialization-no-default.rs b/src/test/ui/specialization/specialization-no-default.rs
index 29afbbd9bf2..57346b26d24 100644
--- a/src/test/ui/specialization/specialization-no-default.rs
+++ b/src/test/ui/specialization/specialization-no-default.rs
@@ -3,9 +3,7 @@
 // Check a number of scenarios in which one impl tries to override another,
 // without correctly using `default`.
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 1: one layer of specialization, multiple methods, missing `default`
-////////////////////////////////////////////////////////////////////////////////
 
 trait Foo {
     fn foo(&self);
@@ -25,9 +23,7 @@ impl Foo for u32 {
     fn bar(&self) {} //~ ERROR E0520
 }
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 2: one layer of specialization, missing `default` on associated type
-////////////////////////////////////////////////////////////////////////////////
 
 trait Bar {
     type T;
@@ -41,9 +37,7 @@ impl Bar for u8 {
     type T = (); //~ ERROR E0520
 }
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 3a: multiple layers of specialization, missing interior `default`
-////////////////////////////////////////////////////////////////////////////////
 
 trait Baz {
     fn baz(&self);
@@ -61,10 +55,8 @@ impl Baz for i32 {
     fn baz(&self) {} //~ ERROR E0520
 }
 
-////////////////////////////////////////////////////////////////////////////////
 // Test 3b: multiple layers of specialization, missing interior `default`,
 // redundant `default` in bottom layer.
-////////////////////////////////////////////////////////////////////////////////
 
 trait Redundant {
     fn redundant(&self);
diff --git a/src/test/ui/specialization/specialization-no-default.stderr b/src/test/ui/specialization/specialization-no-default.stderr
index c39986de38d..992e9abbd4c 100644
--- a/src/test/ui/specialization/specialization-no-default.stderr
+++ b/src/test/ui/specialization/specialization-no-default.stderr
@@ -1,5 +1,5 @@
 error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:22:5
+  --> $DIR/specialization-no-default.rs:20:5
    |
 LL | / impl<T> Foo for T {
 LL | |     fn foo(&self) {}
@@ -13,7 +13,7 @@ LL |       fn foo(&self) {}
    = note: to specialize, `foo` in the parent `impl` must be marked `default`
 
 error[E0520]: `bar` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:25:5
+  --> $DIR/specialization-no-default.rs:23:5
    |
 LL | / impl<T> Foo for T {
 LL | |     fn foo(&self) {}
@@ -27,7 +27,7 @@ LL |       fn bar(&self) {}
    = note: to specialize, `bar` in the parent `impl` must be marked `default`
 
 error[E0520]: `T` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:41:5
+  --> $DIR/specialization-no-default.rs:37:5
    |
 LL | / impl<T> Bar for T {
 LL | |     type T = u8;
@@ -40,7 +40,7 @@ LL |       type T = ();
    = note: to specialize, `T` in the parent `impl` must be marked `default`
 
 error[E0520]: `baz` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:61:5
+  --> $DIR/specialization-no-default.rs:55:5
    |
 LL | / impl<T: Clone> Baz for T {
 LL | |     fn baz(&self) {}
@@ -53,7 +53,7 @@ LL |       fn baz(&self) {}
    = note: to specialize, `baz` in the parent `impl` must be marked `default`
 
 error[E0520]: `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
-  --> $DIR/specialization-no-default.rs:82:5
+  --> $DIR/specialization-no-default.rs:74:5
    |
 LL | / impl<T: Clone> Redundant for T {
 LL | |     fn redundant(&self) {}
diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs
new file mode 100644
index 00000000000..d625199c937
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.rs
@@ -0,0 +1,3 @@
+fn main() {
+    assert_eq!(10u64, 10usize); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr
new file mode 100644
index 00000000000..f04306997a9
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-try_into-in-macros.stderr
@@ -0,0 +1,11 @@
+error[E0308]: mismatched types
+  --> $DIR/dont-suggest-try_into-in-macros.rs:2:5
+   |
+LL |     assert_eq!(10u64, 10usize);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u64, found usize
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs
index 52bb118fa23..137b72dcd9c 100644
--- a/src/test/ui/symbol-names/impl1.rs
+++ b/src/test/ui/symbol-names/impl1.rs
@@ -64,9 +64,9 @@ fn main() {
             //[legacy]~^ ERROR symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method
             //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method
             //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method)
-             //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
-                //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
-                //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
+             //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
+                //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
+                //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
             #[rustc_def_path]
             //[legacy]~^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
                //[v0]~^^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr
index 1c4b256c9e9..e024799df86 100644
--- a/src/test/ui/symbol-names/impl1.v0.stderr
+++ b/src/test/ui/symbol-names/impl1.v0.stderr
@@ -46,19 +46,19 @@ error: def-path(bar::<impl foo::Foo>::baz)
 LL |         #[rustc_def_path]
    |         ^^^^^^^^^^^^^^^^^
 
-error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
+error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
   --> $DIR/impl1.rs:63:13
    |
 LL |             #[rustc_symbol_name]
    |             ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
+error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
   --> $DIR/impl1.rs:63:13
    |
 LL |             #[rustc_symbol_name]
    |             ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
+error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
   --> $DIR/impl1.rs:63:13
    |
 LL |             #[rustc_symbol_name]
diff --git a/src/test/ui/symbol-names/issue-60925.legacy.stderr b/src/test/ui/symbol-names/issue-60925.legacy.stderr
index 7fcd2ede31b..de8efdde737 100644
--- a/src/test/ui/symbol-names/issue-60925.legacy.stderr
+++ b/src/test/ui/symbol-names/issue-60925.legacy.stderr
@@ -4,13 +4,13 @@ error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3f
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo::h059a991a004536ad)
+error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h059a991a004536ad)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling-alt(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo)
+error: demangling-alt(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
diff --git a/src/test/ui/symbol-names/issue-60925.rs b/src/test/ui/symbol-names/issue-60925.rs
index 89de15cc0f3..02438351dbc 100644
--- a/src/test/ui/symbol-names/issue-60925.rs
+++ b/src/test/ui/symbol-names/issue-60925.rs
@@ -20,8 +20,8 @@ mod foo {
     impl Foo<::llvm::Foo> {
         #[rustc_symbol_name]
         //[legacy]~^ ERROR symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo
-        //[legacy]~| ERROR demangling(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo
-        //[legacy]~| ERROR demangling-alt(issue_60925::foo::Foo<issue_60925::llv$u6d$..Foo$GT$::foo)
+        //[legacy]~| ERROR demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo
+        //[legacy]~| ERROR demangling-alt(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo)
          //[v0]~^^^^ ERROR symbol-name(_RNvMNtCs4fqI2P2rA04_11issue_609253fooINtB2_3FooNtNtB4_4llvm3FooE3foo)
             //[v0]~| ERROR demangling(<issue_60925[317d481089b8c8fe]::foo::Foo<issue_60925[317d481089b8c8fe]::llvm::Foo>>::foo)
             //[v0]~| ERROR demangling-alt(<issue_60925::foo::Foo<issue_60925::llvm::Foo>>::foo)
diff --git a/src/test/ui/traits/traits-conditional-model-fn.rs b/src/test/ui/traits/traits-conditional-model-fn.rs
index 27ce6d93a81..afdfb96394b 100644
--- a/src/test/ui/traits/traits-conditional-model-fn.rs
+++ b/src/test/ui/traits/traits-conditional-model-fn.rs
@@ -14,8 +14,6 @@ use go_trait::{Go, GoMut, GoOnce, go, go_mut, go_once};
 use std::rc::Rc;
 use std::cell::Cell;
 
-///////////////////////////////////////////////////////////////////////////
-
 struct SomeGoableThing {
     counter: Rc<Cell<isize>>
 }
@@ -26,8 +24,6 @@ impl Go for SomeGoableThing {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 struct SomeGoOnceableThing {
     counter: Rc<Cell<isize>>
 }
@@ -38,8 +34,6 @@ impl GoOnce for SomeGoOnceableThing {
     }
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 fn main() {
     let counter = Rc::new(Cell::new(0));
     let mut x = SomeGoableThing { counter: counter.clone() };
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 05cfdf1ce53..3da6be74129 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1659,10 +1659,10 @@ impl<'test> TestCx<'test> {
             _ if self.config.target.contains("vxworks") => {
                 let aux_dir = self.aux_output_dir_name();
                 let ProcArgs { prog, args } = self.make_run_args();
-                let mut vx_run = Command::new("vx-run");
-                vx_run.args(&[&prog]).args(args).envs(env.clone());
+                let mut wr_run = Command::new("wr-run");
+                wr_run.args(&[&prog]).args(args).envs(env.clone());
                 self.compose_and_run(
-                    vx_run,
+                    wr_run,
                     self.config.run_lib_path.to_str().unwrap(),
                     Some(aux_dir.to_str().unwrap()),
                     None,
diff --git a/src/tools/miri b/src/tools/miri
-Subproject c1cb24969e84dfaded2769ab5575effc8d4f5c3
+Subproject 4f6f264c305ea30f1de90ad0c2f341e84d972b2
diff --git a/src/tools/rls b/src/tools/rls
-Subproject 7b0a20bf13b7061b1eb31a058117ac5517ff8cc
+Subproject 496c89275221303a4b0c2779cb8203fb3ce2a13