about summary refs log tree commit diff
diff options
context:
space:
mode:
authorStefan Lankes <slankes@eonerc.rwth-aachen.de>2019-11-13 00:24:37 +0100
committerStefan Lankes <slankes@eonerc.rwth-aachen.de>2019-11-13 00:24:37 +0100
commit88717319142e162ae2f48124d94f33d2c21bc2ce (patch)
treee50a968f836c55007e9bc8f305d4f0f80aca042c
parent969b74144641bf1c8ae5aba0581f4b52a4c15bac (diff)
parent4f03f4a989d1c8346c19dfb417a77c09b34408b8 (diff)
downloadrust-88717319142e162ae2f48124d94f33d2c21bc2ce.tar.gz
rust-88717319142e162ae2f48124d94f33d2c21bc2ce.zip
Merge remote-tracking branch 'rust-lang/master' into hermit
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Cargo.lock97
-rw-r--r--README.md2
-rw-r--r--src/bootstrap/flags.rs6
-rw-r--r--src/bootstrap/test.rs5
-rw-r--r--src/ci/azure-pipelines/auto.yml4
-rw-r--r--src/ci/docker/dist-i686-linux/Dockerfile2
-rwxr-xr-xsrc/ci/docker/dist-various-2/build-wasi-toolchain.sh14
-rw-r--r--src/ci/docker/dist-x86_64-linux/Dockerfile2
-rwxr-xr-xsrc/ci/docker/dist-x86_64-linux/build-clang.sh5
-rw-r--r--src/ci/docker/dist-x86_64-linux/llvm-project-centos.patch18
-rwxr-xr-xsrc/ci/scripts/install-clang.sh23
m---------src/doc/rustc-guide0
-rw-r--r--src/doc/rustc/src/codegen-options/index.md6
-rw-r--r--src/doc/rustc/src/command-line-arguments.md30
-rw-r--r--src/doc/rustc/src/lints/listing/deny-by-default.md91
-rw-r--r--src/doc/rustc/src/lints/listing/warn-by-default.md40
-rw-r--r--src/doc/rustdoc/src/SUMMARY.md2
-rw-r--r--src/doc/rustdoc/src/how-to-write-documentation.md82
-rw-r--r--src/doc/rustdoc/src/lints.md119
-rw-r--r--src/doc/unstable-book/src/language-features/on-unimplemented.md154
-rw-r--r--src/doc/unstable-book/src/language-features/re-rebalance-coherence.md23
-rwxr-xr-xsrc/etc/generate-deriving-span-tests.py3
-rw-r--r--src/liballoc/collections/linked_list.rs2
-rw-r--r--src/liballoc/collections/vec_deque.rs32
-rw-r--r--src/liballoc/collections/vec_deque/tests.rs35
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/rc.rs2
-rw-r--r--src/liballoc/string.rs2
-rw-r--r--src/liballoc/sync.rs2
-rw-r--r--src/libarena/Cargo.toml2
-rw-r--r--src/libcore/alloc.rs2
-rw-r--r--src/libcore/any.rs6
-rw-r--r--src/libcore/array/iter.rs13
-rw-r--r--src/libcore/array/mod.rs2
-rw-r--r--src/libcore/ascii.rs1
-rw-r--r--src/libcore/benches/ascii.rs2
-rw-r--r--src/libcore/cell.rs11
-rw-r--r--src/libcore/char/convert.rs1
-rw-r--r--src/libcore/char/decode.rs3
-rw-r--r--src/libcore/char/methods.rs2
-rw-r--r--src/libcore/convert.rs27
-rw-r--r--src/libcore/ffi.rs1
-rw-r--r--src/libcore/fmt/float.rs2
-rw-r--r--src/libcore/fmt/mod.rs2
-rw-r--r--src/libcore/fmt/num.rs2
-rw-r--r--src/libcore/hash/mod.rs2
-rw-r--r--src/libcore/hash/sip.rs2
-rw-r--r--src/libcore/hint.rs2
-rw-r--r--src/libcore/iter/adapters/mod.rs14
-rw-r--r--src/libcore/iter/adapters/zip.rs2
-rw-r--r--src/libcore/iter/traits/collect.rs1
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/macros.rs36
-rw-r--r--src/libcore/mem/maybe_uninit.rs235
-rw-r--r--src/libcore/mem/mod.rs21
-rw-r--r--src/libcore/num/dec2flt/algorithm.rs4
-rw-r--r--src/libcore/num/f32.rs2
-rw-r--r--src/libcore/num/f64.rs2
-rw-r--r--src/libcore/num/mod.rs27
-rw-r--r--src/libcore/option.rs2
-rw-r--r--src/libcore/panicking.rs2
-rw-r--r--src/libcore/pin.rs2
-rw-r--r--src/libcore/ptr/mod.rs25
-rw-r--r--src/libcore/ptr/non_null.rs2
-rw-r--r--src/libcore/ptr/unique.rs2
-rw-r--r--src/libcore/slice/memchr.rs2
-rw-r--r--src/libcore/slice/mod.rs61
-rw-r--r--src/libcore/slice/sort.rs2
-rw-r--r--src/libcore/str/lossy.rs2
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/libcore/str/pattern.rs2
-rw-r--r--src/libcore/sync/atomic.rs2
-rw-r--r--src/libcore/tests/num/flt2dec/mod.rs2
-rw-r--r--src/libcore/time.rs2
-rw-r--r--src/libfmt_macros/lib.rs24
-rw-r--r--src/libfmt_macros/tests.rs43
-rw-r--r--src/libpanic_abort/lib.rs1
-rw-r--r--src/libpanic_unwind/lib.rs1
-rw-r--r--src/librustc/Cargo.toml2
-rw-r--r--src/librustc/arena.rs2
-rw-r--r--src/librustc/dep_graph/dep_node.rs2
-rw-r--r--src/librustc/error_codes.rs9
-rw-r--r--src/librustc/hir/def.rs23
-rw-r--r--src/librustc/hir/intravisit.rs8
-rw-r--r--src/librustc/hir/lowering.rs97
-rw-r--r--src/librustc/hir/lowering/expr.rs25
-rw-r--r--src/librustc/hir/lowering/item.rs95
-rw-r--r--src/librustc/hir/map/blocks.rs18
-rw-r--r--src/librustc/hir/map/def_collector.rs17
-rw-r--r--src/librustc/hir/map/definitions.rs90
-rw-r--r--src/librustc/hir/map/mod.rs14
-rw-r--r--src/librustc/hir/mod.rs119
-rw-r--r--src/librustc/hir/pat_util.rs5
-rw-r--r--src/librustc/hir/print.rs38
-rw-r--r--src/librustc/ich/hcx.rs5
-rw-r--r--src/librustc/ich/impls_syntax.rs54
-rw-r--r--src/librustc/infer/error_reporting/mod.rs16
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs6
-rw-r--r--src/librustc/infer/region_constraints/README.md2
-rw-r--r--src/librustc/lint/builtin.rs87
-rw-r--r--src/librustc/lint/context.rs3
-rw-r--r--src/librustc/lint/internal.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs12
-rw-r--r--src/librustc/middle/reachable.rs6
-rw-r--r--src/librustc/middle/resolve_lifetime.rs12
-rw-r--r--src/librustc/middle/stability.rs13
-rw-r--r--src/librustc/mir/interpret/value.rs12
-rw-r--r--src/librustc/mir/mod.rs21
-rw-r--r--src/librustc/mir/mono.rs2
-rw-r--r--src/librustc/mir/tcx.rs8
-rw-r--r--src/librustc/query/mod.rs8
-rw-r--r--src/librustc/session/code_stats.rs12
-rw-r--r--src/librustc/session/config.rs237
-rw-r--r--src/librustc/session/mod.rs46
-rw-r--r--src/librustc/traits/coherence.rs146
-rw-r--r--src/librustc/traits/error_reporting.rs49
-rw-r--r--src/librustc/traits/mod.rs9
-rw-r--r--src/librustc/traits/on_unimplemented.rs2
-rw-r--r--src/librustc/traits/query/dropck_outlives.rs16
-rw-r--r--src/librustc/traits/query/type_op/outlives.rs4
-rw-r--r--src/librustc/traits/select.rs8
-rw-r--r--src/librustc/traits/structural_impls.rs2
-rw-r--r--src/librustc/ty/adjustment.rs11
-rw-r--r--src/librustc/ty/binding.rs8
-rw-r--r--src/librustc/ty/codec.rs3
-rw-r--r--src/librustc/ty/context.rs15
-rw-r--r--src/librustc/ty/error.rs37
-rw-r--r--src/librustc/ty/inhabitedness/def_id_forest.rs10
-rw-r--r--src/librustc/ty/layout.rs32
-rw-r--r--src/librustc/ty/mod.rs11
-rw-r--r--src/librustc/ty/print/obsolete.rs30
-rw-r--r--src/librustc/ty/print/pretty.rs36
-rw-r--r--src/librustc/ty/query/mod.rs1
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs7
-rw-r--r--src/librustc/ty/relate.rs4
-rw-r--r--src/librustc/ty/sty.rs8
-rw-r--r--src/librustc/ty/util.rs4
-rw-r--r--src/librustc/ty/wf.rs101
-rw-r--r--src/librustc_apfloat/Cargo.toml2
-rw-r--r--src/librustc_codegen_llvm/attributes.rs2
-rw-r--r--src/librustc_codegen_llvm/back/write.rs7
-rw-r--r--src/librustc_codegen_llvm/context.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs10
-rw-r--r--src/librustc_codegen_llvm/debuginfo/namespace.rs6
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs10
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm/mod.rs1
-rw-r--r--src/librustc_codegen_llvm/type_of.rs6
-rw-r--r--src/librustc_codegen_ssa/back/command.rs2
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs6
-rw-r--r--src/librustc_codegen_ssa/base.rs6
-rw-r--r--src/librustc_codegen_ssa/debuginfo/type_names.rs18
-rw-r--r--src/librustc_codegen_ssa/lib.rs3
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs3
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs1
-rw-r--r--src/librustc_codegen_utils/symbol_names/legacy.rs5
-rw-r--r--src/librustc_codegen_utils/symbol_names/v0.rs11
-rw-r--r--src/librustc_data_structures/Cargo.toml2
-rw-r--r--src/librustc_driver/Cargo.toml2
-rw-r--r--src/librustc_driver/args.rs12
-rw-r--r--src/librustc_driver/lib.rs62
-rw-r--r--src/librustc_driver/pretty.rs328
-rw-r--r--src/librustc_errors/emitter.rs12
-rw-r--r--src/librustc_errors/lib.rs10
-rw-r--r--src/librustc_incremental/assert_module_sources.rs16
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs4
-rw-r--r--src/librustc_index/Cargo.toml2
-rw-r--r--src/librustc_interface/Cargo.toml7
-rw-r--r--src/librustc_interface/interface.rs21
-rw-r--r--src/librustc_interface/passes.rs27
-rw-r--r--src/librustc_interface/tests.rs59
-rw-r--r--src/librustc_interface/util.rs51
-rw-r--r--src/librustc_lexer/src/cursor.rs12
-rw-r--r--src/librustc_lexer/src/lib.rs271
-rw-r--r--src/librustc_lint/array_into_iter.rs91
-rw-r--r--src/librustc_lint/builtin.rs54
-rw-r--r--src/librustc_lint/lib.rs17
-rw-r--r--src/librustc_lint/types.rs138
-rw-r--r--src/librustc_lint/unused.rs4
-rw-r--r--src/librustc_metadata/Cargo.toml3
-rw-r--r--src/librustc_metadata/creader.rs4
-rw-r--r--src/librustc_metadata/cstore.rs8
-rw-r--r--src/librustc_metadata/lib.rs6
-rw-r--r--src/librustc_metadata/link_args.rs2
-rw-r--r--src/librustc_metadata/locator.rs2
-rw-r--r--src/librustc_metadata/native_libs.rs2
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs (renamed from src/librustc_metadata/decoder.rs)128
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs (renamed from src/librustc_metadata/cstore_impl.rs)18
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs (renamed from src/librustc_metadata/encoder.rs)99
-rw-r--r--src/librustc_metadata/rmeta/mod.rs (renamed from src/librustc_metadata/schema.rs)188
-rw-r--r--src/librustc_metadata/rmeta/table.rs (renamed from src/librustc_metadata/table.rs)21
-rw-r--r--src/librustc_mir/Cargo.toml2
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs156
-rw-r--r--src/librustc_mir/borrow_check/mod.rs12
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs6
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs170
-rw-r--r--src/librustc_mir/borrow_check/nll/universal_regions.rs2
-rw-r--r--src/librustc_mir/borrow_check/place_ext.rs2
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs6
-rw-r--r--src/librustc_mir/borrow_check/prefixes.rs4
-rw-r--r--src/librustc_mir/build/expr/as_place.rs303
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs95
-rw-r--r--src/librustc_mir/build/expr/category.rs4
-rw-r--r--src/librustc_mir/build/expr/into.rs107
-rw-r--r--src/librustc_mir/build/mod.rs13
-rw-r--r--src/librustc_mir/const_eval.rs2
-rw-r--r--src/librustc_mir/hair/constant.rs5
-rw-r--r--src/librustc_mir/hair/cx/expr.rs13
-rw-r--r--src/librustc_mir/hair/mod.rs2
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs593
-rw-r--r--src/librustc_mir/hair/pattern/check_match.rs8
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs20
-rw-r--r--src/librustc_mir/interpret/cast.rs8
-rw-r--r--src/librustc_mir/interpret/eval_context.rs2
-rw-r--r--src/librustc_mir/interpret/intern.rs36
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs9
-rw-r--r--src/librustc_mir/interpret/intrinsics/caller_location.rs3
-rw-r--r--src/librustc_mir/interpret/memory.rs44
-rw-r--r--src/librustc_mir/interpret/operand.rs26
-rw-r--r--src/librustc_mir/interpret/place.rs20
-rw-r--r--src/librustc_mir/interpret/snapshot.rs2
-rw-r--r--src/librustc_mir/interpret/terminator.rs2
-rw-r--r--src/librustc_mir/interpret/traits.rs33
-rw-r--r--src/librustc_mir/interpret/validity.rs58
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/librustc_mir/shim.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/mod.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/qualifs.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs55
-rw-r--r--src/librustc_mir/transform/const_prop.rs35
-rw-r--r--src/librustc_mir/transform/generator.rs6
-rw-r--r--src/librustc_mir/transform/mod.rs10
-rw-r--r--src/librustc_mir/transform/promote_consts.rs142
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs591
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs7
-rw-r--r--src/librustc_mir/transform/simplify.rs23
-rw-r--r--src/librustc_mir/transform/uninhabited_enum_branching.rs126
-rw-r--r--src/librustc_mir/util/borrowck_errors.rs14
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs4
-rw-r--r--src/librustc_parse/Cargo.toml21
-rw-r--r--src/librustc_parse/error_codes.rs174
-rw-r--r--src/librustc_parse/lexer/mod.rs (renamed from src/libsyntax/parse/lexer/mod.rs)38
-rw-r--r--src/librustc_parse/lexer/tokentrees.rs (renamed from src/libsyntax/parse/lexer/tokentrees.rs)9
-rw-r--r--src/librustc_parse/lexer/unescape_error_reporting.rs (renamed from src/libsyntax/parse/unescape_error_reporting.rs)2
-rw-r--r--src/librustc_parse/lexer/unicode_chars.rs (renamed from src/libsyntax/parse/lexer/unicode_chars.rs)2
-rw-r--r--src/librustc_parse/lib.rs (renamed from src/libsyntax/parse/mod.rs)61
-rw-r--r--src/librustc_parse/parser/attr.rs (renamed from src/libsyntax/parse/parser/attr.rs)33
-rw-r--r--src/librustc_parse/parser/diagnostics.rs (renamed from src/libsyntax/parse/parser/diagnostics.rs)45
-rw-r--r--src/librustc_parse/parser/expr.rs (renamed from src/libsyntax/parse/parser/expr.rs)49
-rw-r--r--src/librustc_parse/parser/generics.rs (renamed from src/libsyntax/parse/parser/generics.rs)14
-rw-r--r--src/librustc_parse/parser/item.rs (renamed from src/libsyntax/parse/parser/item.rs)72
-rw-r--r--src/librustc_parse/parser/mod.rs (renamed from src/libsyntax/parse/parser.rs)104
-rw-r--r--src/librustc_parse/parser/module.rs (renamed from src/libsyntax/parse/parser/module.rs)70
-rw-r--r--src/librustc_parse/parser/pat.rs (renamed from src/libsyntax/parse/parser/pat.rs)37
-rw-r--r--src/librustc_parse/parser/path.rs (renamed from src/libsyntax/parse/parser/path.rs)24
-rw-r--r--src/librustc_parse/parser/stmt.rs (renamed from src/libsyntax/parse/parser/stmt.rs)26
-rw-r--r--src/librustc_parse/parser/ty.rs (renamed from src/libsyntax/parse/parser/ty.rs)22
-rw-r--r--src/librustc_parse/validate_attr.rs111
-rw-r--r--src/librustc_passes/Cargo.toml5
-rw-r--r--src/librustc_passes/ast_validation.rs148
-rw-r--r--src/librustc_passes/dead.rs17
-rw-r--r--src/librustc_passes/loops.rs4
-rw-r--r--src/librustc_plugin/registry.rs1
-rw-r--r--src/librustc_resolve/Cargo.toml2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs13
-rw-r--r--src/librustc_resolve/check_unused.rs4
-rw-r--r--src/librustc_resolve/diagnostics.rs14
-rw-r--r--src/librustc_resolve/late.rs24
-rw-r--r--src/librustc_resolve/lib.rs65
-rw-r--r--src/librustc_resolve/macros.rs154
-rw-r--r--src/librustc_resolve/resolve_imports.rs22
-rw-r--r--src/librustc_save_analysis/Cargo.toml2
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs8
-rw-r--r--src/librustc_save_analysis/lib.rs10
-rw-r--r--src/librustc_save_analysis/sig.rs32
-rw-r--r--src/librustc_save_analysis/span_utils.rs8
-rw-r--r--src/librustc_target/abi/call/mips64.rs6
-rw-r--r--src/librustc_target/abi/call/mod.rs4
-rw-r--r--src/librustc_target/abi/call/powerpc.rs41
-rw-r--r--src/librustc_target/abi/call/x86_64.rs2
-rw-r--r--src/librustc_target/abi/mod.rs64
-rw-r--r--src/librustc_target/spec/mod.rs9
-rw-r--r--src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs37
-rw-r--r--src/librustc_target/spec/windows_base.rs27
-rw-r--r--src/librustc_traits/Cargo.toml2
-rw-r--r--src/librustc_traits/chalk_context/program_clauses/builtin.rs4
-rw-r--r--src/librustc_traits/dropck_outlives.rs3
-rw-r--r--src/librustc_traits/generic_types.rs2
-rw-r--r--src/librustc_typeck/Cargo.toml2
-rw-r--r--src/librustc_typeck/astconv.rs6
-rw-r--r--src/librustc_typeck/check/_match.rs4
-rw-r--r--src/librustc_typeck/check/callee.rs4
-rw-r--r--src/librustc_typeck/check/cast.rs17
-rw-r--r--src/librustc_typeck/check/closure.rs6
-rw-r--r--src/librustc_typeck/check/coercion.rs20
-rw-r--r--src/librustc_typeck/check/compare_method.rs14
-rw-r--r--src/librustc_typeck/check/demand.rs18
-rw-r--r--src/librustc_typeck/check/expr.rs54
-rw-r--r--src/librustc_typeck/check/intrinsic.rs24
-rw-r--r--src/librustc_typeck/check/method/confirm.rs10
-rw-r--r--src/librustc_typeck/check/method/probe.rs8
-rw-r--r--src/librustc_typeck/check/method/suggest.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs220
-rw-r--r--src/librustc_typeck/check/op.rs8
-rw-r--r--src/librustc_typeck/check/pat.rs24
-rw-r--r--src/librustc_typeck/check/upvar.rs6
-rw-r--r--src/librustc_typeck/check/wfcheck.rs6
-rw-r--r--src/librustc_typeck/coherence/builtin.rs2
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs4
-rw-r--r--src/librustc_typeck/collect.rs92
-rw-r--r--src/librustc_typeck/error_codes.rs208
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/librustc_typeck/variance/constraints.rs4
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/clean/mod.rs83
-rw-r--r--src/librustdoc/config.rs4
-rw-r--r--src/librustdoc/html/highlight.rs9
-rw-r--r--src/librustdoc/html/render.rs101
-rw-r--r--src/librustdoc/html/static/main.js172
-rw-r--r--src/librustdoc/html/static/settings.css14
-rw-r--r--src/librustdoc/html/static/storage.js4
-rw-r--r--src/librustdoc/html/static/themes/dark.css3
-rw-r--r--src/librustdoc/html/static/themes/light.css3
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs7
-rw-r--r--src/librustdoc/test.rs8
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/libserialize/Cargo.toml2
-rw-r--r--src/libstd/collections/hash/set.rs2
-rw-r--r--src/libstd/f32.rs46
-rw-r--r--src/libstd/f64.rs66
-rw-r--r--src/libstd/io/buffered.rs7
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/net/ip.rs4
-rw-r--r--src/libstd/process.rs29
-rw-r--r--src/libstd/sync/once.rs291
-rw-r--r--src/libstd/sys/sgx/abi/mod.rs1
-rw-r--r--src/libstd/sys/sgx/rwlock.rs3
-rw-r--r--src/libstd/sys/unix/rand.rs3
-rw-r--r--src/libstd/sys/vxworks/os.rs3
-rw-r--r--src/libstd/thread/local.rs4
-rw-r--r--src/libstd/thread/mod.rs12
-rw-r--r--src/libsyntax/Cargo.toml3
-rw-r--r--src/libsyntax/ast.rs231
-rw-r--r--src/libsyntax/attr/builtin.rs114
-rw-r--r--src/libsyntax/attr/mod.rs111
-rw-r--r--src/libsyntax/error_codes.rs166
-rw-r--r--src/libsyntax/expand/mod.rs10
-rw-r--r--src/libsyntax/feature_gate/accepted.rs3
-rw-r--r--src/libsyntax/feature_gate/active.rs22
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs23
-rw-r--r--src/libsyntax/feature_gate/check.rs130
-rw-r--r--src/libsyntax/feature_gate/mod.rs11
-rw-r--r--src/libsyntax/feature_gate/removed.rs6
-rw-r--r--src/libsyntax/json/tests.rs15
-rw-r--r--src/libsyntax/lib.rs11
-rw-r--r--src/libsyntax/mut_visit.rs28
-rw-r--r--src/libsyntax/print/pprust.rs75
-rw-r--r--src/libsyntax/print/pprust/tests.rs7
-rw-r--r--src/libsyntax/sess.rs119
-rw-r--r--src/libsyntax/source_map.rs18
-rw-r--r--src/libsyntax/token.rs (renamed from src/libsyntax/parse/token.rs)59
-rw-r--r--src/libsyntax/tokenstream.rs33
-rw-r--r--src/libsyntax/util/classify.rs (renamed from src/libsyntax/parse/classify.rs)0
-rw-r--r--src/libsyntax/util/comments.rs (renamed from src/libsyntax/parse/lexer/comments.rs)25
-rw-r--r--src/libsyntax/util/comments/tests.rs (renamed from src/libsyntax/parse/lexer/comments/tests.rs)0
-rw-r--r--src/libsyntax/util/literal.rs (renamed from src/libsyntax/parse/literal.rs)39
-rw-r--r--src/libsyntax/util/parser.rs6
-rw-r--r--src/libsyntax/visit.rs18
-rw-r--r--src/libsyntax_expand/Cargo.toml8
-rw-r--r--src/libsyntax_expand/base.rs28
-rw-r--r--src/libsyntax_expand/config.rs (renamed from src/libsyntax/config.rs)56
-rw-r--r--src/libsyntax_expand/expand.rs38
-rw-r--r--src/libsyntax_expand/lib.rs29
-rw-r--r--src/libsyntax_expand/mbe.rs26
-rw-r--r--src/libsyntax_expand/mbe/macro_check.rs2
-rw-r--r--src/libsyntax_expand/mbe/macro_parser.rs10
-rw-r--r--src/libsyntax_expand/mbe/macro_rules.rs38
-rw-r--r--src/libsyntax_expand/mbe/quoted.rs2
-rw-r--r--src/libsyntax_expand/mbe/transcribe.rs8
-rw-r--r--src/libsyntax_expand/mut_visit/tests.rs (renamed from src/libsyntax/mut_visit/tests.rs)11
-rw-r--r--src/libsyntax_expand/parse/lexer/tests.rs (renamed from src/libsyntax/parse/lexer/tests.rs)22
-rw-r--r--src/libsyntax_expand/parse/tests.rs (renamed from src/libsyntax/parse/tests.rs)59
-rw-r--r--src/libsyntax_expand/proc_macro.rs14
-rw-r--r--src/libsyntax_expand/proc_macro_server.rs17
-rw-r--r--src/libsyntax_expand/tests.rs (renamed from src/libsyntax/tests.rs)23
-rw-r--r--src/libsyntax_expand/tokenstream/tests.rs (renamed from src/libsyntax/tokenstream/tests.rs)10
-rw-r--r--src/libsyntax_ext/Cargo.toml3
-rw-r--r--src/libsyntax_ext/asm.rs2
-rw-r--r--src/libsyntax_ext/assert.rs6
-rw-r--r--src/libsyntax_ext/cfg.rs2
-rw-r--r--src/libsyntax_ext/cmdline_attrs.rs4
-rw-r--r--src/libsyntax_ext/concat.rs3
-rw-r--r--src/libsyntax_ext/concat_idents.rs2
-rw-r--r--src/libsyntax_ext/deriving/clone.rs3
-rw-r--r--src/libsyntax_ext/deriving/cmp/eq.rs3
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_eq.rs3
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs38
-rw-r--r--src/libsyntax_ext/env.rs2
-rw-r--r--src/libsyntax_ext/format.rs106
-rw-r--r--src/libsyntax_ext/global_allocator.rs15
-rw-r--r--src/libsyntax_ext/global_asm.rs2
-rw-r--r--src/libsyntax_ext/plugin_macro_defs.rs4
-rw-r--r--src/libsyntax_ext/proc_macro_harness.rs24
-rw-r--r--src/libsyntax_ext/source_util.rs11
-rw-r--r--src/libsyntax_ext/test.rs14
-rw-r--r--src/libsyntax_ext/test_harness.rs7
-rw-r--r--src/libsyntax_ext/util.rs5
-rw-r--r--src/libsyntax_pos/hygiene.rs19
-rw-r--r--src/libsyntax_pos/lib.rs1
-rw-r--r--src/libsyntax_pos/symbol.rs65
-rw-r--r--src/libtest/tests.rs4
m---------src/llvm-project0
-rw-r--r--src/rustllvm/PassWrapper.cpp7
-rw-r--r--src/test/codegen/abi-efiapi.rs6
-rw-r--r--src/test/incremental/hashes/struct_constructors.rs4
-rw-r--r--src/test/incremental/issue-59523-on-implemented-is-not-unused.rs2
-rw-r--r--src/test/mir-opt/const_prop/return_place.rs54
-rw-r--r--src/test/mir-opt/graphviz.rs10
-rw-r--r--src/test/mir-opt/inline-closure-borrows-arg.rs2
-rw-r--r--src/test/mir-opt/inline-closure.rs2
-rw-r--r--src/test/mir-opt/match_false_edges.rs12
-rw-r--r--src/test/mir-opt/retag.rs2
-rw-r--r--src/test/mir-opt/storage_live_dead_in_statics.rs4
-rw-r--r--src/test/mir-opt/uninhabited_enum_branching.rs224
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/Makefile4
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/rustc.rs1
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/Makefile18
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/foo.rs3
-rw-r--r--src/test/run-make-fulldeps/invalid-library/Makefile4
-rw-r--r--src/test/run-make-fulldeps/long-linker-command-lines/foo.rs73
-rw-r--r--src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile3
-rw-r--r--src/test/rustdoc-ui/intra-links-warning-crlf.rs7
-rw-r--r--src/test/rustdoc-ui/intra-links-warning-crlf.stderr6
-rw-r--r--src/test/rustdoc-ui/intra-links-warning.rs33
-rw-r--r--src/test/rustdoc-ui/intra-links-warning.stderr34
-rw-r--r--src/test/rustdoc-ui/invalid-syntax.rs13
-rw-r--r--src/test/rustdoc-ui/invalid-syntax.stderr84
-rw-r--r--src/test/rustdoc/inline_cross/use_crate.rs2
-rw-r--r--src/test/ui-fulldeps/ast_stmt_expr_attr.rs29
-rw-r--r--src/test/ui-fulldeps/auxiliary/roman-numerals.rs2
-rw-r--r--src/test/ui-fulldeps/issue-15778-pass.rs12
-rw-r--r--src/test/ui-fulldeps/issue-15778-pass.stderr2
-rw-r--r--src/test/ui-fulldeps/issue-40001.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs5
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr15
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.rs6
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr17
-rw-r--r--src/test/ui-fulldeps/llvm-pass-plugin.rs2
-rw-r--r--src/test/ui-fulldeps/lto-syntax-extension.rs2
-rw-r--r--src/test/ui-fulldeps/mod_dir_path_canonicalized.rs9
-rw-r--r--src/test/ui-fulldeps/outlive-expansion-phase.rs2
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.rs10
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.stderr12
-rw-r--r--src/test/ui-fulldeps/plugin-args-1.rs2
-rw-r--r--src/test/ui-fulldeps/plugin-args-2.rs2
-rw-r--r--src/test/ui-fulldeps/plugin-args-3.rs2
-rw-r--r--src/test/ui-fulldeps/pprust-expr-roundtrip.rs9
-rw-r--r--src/test/ui-fulldeps/roman-numerals-macro.rs2
-rw-r--r--src/test/ui/abi/abi-sysv64-register-usage.rs1
-rw-r--r--src/test/ui/align-with-extern-c-fn.rs2
-rw-r--r--src/test/ui/anon-params-denied-2018.stderr8
-rw-r--r--src/test/ui/associated-type-bounds/dyn-lcsit.rs2
-rw-r--r--src/test/ui/associated-type-bounds/lcsit.rs2
-rw-r--r--src/test/ui/associated-type-bounds/type-alias.rs26
-rw-r--r--src/test/ui/associated-types/associated-types-issue-20346.stderr5
-rw-r--r--src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs16
-rw-r--r--src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr28
-rw-r--r--src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr2
-rw-r--r--src/test/ui/async-await/issue-61793.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-53249.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-54752-async-block.rs1
-rw-r--r--src/test/ui/async-await/issues/issue-54974.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-60518.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.rs3
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr12
-rw-r--r--src/test/ui/async-await/no-async-const.stderr2
-rw-r--r--src/test/ui/async-await/no-unsafe-async.stderr4
-rw-r--r--src/test/ui/attributes/register-attr-tool-fail.rs13
-rw-r--r--src/test/ui/attributes/register-attr-tool-fail.stderr42
-rw-r--r--src/test/ui/attributes/register-attr-tool-import.rs14
-rw-r--r--src/test/ui/attributes/register-attr-tool-import.stderr26
-rw-r--r--src/test/ui/attributes/register-attr-tool-prelude.rs14
-rw-r--r--src/test/ui/attributes/register-attr-tool-prelude.stderr15
-rw-r--r--src/test/ui/attributes/register-attr-tool-unused.rs10
-rw-r--r--src/test/ui/attributes/register-attr-tool-unused.stderr33
-rw-r--r--src/test/ui/attributes/register-attr-tool.rs19
-rw-r--r--src/test/ui/block-expr-precedence.rs1
-rw-r--r--src/test/ui/borrowck/borrowck-init-in-fru.stderr4
-rw-r--r--src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs2
-rw-r--r--src/test/ui/borrowck/slice-index-bounds-check-invalidation.rs82
-rw-r--r--src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr35
-rw-r--r--src/test/ui/can-begin-expr-check.stderr2
-rw-r--r--src/test/ui/closure-expected-type/issue-24421.rs2
-rw-r--r--src/test/ui/closures/closure-move-sync.rs3
-rw-r--r--src/test/ui/closures/closure-move-sync.stderr8
-rw-r--r--src/test/ui/codemap_tests/bad-format-args.stderr2
-rw-r--r--src/test/ui/codemap_tests/unicode_3.rs2
-rw-r--r--src/test/ui/coherence/coherence-all-remote.re.stderr11
-rw-r--r--src/test/ui/coherence/coherence-all-remote.rs6
-rw-r--r--src/test/ui/coherence/coherence-all-remote.stderr (renamed from src/test/ui/coherence/coherence-all-remote.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-bigint-int.rs3
-rw-r--r--src/test/ui/coherence/coherence-bigint-param.old.stderr11
-rw-r--r--src/test/ui/coherence/coherence-bigint-param.rs6
-rw-r--r--src/test/ui/coherence/coherence-bigint-param.stderr (renamed from src/test/ui/coherence/coherence-bigint-param.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-bigint-vecint.rs3
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs7
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr (renamed from src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs7
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr (renamed from src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.re.stderr13
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs6
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr (renamed from src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs7
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr (renamed from src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs7
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr (renamed from src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs7
-rw-r--r--src/test/ui/coherence/coherence-blanket-conflicts-with-specific.stderr (renamed from src/test/ui/coherence/coherence-blanket-conflicts-with-specific.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-blanket.rs3
-rw-r--r--src/test/ui/coherence/coherence-conflicting-negative-trait-impl.old.stderr21
-rw-r--r--src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs9
-rw-r--r--src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr (renamed from src/test/ui/coherence/coherence-conflicting-negative-trait-impl.re.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-covered-type-parameter.rs3
-rw-r--r--src/test/ui/coherence/coherence-cow.a.stderr11
-rw-r--r--src/test/ui/coherence/coherence-cow.b.stderr11
-rw-r--r--src/test/ui/coherence/coherence-cow.c.stderr11
-rw-r--r--src/test/ui/coherence/coherence-cow.re_b.stderr2
-rw-r--r--src/test/ui/coherence/coherence-cow.re_c.stderr2
-rw-r--r--src/test/ui/coherence/coherence-cow.rs19
-rw-r--r--src/test/ui/coherence/coherence-cross-crate-conflict.re.stderr21
-rw-r--r--src/test/ui/coherence/coherence-cross-crate-conflict.rs9
-rw-r--r--src/test/ui/coherence/coherence-cross-crate-conflict.stderr (renamed from src/test/ui/coherence/coherence-cross-crate-conflict.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-default-trait-impl.re.stderr16
-rw-r--r--src/test/ui/coherence/coherence-default-trait-impl.rs9
-rw-r--r--src/test/ui/coherence/coherence-default-trait-impl.stderr (renamed from src/test/ui/coherence/coherence-default-trait-impl.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-error-suppression.re.stderr9
-rw-r--r--src/test/ui/coherence/coherence-error-suppression.rs7
-rw-r--r--src/test/ui/coherence/coherence-error-suppression.stderr (renamed from src/test/ui/coherence/coherence-error-suppression.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence-fundamental-trait-objects.rs6
-rw-r--r--src/test/ui/coherence/coherence-fundamental-trait-objects.stderr (renamed from src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-impl-in-fn.rs3
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr11
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs7
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr (renamed from src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait.re.stderr21
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait.rs13
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait.stderr (renamed from src/test/ui/coherence/coherence-impl-trait-for-trait.old.stderr)6
-rw-r--r--src/test/ui/coherence/coherence-impls-copy.re.stderr95
-rw-r--r--src/test/ui/coherence/coherence-impls-copy.rs33
-rw-r--r--src/test/ui/coherence/coherence-impls-copy.stderr (renamed from src/test/ui/coherence/coherence-impls-copy.old.stderr)20
-rw-r--r--src/test/ui/coherence/coherence-impls-send.re.stderr43
-rw-r--r--src/test/ui/coherence/coherence-impls-send.rs15
-rw-r--r--src/test/ui/coherence/coherence-impls-send.stderr (renamed from src/test/ui/coherence/coherence-impls-send.old.stderr)8
-rw-r--r--src/test/ui/coherence/coherence-impls-sized.re.stderr73
-rw-r--r--src/test/ui/coherence/coherence-impls-sized.rs36
-rw-r--r--src/test/ui/coherence/coherence-impls-sized.stderr (renamed from src/test/ui/coherence/coherence-impls-sized.old.stderr)18
-rw-r--r--src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.re.stderr16
-rw-r--r--src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs7
-rw-r--r--src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr (renamed from src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-iterator-vec-any-elem.rs3
-rw-r--r--src/test/ui/coherence/coherence-iterator-vec.rs3
-rw-r--r--src/test/ui/coherence/coherence-lone-type-parameter.re.stderr11
-rw-r--r--src/test/ui/coherence/coherence-lone-type-parameter.rs6
-rw-r--r--src/test/ui/coherence/coherence-lone-type-parameter.stderr (renamed from src/test/ui/coherence/coherence-lone-type-parameter.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-multidispatch-tuple.rs3
-rw-r--r--src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs3
-rw-r--r--src/test/ui/coherence/coherence-negative-impls-safe.re.stderr9
-rw-r--r--src/test/ui/coherence/coherence-negative-impls-safe.rs6
-rw-r--r--src/test/ui/coherence/coherence-negative-impls-safe.stderr (renamed from src/test/ui/coherence/coherence-negative-impls-safe.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.re.stderr11
-rw-r--r--src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs7
-rw-r--r--src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr (renamed from src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-orphan.re.stderr26
-rw-r--r--src/test/ui/coherence/coherence-orphan.rs9
-rw-r--r--src/test/ui/coherence/coherence-orphan.stderr (renamed from src/test/ui/coherence/coherence-orphan.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-overlap-all-t-and-tuple.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs7
-rw-r--r--src/test/ui/coherence/coherence-overlap-all-t-and-tuple.stderr (renamed from src/test/ui/coherence/coherence-overlap-all-t-and-tuple.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-overlap-downstream-inherent.re.stderr23
-rw-r--r--src/test/ui/coherence/coherence-overlap-downstream-inherent.rs10
-rw-r--r--src/test/ui/coherence/coherence-overlap-downstream-inherent.stderr (renamed from src/test/ui/coherence/coherence-overlap-downstream-inherent.old.stderr)8
-rw-r--r--src/test/ui/coherence/coherence-overlap-downstream.re.stderr21
-rw-r--r--src/test/ui/coherence/coherence-overlap-downstream.rs10
-rw-r--r--src/test/ui/coherence/coherence-overlap-downstream.stderr (renamed from src/test/ui/coherence/coherence-overlap-downstream.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516-inherent.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs7
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516-inherent.stderr (renamed from src/test/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516.re.stderr13
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516.rs7
-rw-r--r--src/test/ui/coherence/coherence-overlap-issue-23516.stderr (renamed from src/test/ui/coherence/coherence-overlap-issue-23516.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-overlap-messages.re.stderr44
-rw-r--r--src/test/ui/coherence/coherence-overlap-messages.rs19
-rw-r--r--src/test/ui/coherence/coherence-overlap-messages.stderr (renamed from src/test/ui/coherence/coherence-overlap-messages.old.stderr)10
-rw-r--r--src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence-overlap-upstream-inherent.rs6
-rw-r--r--src/test/ui/coherence/coherence-overlap-upstream-inherent.stderr (renamed from src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr)4
-rw-r--r--src/test/ui/coherence/coherence-overlap-upstream.re.stderr13
-rw-r--r--src/test/ui/coherence/coherence-overlap-upstream.rs6
-rw-r--r--src/test/ui/coherence/coherence-overlap-upstream.stderr (renamed from src/test/ui/coherence/coherence-overlap-upstream.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-overlapping-pairs.old.stderr11
-rw-r--r--src/test/ui/coherence/coherence-overlapping-pairs.rs6
-rw-r--r--src/test/ui/coherence/coherence-overlapping-pairs.stderr (renamed from src/test/ui/coherence/coherence-overlapping-pairs.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-pair-covered-uncovered-1.old.stderr11
-rw-r--r--src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs6
-rw-r--r--src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr (renamed from src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-pair-covered-uncovered.old.stderr11
-rw-r--r--src/test/ui/coherence/coherence-pair-covered-uncovered.rs6
-rw-r--r--src/test/ui/coherence/coherence-pair-covered-uncovered.stderr (renamed from src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-orphan.rs6
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-orphan.stderr (renamed from src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-ty-param.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-ty-param.rs7
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr (renamed from src/test/ui/coherence/coherence-projection-conflict-ty-param.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict.rs7
-rw-r--r--src/test/ui/coherence/coherence-projection-conflict.stderr (renamed from src/test/ui/coherence/coherence-projection-conflict.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-projection-ok-orphan.rs3
-rw-r--r--src/test/ui/coherence/coherence-projection-ok.rs3
-rw-r--r--src/test/ui/coherence/coherence-rfc447-constrained.rs3
-rw-r--r--src/test/ui/coherence/coherence-subtyping.rs2
-rw-r--r--src/test/ui/coherence/coherence-tuple-conflict.re.stderr12
-rw-r--r--src/test/ui/coherence/coherence-tuple-conflict.rs7
-rw-r--r--src/test/ui/coherence/coherence-tuple-conflict.stderr (renamed from src/test/ui/coherence/coherence-tuple-conflict.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-vec-local-2.old.stderr11
-rw-r--r--src/test/ui/coherence/coherence-vec-local-2.rs6
-rw-r--r--src/test/ui/coherence/coherence-vec-local-2.stderr (renamed from src/test/ui/coherence/coherence-vec-local-2.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-vec-local.old.stderr14
-rw-r--r--src/test/ui/coherence/coherence-vec-local.rs6
-rw-r--r--src/test/ui/coherence/coherence-vec-local.stderr (renamed from src/test/ui/coherence/coherence-vec-local.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence-where-clause.rs3
-rw-r--r--src/test/ui/coherence/coherence_copy_like.rs3
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs3
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs3
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs6
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr (renamed from src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_struct.rs6
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_struct.stderr (renamed from src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_tuple.rs6
-rw-r--r--src/test/ui/coherence/coherence_copy_like_err_tuple.stderr (renamed from src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_inherent.re.stderr13
-rw-r--r--src/test/ui/coherence/coherence_inherent.rs7
-rw-r--r--src/test/ui/coherence/coherence_inherent.stderr (renamed from src/test/ui/coherence/coherence_inherent.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_inherent_cc.re.stderr13
-rw-r--r--src/test/ui/coherence/coherence_inherent_cc.rs6
-rw-r--r--src/test/ui/coherence/coherence_inherent_cc.stderr (renamed from src/test/ui/coherence/coherence_inherent_cc.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_local.rs3
-rw-r--r--src/test/ui/coherence/coherence_local_err_struct.re.stderr14
-rw-r--r--src/test/ui/coherence/coherence_local_err_struct.rs6
-rw-r--r--src/test/ui/coherence/coherence_local_err_struct.stderr (renamed from src/test/ui/coherence/coherence_local_err_struct.old.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_local_err_tuple.old.stderr14
-rw-r--r--src/test/ui/coherence/coherence_local_err_tuple.rs6
-rw-r--r--src/test/ui/coherence/coherence_local_err_tuple.stderr (renamed from src/test/ui/coherence/coherence_local_err_tuple.re.stderr)2
-rw-r--r--src/test/ui/coherence/coherence_local_ref.rs3
-rw-r--r--src/test/ui/coherence/impl-foreign-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-foreign.stderr2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr6
-rw-r--r--src/test/ui/coherence/impl-foreign-for-foreign[local].rs2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr4
-rw-r--r--src/test/ui/coherence/impl-foreign-for-fundamental[local].rs2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-local.rs2
-rw-r--r--src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs1
-rw-r--r--src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs1
-rw-r--r--src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr2
-rw-r--r--src/test/ui/coherence/impl-foreign[foreign]-for-local.rs2
-rw-r--r--src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr6
-rw-r--r--src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr4
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs2
-rw-r--r--src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr2
-rw-r--r--src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs1
-rw-r--r--src/test/ui/coherence/re-rebalance-coherence.rs2
-rw-r--r--src/test/ui/compare-method/reordered-type-param.stderr5
-rw-r--r--src/test/ui/const-generics/const-expression-parameter.stderr2
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr.rs8
-rw-r--r--src/test/ui/consts/const-eval/const_fn_ptr.stderr10
-rw-r--r--src/test/ui/consts/const-eval/issue-64970.rs2
-rw-r--r--src/test/ui/consts/const-eval/issue-64970.stderr8
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.stderr4
-rw-r--r--src/test/ui/consts/const-size_of-cycle.rs3
-rw-r--r--src/test/ui/consts/const-size_of-cycle.stderr6
-rw-r--r--src/test/ui/consts/const_let_promote.rs17
-rw-r--r--src/test/ui/consts/const_let_refutable.stderr4
-rw-r--r--src/test/ui/consts/issue-62045.rs2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn.stderr19
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs1
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr14
-rw-r--r--src/test/ui/consts/miri_unleashed/enum_discriminants.rs6
-rw-r--r--src/test/ui/consts/packed_pattern.rs2
-rw-r--r--src/test/ui/consts/packed_pattern2.rs2
-rw-r--r--src/test/ui/consts/promote_borrowed_field.rs12
-rw-r--r--src/test/ui/deprecation/deprecation-in-future.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Default-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Default-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Default-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Default-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-struct.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-tuple-struct.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-40006.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr8
-rw-r--r--src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs2
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr2
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr2
-rw-r--r--src/test/ui/enum-discriminant/discriminant_value.rs45
-rw-r--r--src/test/ui/error-codes/e0119/complex-impl.rs2
-rw-r--r--src/test/ui/error-codes/e0119/complex-impl.stderr15
-rw-r--r--src/test/ui/extern/extern-prelude-core.rs2
-rw-r--r--src/test/ui/extern/extern-prelude-core.stderr8
-rw-r--r--src/test/ui/extern/extern-prelude-std.rs1
-rw-r--r--src/test/ui/extern/extern-prelude-std.stderr8
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-inline.rs2
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr6
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs2
-rw-r--r--src/test/ui/feature-gate/unstable-attribute-allow-issue-none.rs13
-rw-r--r--src/test/ui/feature-gate/unstable-attribute-allow-issue-none.stderr8
-rw-r--r--src/test/ui/feature-gated-feature-in-macro-arg.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.stderr272
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-custom_attribute2.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr34
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_prelude.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-intrinsics.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-on-unimplemented.rs9
-rw-r--r--src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.rs13
-rw-r--r--src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.stderr11
-rw-r--r--src/test/ui/feature-gates/feature-gate-register_attr.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-register_attr.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-register_tool.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-register_tool.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr16
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr8
-rw-r--r--src/test/ui/generator/issue-53548-1.rs2
-rw-r--r--src/test/ui/generator/issue-53548.rs2
-rw-r--r--src/test/ui/hygiene/dollar-crate-modern.rs2
-rw-r--r--src/test/ui/hygiene/dollar-crate-modern.stderr8
-rw-r--r--src/test/ui/hygiene/generic_params.rs1
-rw-r--r--src/test/ui/hygiene/hygienic-labels-in-let.rs28
-rw-r--r--src/test/ui/hygiene/hygienic-labels-in-let.stderr54
-rw-r--r--src/test/ui/hygiene/hygienic-labels.rs31
-rw-r--r--src/test/ui/hygiene/hygienic-labels.stderr53
-rw-r--r--src/test/ui/hygiene/issue-61574-const-parameters.rs2
-rw-r--r--src/test/ui/if-ret.rs2
-rw-r--r--src/test/ui/if/ifmt-bad-arg.rs5
-rw-r--r--src/test/ui/if/ifmt-bad-arg.stderr17
-rw-r--r--src/test/ui/if/ifmt-unknown-trait.stderr4
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr4
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.rs3
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.stderr6
-rw-r--r--src/test/ui/impl-trait/issues/issue-42479.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-49376.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-52128.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs37
-rw-r--r--src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr32
-rw-r--r--src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs35
-rw-r--r--src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr30
-rw-r--r--src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs35
-rw-r--r--src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr42
-rw-r--r--src/test/ui/impl-trait/trait_type.stderr2
-rw-r--r--src/test/ui/impl-trait/universal-mismatched-type.stderr6
-rw-r--r--src/test/ui/impl-trait/universal-two-impl-traits.stderr11
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs3
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr6
-rw-r--r--src/test/ui/imports/import-prefix-macro-1.stderr2
-rw-r--r--src/test/ui/imports/issue-53140.rs2
-rw-r--r--src/test/ui/imports/issue-55811.rs2
-rw-r--r--src/test/ui/imports/issue-56263.rs2
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs3
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr2
-rw-r--r--src/test/ui/inference/inference-variable-behind-raw-pointer.rs4
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.rs3
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.stderr4
-rw-r--r--src/test/ui/invalid/invalid-variadic-function.stderr2
-rw-r--r--src/test/ui/issues/auxiliary/issue-38715-modern.rs7
-rw-r--r--src/test/ui/issues/auxiliary/issue-38715.rs7
-rw-r--r--src/test/ui/issues/issue-10396.rs2
-rw-r--r--src/test/ui/issues/issue-10456.rs2
-rw-r--r--src/test/ui/issues/issue-10763.rs2
-rw-r--r--src/test/ui/issues/issue-10853.rs2
-rw-r--r--src/test/ui/issues/issue-10902.rs2
-rw-r--r--src/test/ui/issues/issue-11384.rs2
-rw-r--r--src/test/ui/issues/issue-11592.rs2
-rw-r--r--src/test/ui/issues/issue-11612.rs2
-rw-r--r--src/test/ui/issues/issue-11869.rs2
-rw-r--r--src/test/ui/issues/issue-1251.rs2
-rw-r--r--src/test/ui/issues/issue-12729.rs2
-rw-r--r--src/test/ui/issues/issue-13105.rs2
-rw-r--r--src/test/ui/issues/issue-13167.rs2
-rw-r--r--src/test/ui/issues/issue-13214.rs2
-rw-r--r--src/test/ui/issues/issue-13405.rs2
-rw-r--r--src/test/ui/issues/issue-13703.rs2
-rw-r--r--src/test/ui/issues/issue-13775.rs2
-rw-r--r--src/test/ui/issues/issue-13837.rs2
-rw-r--r--src/test/ui/issues/issue-13853.stderr4
-rw-r--r--src/test/ui/issues/issue-14082.rs2
-rw-r--r--src/test/ui/issues/issue-14227.rs5
-rw-r--r--src/test/ui/issues/issue-14227.stderr10
-rw-r--r--src/test/ui/issues/issue-14254.rs2
-rw-r--r--src/test/ui/issues/issue-14330.rs2
-rw-r--r--src/test/ui/issues/issue-14837.rs2
-rw-r--r--src/test/ui/issues/issue-14901.rs2
-rw-r--r--src/test/ui/issues/issue-14933.rs2
-rw-r--r--src/test/ui/issues/issue-14936.rs2
-rw-r--r--src/test/ui/issues/issue-14959.rs2
-rw-r--r--src/test/ui/issues/issue-15108.rs4
-rw-r--r--src/test/ui/issues/issue-15261.rs2
-rw-r--r--src/test/ui/issues/issue-15689-2.rs2
-rw-r--r--src/test/ui/issues/issue-15735.rs2
-rw-r--r--src/test/ui/issues/issue-16441.rs1
-rw-r--r--src/test/ui/issues/issue-16538.rs3
-rw-r--r--src/test/ui/issues/issue-16538.stderr16
-rw-r--r--src/test/ui/issues/issue-16596.rs2
-rw-r--r--src/test/ui/issues/issue-16668.rs2
-rw-r--r--src/test/ui/issues/issue-17121.rs2
-rw-r--r--src/test/ui/issues/issue-17263.rs2
-rw-r--r--src/test/ui/issues/issue-17336.rs2
-rw-r--r--src/test/ui/issues/issue-17450.rs2
-rw-r--r--src/test/ui/issues/issue-17718-const-destructors.rs2
-rw-r--r--src/test/ui/issues/issue-17732.rs2
-rw-r--r--src/test/ui/issues/issue-17746.rs2
-rw-r--r--src/test/ui/issues/issue-17904.rs2
-rw-r--r--src/test/ui/issues/issue-18083.rs2
-rw-r--r--src/test/ui/issues/issue-18088.rs2
-rw-r--r--src/test/ui/issues/issue-18188.rs2
-rw-r--r--src/test/ui/issues/issue-1821.rs2
-rw-r--r--src/test/ui/issues/issue-18446-2.rs2
-rw-r--r--src/test/ui/issues/issue-1866.rs2
-rw-r--r--src/test/ui/issues/issue-18738.rs2
-rw-r--r--src/test/ui/issues/issue-18809.rs2
-rw-r--r--src/test/ui/issues/issue-18906.rs2
-rw-r--r--src/test/ui/issues/issue-18988.rs2
-rw-r--r--src/test/ui/issues/issue-19037.rs2
-rw-r--r--src/test/ui/issues/issue-19081.rs2
-rw-r--r--src/test/ui/issues/issue-19097.rs2
-rw-r--r--src/test/ui/issues/issue-19098.rs2
-rw-r--r--src/test/ui/issues/issue-19102.rs2
-rw-r--r--src/test/ui/issues/issue-19129-1.rs2
-rw-r--r--src/test/ui/issues/issue-19129-2.rs2
-rw-r--r--src/test/ui/issues/issue-19398.rs2
-rw-r--r--src/test/ui/issues/issue-19404.rs2
-rw-r--r--src/test/ui/issues/issue-19479.rs2
-rw-r--r--src/test/ui/issues/issue-19631.rs2
-rw-r--r--src/test/ui/issues/issue-19632.rs2
-rw-r--r--src/test/ui/issues/issue-19850.rs2
-rw-r--r--src/test/ui/issues/issue-19982.rs2
-rw-r--r--src/test/ui/issues/issue-20009.rs2
-rw-r--r--src/test/ui/issues/issue-20091.rs2
-rw-r--r--src/test/ui/issues/issue-20186.rs2
-rw-r--r--src/test/ui/issues/issue-20225.stderr13
-rw-r--r--src/test/ui/issues/issue-20396.rs2
-rw-r--r--src/test/ui/issues/issue-20414.rs2
-rw-r--r--src/test/ui/issues/issue-20454.rs2
-rw-r--r--src/test/ui/issues/issue-20616-1.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-2.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-3.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-4.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-5.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-6.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-7.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-8.stderr2
-rw-r--r--src/test/ui/issues/issue-20616-9.stderr2
-rw-r--r--src/test/ui/issues/issue-2063-resource.rs2
-rw-r--r--src/test/ui/issues/issue-20644.rs2
-rw-r--r--src/test/ui/issues/issue-20763-1.rs2
-rw-r--r--src/test/ui/issues/issue-20763-2.rs2
-rw-r--r--src/test/ui/issues/issue-20797.rs2
-rw-r--r--src/test/ui/issues/issue-20825-2.rs2
-rw-r--r--src/test/ui/issues/issue-21140.rs2
-rw-r--r--src/test/ui/issues/issue-21146.stderr2
-rw-r--r--src/test/ui/issues/issue-21160.rs3
-rw-r--r--src/test/ui/issues/issue-21160.stderr2
-rw-r--r--src/test/ui/issues/issue-21174-2.rs2
-rw-r--r--src/test/ui/issues/issue-21245.rs2
-rw-r--r--src/test/ui/issues/issue-21363.rs2
-rw-r--r--src/test/ui/issues/issue-21402.rs2
-rw-r--r--src/test/ui/issues/issue-21520.rs2
-rw-r--r--src/test/ui/issues/issue-21562.rs2
-rw-r--r--src/test/ui/issues/issue-21622.rs2
-rw-r--r--src/test/ui/issues/issue-21634.rs2
-rw-r--r--src/test/ui/issues/issue-21726.rs2
-rw-r--r--src/test/ui/issues/issue-21891.rs2
-rw-r--r--src/test/ui/issues/issue-22066.rs2
-rw-r--r--src/test/ui/issues/issue-22356.rs2
-rw-r--r--src/test/ui/issues/issue-22375.rs2
-rw-r--r--src/test/ui/issues/issue-22471.rs2
-rw-r--r--src/test/ui/issues/issue-22777.rs2
-rw-r--r--src/test/ui/issues/issue-22781.rs2
-rw-r--r--src/test/ui/issues/issue-22814.rs2
-rw-r--r--src/test/ui/issues/issue-22894.rs2
-rw-r--r--src/test/ui/issues/issue-2311-2.rs2
-rw-r--r--src/test/ui/issues/issue-2311.rs2
-rw-r--r--src/test/ui/issues/issue-2312.rs2
-rw-r--r--src/test/ui/issues/issue-23406.rs2
-rw-r--r--src/test/ui/issues/issue-23442.rs2
-rw-r--r--src/test/ui/issues/issue-23550.rs2
-rw-r--r--src/test/ui/issues/issue-23649-3.rs2
-rw-r--r--src/test/ui/issues/issue-24085.rs2
-rw-r--r--src/test/ui/issues/issue-24161.rs2
-rw-r--r--src/test/ui/issues/issue-24204.stderr2
-rw-r--r--src/test/ui/issues/issue-24227.rs2
-rw-r--r--src/test/ui/issues/issue-24338.rs2
-rw-r--r--src/test/ui/issues/issue-24389.rs2
-rw-r--r--src/test/ui/issues/issue-24434.rs2
-rw-r--r--src/test/ui/issues/issue-2487-a.rs2
-rw-r--r--src/test/ui/issues/issue-2502.rs2
-rw-r--r--src/test/ui/issues/issue-25180.rs2
-rw-r--r--src/test/ui/issues/issue-25394.rs2
-rw-r--r--src/test/ui/issues/issue-25579.rs2
-rw-r--r--src/test/ui/issues/issue-26095.rs2
-rw-r--r--src/test/ui/issues/issue-2611-3.rs2
-rw-r--r--src/test/ui/issues/issue-26205.rs2
-rw-r--r--src/test/ui/issues/issue-26646.rs2
-rw-r--r--src/test/ui/issues/issue-26997.rs3
-rw-r--r--src/test/ui/issues/issue-27033.rs3
-rw-r--r--src/test/ui/issues/issue-27033.stderr4
-rw-r--r--src/test/ui/issues/issue-27105.rs2
-rw-r--r--src/test/ui/issues/issue-27281.rs2
-rw-r--r--src/test/ui/issues/issue-2748-a.rs2
-rw-r--r--src/test/ui/issues/issue-27583.rs2
-rw-r--r--src/test/ui/issues/issue-27889.rs2
-rw-r--r--src/test/ui/issues/issue-2804-2.rs2
-rw-r--r--src/test/ui/issues/issue-28279.rs2
-rw-r--r--src/test/ui/issues/issue-28324.rs5
-rw-r--r--src/test/ui/issues/issue-28324.stderr10
-rw-r--r--src/test/ui/issues/issue-28561.rs2
-rw-r--r--src/test/ui/issues/issue-28600.rs3
-rw-r--r--src/test/ui/issues/issue-28822.rs2
-rw-r--r--src/test/ui/issues/issue-28871.rs2
-rw-r--r--src/test/ui/issues/issue-28936.rs2
-rw-r--r--src/test/ui/issues/issue-28999.rs2
-rw-r--r--src/test/ui/issues/issue-29030.rs2
-rw-r--r--src/test/ui/issues/issue-29037.rs2
-rw-r--r--src/test/ui/issues/issue-2904.rs2
-rw-r--r--src/test/ui/issues/issue-29048.rs2
-rw-r--r--src/test/ui/issues/issue-29071.rs2
-rw-r--r--src/test/ui/issues/issue-29276.rs2
-rw-r--r--src/test/ui/issues/issue-2951.rs2
-rw-r--r--src/test/ui/issues/issue-2951.stderr7
-rw-r--r--src/test/ui/issues/issue-29516.rs2
-rw-r--r--src/test/ui/issues/issue-29540.rs2
-rw-r--r--src/test/ui/issues/issue-29710.rs2
-rw-r--r--src/test/ui/issues/issue-29740.rs2
-rw-r--r--src/test/ui/issues/issue-29743.rs3
-rw-r--r--src/test/ui/issues/issue-31260.rs2
-rw-r--r--src/test/ui/issues/issue-3149.rs2
-rw-r--r--src/test/ui/issues/issue-31597.rs2
-rw-r--r--src/test/ui/issues/issue-32324.rs2
-rw-r--r--src/test/ui/issues/issue-32995-2.rs5
-rw-r--r--src/test/ui/issues/issue-32995-2.stderr29
-rw-r--r--src/test/ui/issues/issue-32995.rs9
-rw-r--r--src/test/ui/issues/issue-32995.stderr65
-rw-r--r--src/test/ui/issues/issue-33140-traitobject-crate.rs8
-rw-r--r--src/test/ui/issues/issue-33140-traitobject-crate.stderr7
-rw-r--r--src/test/ui/issues/issue-33264.rs2
-rw-r--r--src/test/ui/issues/issue-33287.rs2
-rw-r--r--src/test/ui/issues/issue-3344.stderr2
-rw-r--r--src/test/ui/issues/issue-33903.rs2
-rw-r--r--src/test/ui/issues/issue-34194.rs2
-rw-r--r--src/test/ui/issues/issue-3424.rs2
-rw-r--r--src/test/ui/issues/issue-34334.stderr2
-rw-r--r--src/test/ui/issues/issue-34751.rs2
-rw-r--r--src/test/ui/issues/issue-34780.rs2
-rw-r--r--src/test/ui/issues/issue-35376.rs2
-rw-r--r--src/test/ui/issues/issue-35546.rs2
-rw-r--r--src/test/ui/issues/issue-3563-2.rs2
-rw-r--r--src/test/ui/issues/issue-36075.rs2
-rw-r--r--src/test/ui/issues/issue-3609.rs2
-rw-r--r--src/test/ui/issues/issue-36744-without-calls.rs2
-rw-r--r--src/test/ui/issues/issue-37323.rs3
-rw-r--r--src/test/ui/issues/issue-37655.rs2
-rw-r--r--src/test/ui/issues/issue-37725.rs2
-rw-r--r--src/test/ui/issues/issue-37733.rs2
-rw-r--r--src/test/ui/issues/issue-38715-rpass.rs15
-rw-r--r--src/test/ui/issues/issue-38715.rs1
-rw-r--r--src/test/ui/issues/issue-38715.stderr3
-rw-r--r--src/test/ui/issues/issue-38727.rs2
-rw-r--r--src/test/ui/issues/issue-3874.rs2
-rw-r--r--src/test/ui/issues/issue-38763.rs1
-rw-r--r--src/test/ui/issues/issue-38875/issue-38875.rs2
-rw-r--r--src/test/ui/issues/issue-3888-2.rs2
-rw-r--r--src/test/ui/issues/issue-39089.rs2
-rw-r--r--src/test/ui/issues/issue-39467.rs2
-rw-r--r--src/test/ui/issues/issue-39616.stderr2
-rw-r--r--src/test/ui/issues/issue-39720.rs4
-rw-r--r--src/test/ui/issues/issue-3979-2.rs2
-rw-r--r--src/test/ui/issues/issue-39848.stderr2
-rw-r--r--src/test/ui/issues/issue-3991.rs2
-rw-r--r--src/test/ui/issues/issue-39984.rs2
-rw-r--r--src/test/ui/issues/issue-40136.rs2
-rw-r--r--src/test/ui/issues/issue-4025.rs2
-rw-r--r--src/test/ui/issues/issue-40510-2.rs2
-rw-r--r--src/test/ui/issues/issue-40510-4.rs2
-rw-r--r--src/test/ui/issues/issue-40962.rs2
-rw-r--r--src/test/ui/issues/issue-41272.rs2
-rw-r--r--src/test/ui/issues/issue-41298.rs2
-rw-r--r--src/test/ui/issues/issue-41628.rs2
-rw-r--r--src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs2
-rw-r--r--src/test/ui/issues/issue-41998.rs2
-rw-r--r--src/test/ui/issues/issue-42467.rs2
-rw-r--r--src/test/ui/issues/issue-42956.rs2
-rw-r--r--src/test/ui/issues/issue-43057.rs2
-rw-r--r--src/test/ui/issues/issue-43357.rs2
-rw-r--r--src/test/ui/issues/issue-43398.rs8
-rw-r--r--src/test/ui/issues/issue-43483.rs2
-rw-r--r--src/test/ui/issues/issue-44005.rs2
-rw-r--r--src/test/ui/issues/issue-44021.stderr2
-rw-r--r--src/test/ui/issues/issue-44056.rs2
-rw-r--r--src/test/ui/issues/issue-44247.rs2
-rw-r--r--src/test/ui/issues/issue-44373-2.rs2
-rw-r--r--src/test/ui/issues/issue-4464.rs2
-rw-r--r--src/test/ui/issues/issue-44730.rs2
-rw-r--r--src/test/ui/issues/issue-44851.rs2
-rw-r--r--src/test/ui/issues/issue-45425.rs2
-rw-r--r--src/test/ui/issues/issue-46959.rs2
-rw-r--r--src/test/ui/issues/issue-46964.rs2
-rw-r--r--src/test/ui/issues/issue-47094.rs6
-rw-r--r--src/test/ui/issues/issue-47309.rs2
-rw-r--r--src/test/ui/issues/issue-47673.rs2
-rw-r--r--src/test/ui/issues/issue-47703-1.rs2
-rw-r--r--src/test/ui/issues/issue-47703-tuple.rs2
-rw-r--r--src/test/ui/issues/issue-47703.rs2
-rw-r--r--src/test/ui/issues/issue-47722.rs2
-rw-r--r--src/test/ui/issues/issue-47789.rs2
-rw-r--r--src/test/ui/issues/issue-4830.rs2
-rw-r--r--src/test/ui/issues/issue-48551.rs2
-rw-r--r--src/test/ui/issues/issue-49556.rs2
-rw-r--r--src/test/ui/issues/issue-49579.rs2
-rw-r--r--src/test/ui/issues/issue-50187.rs2
-rw-r--r--src/test/ui/issues/issue-50411.rs2
-rw-r--r--src/test/ui/issues/issue-50471.rs2
-rw-r--r--src/test/ui/issues/issue-50518.rs2
-rw-r--r--src/test/ui/issues/issue-50761.rs2
-rw-r--r--src/test/ui/issues/issue-50993.rs2
-rw-r--r--src/test/ui/issues/issue-51582.rs2
-rw-r--r--src/test/ui/issues/issue-51655.rs2
-rw-r--r--src/test/ui/issues/issue-51907.rs2
-rw-r--r--src/test/ui/issues/issue-51947.rs2
-rw-r--r--src/test/ui/issues/issue-52057.rs1
-rw-r--r--src/test/ui/issues/issue-52057.stderr8
-rw-r--r--src/test/ui/issues/issue-52496.stderr2
-rw-r--r--src/test/ui/issues/issue-52992.rs2
-rw-r--r--src/test/ui/issues/issue-53419.rs2
-rw-r--r--src/test/ui/issues/issue-5353.rs2
-rw-r--r--src/test/ui/issues/issue-53568.rs2
-rw-r--r--src/test/ui/issues/issue-53675-a-test-called-panic.rs2
-rw-r--r--src/test/ui/issues/issue-53912.rs2
-rw-r--r--src/test/ui/issues/issue-54387.rs2
-rw-r--r--src/test/ui/issues/issue-54521-1.rs2
-rw-r--r--src/test/ui/issues/issue-54943-1.rs2
-rw-r--r--src/test/ui/issues/issue-54943-2.rs2
-rw-r--r--src/test/ui/issues/issue-54943-3.rs2
-rw-r--r--src/test/ui/issues/issue-5500-1.rs2
-rw-r--r--src/test/ui/issues/issue-5572.rs2
-rw-r--r--src/test/ui/issues/issue-56128.rs2
-rw-r--r--src/test/ui/issues/issue-56202.rs2
-rw-r--r--src/test/ui/issues/issue-56411-aux.rs2
-rw-r--r--src/test/ui/issues/issue-57156.rs2
-rw-r--r--src/test/ui/issues/issue-57162.rs2
-rw-r--r--src/test/ui/issues/issue-57399-self-return-impl-trait.rs2
-rw-r--r--src/test/ui/issues/issue-57399-self-return-impl-trait.stderr8
-rw-r--r--src/test/ui/issues/issue-57410-1.rs2
-rw-r--r--src/test/ui/issues/issue-57410.rs2
-rw-r--r--src/test/ui/issues/issue-5754.rs2
-rw-r--r--src/test/ui/issues/issue-5884.rs2
-rw-r--r--src/test/ui/issues/issue-58856-2.stderr2
-rw-r--r--src/test/ui/issues/issue-5900.rs2
-rw-r--r--src/test/ui/issues/issue-5950.rs2
-rw-r--r--src/test/ui/issues/issue-60075.stderr2
-rw-r--r--src/test/ui/issues/issue-60662.rs2
-rw-r--r--src/test/ui/issues/issue-60662.stdout2
-rw-r--r--src/test/ui/issues/issue-6341.rs2
-rw-r--r--src/test/ui/issues/issue-6470.rs2
-rw-r--r--src/test/ui/issues/issue-65462.rs15
-rw-r--r--src/test/ui/issues/issue-6557.rs2
-rw-r--r--src/test/ui/issues/issue-6898.rs2
-rw-r--r--src/test/ui/issues/issue-6991.rs2
-rw-r--r--src/test/ui/issues/issue-7268.rs2
-rw-r--r--src/test/ui/issues/issue-7607-2.rs2
-rw-r--r--src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs2
-rw-r--r--src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs2
-rw-r--r--src/test/ui/issues/issue-8398.rs2
-rw-r--r--src/test/ui/issues/issue-8521.rs2
-rw-r--r--src/test/ui/issues/issue-8578.rs2
-rw-r--r--src/test/ui/issues/issue-9110.rs2
-rw-r--r--src/test/ui/issues/issue-9243.rs2
-rw-r--r--src/test/ui/issues/issue-9249.rs2
-rw-r--r--src/test/ui/issues/issue-9719.rs2
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.fixed33
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.rs33
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.stderr37
-rw-r--r--src/test/ui/label/label_break_value_illegal_uses.stderr4
-rw-r--r--src/test/ui/lint/command-line-lint-group-warn.rs3
-rw-r--r--src/test/ui/lint/dead-code/alias-in-pat.rs (renamed from src/test/ui/dead-code-alias-in-pat.rs)0
-rw-r--r--src/test/ui/lint/dead-code/associated-type.rs (renamed from src/test/ui/lint-dead-code-associated-type.rs)0
-rw-r--r--src/test/ui/lint/dead-code/basic.rs (renamed from src/test/ui/fail-no-dead-code.rs)0
-rw-r--r--src/test/ui/lint/dead-code/basic.stderr (renamed from src/test/ui/fail-no-dead-code.stderr)6
-rw-r--r--src/test/ui/lint/dead-code/closure-bang.rs (renamed from src/test/ui/dead-code-closure-bang.rs)0
-rw-r--r--src/test/ui/lint/dead-code/const-and-self.rs (renamed from src/test/ui/lint/lint-dead-code-const-and-self.rs)0
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-enum.rs (renamed from src/test/ui/lint/lint-dead-code-empty-unused-enum.rs)0
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-enum.stderr (renamed from src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr)6
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-public-enum.rs (renamed from src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs)0
-rw-r--r--src/test/ui/lint/dead-code/enum-variants.rs (renamed from src/test/ui/lint-dead-code-variant.rs)0
-rw-r--r--src/test/ui/lint/dead-code/impl-trait.rs (renamed from src/test/ui/lint/lint-dead-code-impl-trait.rs)0
-rw-r--r--src/test/ui/lint/dead-code/impl-trait.stderr (renamed from src/test/ui/lint/lint-dead-code-impl-trait.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/leading-underscore.rs (renamed from src/test/ui/dead-code-leading-underscore.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-1.rs (renamed from src/test/ui/lint/lint-dead-code-1.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-1.stderr (renamed from src/test/ui/lint/lint-dead-code-1.stderr)28
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-2.rs (renamed from src/test/ui/lint/lint-dead-code-2.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-2.stderr (renamed from src/test/ui/lint/lint-dead-code-2.stderr)12
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.rs (renamed from src/test/ui/lint/lint-dead-code-3.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.stderr (renamed from src/test/ui/lint/lint-dead-code-3.stderr)12
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-4.rs (renamed from src/test/ui/lint/lint-dead-code-4.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-4.stderr (renamed from src/test/ui/lint/lint-dead-code-4.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-5.rs (renamed from src/test/ui/lint/lint-dead-code-5.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-5.stderr (renamed from src/test/ui/lint/lint-dead-code-5.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/newline-span.rs19
-rw-r--r--src/test/ui/lint/dead-code/newline-span.stderr26
-rw-r--r--src/test/ui/lint/dead-code/tuple-struct-field.rs (renamed from src/test/ui/dead-code-tuple-struct-field.rs)0
-rw-r--r--src/test/ui/lint/dead-code/type-alias.rs (renamed from src/test/ui/lint/lint-dead-code-type-alias.rs)0
-rw-r--r--src/test/ui/lint/dead-code/type-alias.stderr (renamed from src/test/ui/lint/lint-dead-code-type-alias.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/unused-enum.rs (renamed from src/test/ui/lint/lint-dead-code-unused-enum.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-enum.stderr (renamed from src/test/ui/lint/lint-dead-code-unused-enum.stderr)14
-rw-r--r--src/test/ui/lint/dead-code/unused-struct-variant.rs (renamed from src/test/ui/lint/lint-dead-code-unused-variant.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-struct-variant.stderr (renamed from src/test/ui/lint/lint-dead-code-unused-variant.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/unused-variant-pub.rs (renamed from src/test/ui/lint/lint-dead-code-unused-variant-pub.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.rs (renamed from src/test/ui/lint/lint-dead-code-variant.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.stderr (renamed from src/test/ui/lint/lint-dead-code-variant.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/with-core-crate.rs (renamed from src/test/ui/fail-no-dead-code-core.rs)0
-rw-r--r--src/test/ui/lint/dead-code/with-core-crate.stderr (renamed from src/test/ui/fail-no-dead-code-core.stderr)6
-rw-r--r--src/test/ui/lint/dead-code/with-impl.rs (renamed from src/test/ui/dead-code-impl.rs)0
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs29
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr26
-rw-r--r--src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs2
-rw-r--r--src/test/ui/lint/issue-54099-camel-case-underscore-types.rs2
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.rs186
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.stderr247
-rw-r--r--src/test/ui/lint/must-use-ops.rs44
-rw-r--r--src/test/ui/lint/not_found.rs10
-rw-r--r--src/test/ui/lint/not_found.stderr4
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.rs9
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.stderr129
-rw-r--r--src/test/ui/lint/unreachable_pub-pub_crate.rs29
-rw-r--r--src/test/ui/lint/unreachable_pub-pub_crate.stderr10
-rw-r--r--src/test/ui/lint/unreachable_pub.rs28
-rw-r--r--src/test/ui/lint/unreachable_pub.stderr26
-rw-r--r--src/test/ui/lint/unused_import_warning_issue_45268.rs3
-rw-r--r--src/test/ui/macro_backtrace/main.stderr6
-rw-r--r--src/test/ui/macros/assert-trailing-junk.stderr4
-rw-r--r--src/test/ui/macros/issue-54441.stderr2
-rw-r--r--src/test/ui/macros/macro-lifetime-used-with-labels.rs2
-rw-r--r--src/test/ui/macros/macro-path-prelude-pass.rs4
-rw-r--r--src/test/ui/macros/macro-path-prelude-pass.stderr8
-rw-r--r--src/test/ui/macros/macro-use-all-and-none.rs2
-rw-r--r--src/test/ui/malformed/malformed-derive-entry.stderr4
-rw-r--r--src/test/ui/malformed/malformed-regressions.rs26
-rw-r--r--src/test/ui/malformed/malformed-regressions.stderr24
-rw-r--r--src/test/ui/mir/mir_assign_eval_order.rs67
-rw-r--r--src/test/ui/mir/mir_cast_fn_ret.rs2
-rw-r--r--src/test/ui/mir/mir_codegen_calls.rs1
-rw-r--r--src/test/ui/mismatched_types/issue-35030.stderr7
-rw-r--r--src/test/ui/mismatched_types/recovered-block.stderr2
-rw-r--r--src/test/ui/missing/missing-comma-in-match.fixed2
-rw-r--r--src/test/ui/missing/missing-comma-in-match.rs2
-rw-r--r--src/test/ui/missing/missing-comma-in-match.stderr2
-rw-r--r--src/test/ui/missing/missing-items/m2.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs2
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr8
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr4
-rw-r--r--src/test/ui/nll/issue-16223.rs2
-rw-r--r--src/test/ui/nll/issue-21114-ebfull.rs2
-rw-r--r--src/test/ui/nll/issue-21114-kixunil.rs2
-rw-r--r--src/test/ui/nll/issue-22323-temp-destruction.rs2
-rw-r--r--src/test/ui/nll/issue-30104.rs2
-rw-r--r--src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs2
-rw-r--r--src/test/ui/nll/issue-43058.rs2
-rw-r--r--src/test/ui/nll/issue-47022.rs2
-rw-r--r--src/test/ui/nll/issue-50716-1.rs2
-rw-r--r--src/test/ui/nll/issue-51351.rs2
-rw-r--r--src/test/ui/nll/issue-52078.rs2
-rw-r--r--src/test/ui/nll/issue-52534-2.stderr4
-rw-r--r--src/test/ui/nll/issue-53119.rs2
-rw-r--r--src/test/ui/nll/issue-53570.rs2
-rw-r--r--src/test/ui/nll/issue-55344.rs2
-rw-r--r--src/test/ui/nll/issue-55651.rs2
-rw-r--r--src/test/ui/nll/issue-57280-1.rs2
-rw-r--r--src/test/ui/nll/issue-57280.rs2
-rw-r--r--src/test/ui/nll/issue-61311-normalize.rs2
-rw-r--r--src/test/ui/nll/issue-61320-normalize.rs2
-rw-r--r--src/test/ui/nll/relate_tys/issue-48071.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/issue-53789-1.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/issue-53789-2.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/issue-55756.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr16
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr18
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr20
-rw-r--r--src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr20
-rw-r--r--src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr34
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr10
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr4
-rw-r--r--src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr20
-rw-r--r--src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs2
-rw-r--r--src/test/ui/no-send-res-ports.rs3
-rw-r--r--src/test/ui/no-send-res-ports.stderr6
-rw-r--r--src/test/ui/no-warn-on-field-replace-issue-34101.rs2
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.rs2
-rw-r--r--src/test/ui/on-unimplemented/expected-comma-found-token.rs2
-rw-r--r--src/test/ui/on-unimplemented/expected-comma-found-token.stderr2
-rw-r--r--src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs8
-rw-r--r--src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr (renamed from src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr)8
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.rs2
-rw-r--r--src/test/ui/on-unimplemented/on-impl.rs2
-rw-r--r--src/test/ui/on-unimplemented/on-trait.rs2
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.rs2
-rw-r--r--src/test/ui/parser/assoc-oddities-1.stderr2
-rw-r--r--src/test/ui/parser/assoc-oddities-2.stderr2
-rw-r--r--src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr2
-rw-r--r--src/test/ui/parser/attr-bad-meta.stderr2
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.rs4
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.stderr4
-rw-r--r--src/test/ui/parser/bad-match.stderr2
-rw-r--r--src/test/ui/parser/bad-name.stderr2
-rw-r--r--src/test/ui/parser/better-expected.stderr2
-rw-r--r--src/test/ui/parser/bounds-lifetime-1.stderr2
-rw-r--r--src/test/ui/parser/bounds-lifetime-2.stderr2
-rw-r--r--src/test/ui/parser/bounds-lifetime-where.stderr2
-rw-r--r--src/test/ui/parser/bounds-lifetime.stderr2
-rw-r--r--src/test/ui/parser/bounds-type-where.stderr2
-rw-r--r--src/test/ui/parser/class-implements-bad-trait.stderr2
-rw-r--r--src/test/ui/parser/closure-return-syntax.stderr2
-rw-r--r--src/test/ui/parser/default.stderr2
-rw-r--r--src/test/ui/parser/duplicate-visibility.stderr2
-rw-r--r--src/test/ui/parser/empty-impl-semicolon.stderr2
-rw-r--r--src/test/ui/parser/extern-abi-from-mac-literal-frag.rs26
-rw-r--r--src/test/ui/parser/extern-abi-raw-strings.rs13
-rw-r--r--src/test/ui/parser/extern-abi-string-escaping.rs13
-rw-r--r--src/test/ui/parser/extern-abi-syntactic.rs17
-rw-r--r--src/test/ui/parser/extern-crate-unexpected-token.stderr2
-rw-r--r--src/test/ui/parser/extern-expected-fn-or-brace.stderr2
-rw-r--r--src/test/ui/parser/extern-foreign-crate.stderr2
-rw-r--r--src/test/ui/parser/inverted-parameters.stderr12
-rw-r--r--src/test/ui/parser/issue-15980.rs2
-rw-r--r--src/test/ui/parser/issue-15980.stderr2
-rw-r--r--src/test/ui/parser/issue-17904.stderr2
-rw-r--r--src/test/ui/parser/issue-19096.stderr4
-rw-r--r--src/test/ui/parser/issue-20711-2.stderr2
-rw-r--r--src/test/ui/parser/issue-20711.stderr2
-rw-r--r--src/test/ui/parser/issue-22647.stderr2
-rw-r--r--src/test/ui/parser/issue-22712.stderr2
-rw-r--r--src/test/ui/parser/issue-24197.stderr2
-rw-r--r--src/test/ui/parser/issue-24375.stderr2
-rw-r--r--src/test/ui/parser/issue-24780.stderr2
-rw-r--r--src/test/ui/parser/issue-32446.stderr2
-rw-r--r--src/test/ui/parser/issue-33455.stderr2
-rw-r--r--src/test/ui/parser/issue-41155.stderr2
-rw-r--r--src/test/ui/parser/issue-62660.stderr2
-rw-r--r--src/test/ui/parser/issue-62973.stderr6
-rw-r--r--src/test/ui/parser/issue-63135.stderr8
-rw-r--r--src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs14
-rw-r--r--src/test/ui/parser/lifetime-semicolon.stderr2
-rw-r--r--src/test/ui/parser/macro/issue-37234.stderr2
-rw-r--r--src/test/ui/parser/macro/macro-doc-comments-2.stderr2
-rw-r--r--src/test/ui/parser/macro/macro-incomplete-parse.stderr2
-rw-r--r--src/test/ui/parser/macro/trait-non-item-macros.stderr2
-rw-r--r--src/test/ui/parser/macros-no-semicolon.stderr2
-rw-r--r--src/test/ui/parser/match-refactor-to-expr.rs2
-rw-r--r--src/test/ui/parser/match-refactor-to-expr.stderr2
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr2
-rw-r--r--src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr2
-rw-r--r--src/test/ui/parser/missing_right_paren.rs3
-rw-r--r--src/test/ui/parser/missing_right_paren.stderr17
-rw-r--r--src/test/ui/parser/multitrait.stderr2
-rw-r--r--src/test/ui/parser/not-a-pred.stderr2
-rw-r--r--src/test/ui/parser/omitted-arg-in-item-fn.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-1.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-2.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-3.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-4.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-5.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.stderr2
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.stderr2
-rw-r--r--src/test/ui/parser/pat-ranges-1.stderr2
-rw-r--r--src/test/ui/parser/pat-ranges-2.stderr2
-rw-r--r--src/test/ui/parser/pat-ranges-3.stderr2
-rw-r--r--src/test/ui/parser/pat-ranges-4.stderr2
-rw-r--r--src/test/ui/parser/range-3.stderr2
-rw-r--r--src/test/ui/parser/range-4.stderr2
-rw-r--r--src/test/ui/parser/raw-str-unbalanced.stderr2
-rw-r--r--src/test/ui/parser/raw/raw-literal-keywords.stderr6
-rw-r--r--src/test/ui/parser/recover-enum2.stderr2
-rw-r--r--src/test/ui/parser/recover-for-loop-parens-around-head.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-closure-lifetime.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-enum-newtype.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-fixed-vec.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-ptr-lifetime.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-static-fn.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-with-1.stderr2
-rw-r--r--src/test/ui/parser/removed-syntax-with-2.stderr2
-rw-r--r--src/test/ui/parser/underscore_item_not_const.stderr2
-rw-r--r--src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr2
-rw-r--r--src/test/ui/path-lookahead.rs8
-rw-r--r--src/test/ui/path-lookahead.stderr24
-rw-r--r--src/test/ui/pathless-extern-ok.rs9
-rw-r--r--src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/match-slice-patterns.rs2
-rw-r--r--src/test/ui/pattern/usefulness/match-slice-patterns.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.rs2
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.stderr4
-rw-r--r--src/test/ui/pattern/usefulness/slice-pattern-const-2.rs (renamed from src/test/ui/pattern/slice-pattern-const-2.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr (renamed from src/test/ui/pattern/slice-pattern-const-2.stderr)0
-rw-r--r--src/test/ui/pattern/usefulness/slice-pattern-const-3.rs (renamed from src/test/ui/pattern/slice-pattern-const-3.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr (renamed from src/test/ui/pattern/slice-pattern-const-3.stderr)0
-rw-r--r--src/test/ui/pattern/usefulness/slice-pattern-const.rs (renamed from src/test/ui/pattern/slice-pattern-const.rs)0
-rw-r--r--src/test/ui/pattern/usefulness/slice-pattern-const.stderr (renamed from src/test/ui/pattern/slice-pattern-const.stderr)0
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs75
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr91
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs27
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-reachability.rs26
-rw-r--r--src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr44
-rw-r--r--src/test/ui/privacy/issue-57264-1.rs2
-rw-r--r--src/test/ui/privacy/issue-57264-2.rs2
-rw-r--r--src/test/ui/privacy/legacy-ctor-visibility.rs7
-rw-r--r--src/test/ui/privacy/legacy-ctor-visibility.stderr17
-rw-r--r--src/test/ui/proc-macro/attribute.stderr24
-rw-r--r--src/test/ui/proc-macro/dollar-crate-issue-57089.rs2
-rw-r--r--src/test/ui/proc-macro/expand-to-unstable-2.rs4
-rw-r--r--src/test/ui/proc-macro/expand-to-unstable-2.stderr2
-rw-r--r--src/test/ui/proc-macro/exports.stderr8
-rw-r--r--src/test/ui/proc-macro/issue-41211.rs6
-rw-r--r--src/test/ui/proc-macro/issue-41211.stderr19
-rw-r--r--src/test/ui/proc-macro/pub-at-crate-root.rs2
-rw-r--r--src/test/ui/proc-macro/pub-at-crate-root.stderr2
-rw-r--r--src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs2
-rw-r--r--src/test/ui/removing-extern-crate.fixed11
-rw-r--r--src/test/ui/removing-extern-crate.rs11
-rw-r--r--src/test/ui/removing-extern-crate.stderr8
-rw-r--r--src/test/ui/resolve/issue-57523.rs2
-rw-r--r--src/test/ui/resolve/token-error-correct-3.stderr2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs3
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr2
-rw-r--r--src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs14
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/issue-54467.rs2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr2
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr2
-rw-r--r--src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr2
-rw-r--r--src/test/ui/rust-2018/remove-extern-crate.fixed4
-rw-r--r--src/test/ui/rust-2018/remove-extern-crate.rs4
-rw-r--r--src/test/ui/rust-2018/try-ident.fixed4
-rw-r--r--src/test/ui/rust-2018/try-ident.rs4
-rw-r--r--src/test/ui/rust-2018/try-ident.stderr2
-rw-r--r--src/test/ui/rust-2018/try-macro.fixed5
-rw-r--r--src/test/ui/rust-2018/try-macro.rs5
-rw-r--r--src/test/ui/rust-2018/try-macro.stderr2
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs2
-rw-r--r--src/test/ui/safe-extern-statics.rs6
-rw-r--r--src/test/ui/safe-extern-statics.stderr34
-rw-r--r--src/test/ui/similar-tokens.stderr2
-rw-r--r--src/test/ui/span/impl-wrong-item-for-trait.stderr2
-rw-r--r--src/test/ui/span/issue-23729.stderr2
-rw-r--r--src/test/ui/span/issue-23827.stderr2
-rw-r--r--src/test/ui/span/issue-24356.stderr2
-rw-r--r--src/test/ui/span/issue-24690.rs2
-rw-r--r--src/test/ui/span/issue-34264.stderr6
-rw-r--r--src/test/ui/span/issue-36530.rs4
-rw-r--r--src/test/ui/span/issue-36530.stderr2
-rw-r--r--src/test/ui/span/issue-36537.stderr4
-rw-r--r--src/test/ui/span/unused-warning-point-at-identifier.rs (renamed from src/test/ui/span/unused-warning-point-at-signature.rs)4
-rw-r--r--src/test/ui/span/unused-warning-point-at-identifier.stderr (renamed from src/test/ui/span/unused-warning-point-at-signature.stderr)25
-rw-r--r--src/test/ui/structs/struct-path-self-type-mismatch.stderr15
-rw-r--r--src/test/ui/structs/struct-path-self.stderr6
-rw-r--r--src/test/ui/suggestions/issue-57672.rs2
-rw-r--r--src/test/ui/suggestions/issue-64252-self-type.stderr4
-rw-r--r--src/test/ui/suggestions/let-binding-init-expr-as-ty.rs2
-rw-r--r--src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr19
-rw-r--r--src/test/ui/suggestions/missing-trait-item.fixed20
-rw-r--r--src/test/ui/suggestions/missing-trait-item.rs16
-rw-r--r--src/test/ui/suggestions/missing-trait-item.stderr25
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path-2.rs5
-rw-r--r--src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr13
-rw-r--r--src/test/ui/test-attrs/test-on-macro.rs4
-rw-r--r--src/test/ui/test-attrs/test-warns-dead-code.stderr4
-rw-r--r--src/test/ui/thread-local-not-in-prelude.rs1
-rw-r--r--src/test/ui/traits/trait-suggest-where-clause.rs3
-rw-r--r--src/test/ui/traits/trait-suggest-where-clause.stderr14
-rw-r--r--src/test/ui/traits/traits-issue-23003-overflow.rs2
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs10
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr8
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs10
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr4
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs3
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr4
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs2
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs25
-rw-r--r--src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr16
-rw-r--r--src/test/ui/try-block/try-block-unreachable-code-lint.rs6
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test.stderr2
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test2.stderr2
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test3.stderr2
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr30
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-57866.rs2
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs2
-rw-r--r--src/test/ui/type/ascription/issue-34255-1.rs1
-rw-r--r--src/test/ui/type/ascription/issue-34255-1.stderr10
-rw-r--r--src/test/ui/type/ascription/issue-54516.stderr2
-rw-r--r--src/test/ui/type/ascription/issue-60933.stderr2
-rw-r--r--src/test/ui/type/type-error-break-tail.rs8
-rw-r--r--src/test/ui/type/type-error-break-tail.stderr18
-rw-r--r--src/test/ui/type/type-parameter-names.rs2
-rw-r--r--src/test/ui/type/type-parameter-names.stderr7
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-1.rs2
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-1.stderr12
-rw-r--r--src/test/ui/type/type-params-in-different-spaces-3.stderr14
-rw-r--r--src/test/ui/type_length_limit.rs3
-rw-r--r--src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs2
-rw-r--r--src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr4
-rw-r--r--src/test/ui/unreachable-code-ret.rs (renamed from src/test/ui/dead-code-ret.rs)0
-rw-r--r--src/test/ui/unreachable-code-ret.stderr (renamed from src/test/ui/dead-code-ret.stderr)4
-rw-r--r--src/test/ui/unsafe/unsafe-block-without-braces.stderr2
-rw-r--r--src/tools/build-manifest/Cargo.toml1
-rw-r--r--src/tools/build-manifest/src/main.rs23
m---------src/tools/clippy18
-rw-r--r--src/tools/compiletest/src/runtest.rs13
m---------src/tools/miri14
-rw-r--r--src/tools/tidy/src/style.rs17
1546 files changed, 11346 insertions, 9603 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 37a217d2a04..bd1d49fb24d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -105,7 +105,7 @@ contributions to the compiler and the standard library. It also lists some
 really useful commands to the build system (`./x.py`), which could save you a
 lot of time.
 
-[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html
+[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/building/how-to-build-and-run.html
 
 ## Pull Requests
 [pull-requests]: #pull-requests
diff --git a/Cargo.lock b/Cargo.lock
index 46480aeb447..16f2ffc2815 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -68,7 +68,7 @@ name = "arena"
 version = "0.0.0"
 dependencies = [
  "rustc_data_structures",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -208,6 +208,7 @@ name = "build-manifest"
 version = "0.1.0"
 dependencies = [
  "serde",
+ "serde_json",
  "toml",
 ]
 
@@ -486,7 +487,7 @@ dependencies = [
  "regex-syntax",
  "semver",
  "serde",
- "smallvec",
+ "smallvec 1.0.0",
  "toml",
  "unicode-normalization",
  "url 2.1.0",
@@ -654,7 +655,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
 dependencies = [
  "crossbeam-utils 0.6.5",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -2251,9 +2252,9 @@ dependencies = [
 
 [[package]]
 name = "openssl"
-version = "0.10.16"
+version = "0.10.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec7bd7ca4cce6dbdc77e7c1230682740d307d1218a87fb0349a571272be749f9"
+checksum = "2f372b2b53ce10fb823a337aaa674e3a7d072b957c6264d0f4ff0bd86e657449"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -2280,15 +2281,15 @@ dependencies = [
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.43"
+version = "0.9.52"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33c86834957dd5b915623e94f2f4ab2c70dd8f6b70679824155d5ae21dbd495d"
+checksum = "c977d08e1312e2f7e4b86f9ebaa0ed3b19d1daff75fae88bbb88108afbd801fc"
 dependencies = [
+ "autocfg",
  "cc",
  "libc",
  "openssl-src",
  "pkg-config",
- "rustc_version",
  "vcpkg",
 ]
 
@@ -2391,7 +2392,7 @@ dependencies = [
  "libc",
  "rand 0.6.1",
  "rustc_version",
- "smallvec",
+ "smallvec 0.6.10",
  "winapi 0.3.6",
 ]
 
@@ -2406,7 +2407,7 @@ dependencies = [
  "libc",
  "redox_syscall",
  "rustc_version",
- "smallvec",
+ "smallvec 0.6.10",
  "winapi 0.3.6",
 ]
 
@@ -3134,7 +3135,7 @@ dependencies = [
  "rustc_target",
  "scoped-tls",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -3146,7 +3147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a623fd4805842e9bd0bb6e6dace63efede0ee22de4522a0b03b7c3d15a22f009"
 dependencies = [
  "rustc-ap-rustc_data_structures",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3175,7 +3176,7 @@ dependencies = [
  "rustc-hash",
  "rustc-rayon 0.2.0",
  "rustc-rayon-core 0.2.0",
- "smallvec",
+ "smallvec 0.6.10",
  "stable_deref_trait",
 ]
 
@@ -3203,7 +3204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "457a5c204ae2fdaa5bdb5b196e58ca59896870d80445fe423063c9453496e3ea"
 dependencies = [
  "rustc-ap-serialize",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3249,7 +3250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "92679240e86f4583cc05f8dcf6439bdab87bac9e6555718469176de9bd52ba20"
 dependencies = [
  "indexmap",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3269,7 +3270,7 @@ dependencies = [
  "rustc-ap-serialize",
  "rustc-ap-syntax_pos",
  "scoped-tls",
- "smallvec",
+ "smallvec 0.6.10",
 ]
 
 [[package]]
@@ -3392,7 +3393,7 @@ dependencies = [
  "crossbeam-utils 0.6.5",
  "serde",
  "serde_json",
- "smallvec",
+ "smallvec 0.6.10",
  "syn 0.15.35",
  "url 2.1.0",
  "winapi 0.3.6",
@@ -3403,7 +3404,7 @@ name = "rustc_apfloat"
 version = "0.0.0"
 dependencies = [
  "bitflags",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -3483,7 +3484,7 @@ dependencies = [
  "rustc-rayon-core 0.3.0",
  "rustc_index",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "stable_deref_trait",
 ]
 
@@ -3503,8 +3504,10 @@ dependencies = [
  "rustc_lint",
  "rustc_metadata",
  "rustc_mir",
+ "rustc_parse",
  "rustc_plugin",
  "rustc_plugin_impl",
+ "rustc_resolve",
  "rustc_save_analysis",
  "rustc_target",
  "serialize",
@@ -3551,7 +3554,7 @@ name = "rustc_index"
 version = "0.0.0"
 dependencies = [
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -3570,6 +3573,7 @@ dependencies = [
  "rustc_lint",
  "rustc_metadata",
  "rustc_mir",
+ "rustc_parse",
  "rustc_passes",
  "rustc_plugin_impl",
  "rustc_privacy",
@@ -3578,7 +3582,7 @@ dependencies = [
  "rustc_traits",
  "rustc_typeck",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_expand",
  "syntax_ext",
@@ -3647,9 +3651,10 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_index",
+ "rustc_parse",
  "rustc_target",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "stable_deref_trait",
  "syntax",
  "syntax_expand",
@@ -3674,7 +3679,7 @@ dependencies = [
  "rustc_lexer",
  "rustc_target",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -3691,6 +3696,21 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc_parse"
+version = "0.0.0"
+dependencies = [
+ "bitflags",
+ "log",
+ "rustc_data_structures",
+ "rustc_errors",
+ "rustc_lexer",
+ "rustc_target",
+ "smallvec 1.0.0",
+ "syntax",
+ "syntax_pos",
+]
+
+[[package]]
 name = "rustc_passes"
 version = "0.0.0"
 dependencies = [
@@ -3699,6 +3719,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_index",
+ "rustc_parse",
  "rustc_target",
  "syntax",
  "syntax_pos",
@@ -3745,7 +3766,7 @@ dependencies = [
  "rustc_data_structures",
  "rustc_errors",
  "rustc_metadata",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_expand",
  "syntax_pos",
@@ -3761,7 +3782,7 @@ dependencies = [
  "rustc",
  "rustc_codegen_utils",
  "rustc_data_structures",
- "rustc_target",
+ "rustc_parse",
  "serde_json",
  "syntax",
  "syntax_pos",
@@ -3798,7 +3819,7 @@ dependencies = [
  "rustc",
  "rustc_data_structures",
  "rustc_target",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -3825,7 +3846,7 @@ dependencies = [
  "rustc_errors",
  "rustc_index",
  "rustc_target",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -4069,7 +4090,7 @@ name = "serialize"
 version = "0.0.0"
 dependencies = [
  "indexmap",
- "smallvec",
+ "smallvec 1.0.0",
 ]
 
 [[package]]
@@ -4134,6 +4155,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
 
 [[package]]
+name = "smallvec"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
+
+[[package]]
 name = "socket2"
 version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4355,10 +4382,9 @@ dependencies = [
  "rustc_errors",
  "rustc_index",
  "rustc_lexer",
- "rustc_target",
  "scoped-tls",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax_pos",
 ]
 
@@ -4366,17 +4392,13 @@ dependencies = [
 name = "syntax_expand"
 version = "0.0.0"
 dependencies = [
- "bitflags",
- "lazy_static 1.3.0",
  "log",
  "rustc_data_structures",
  "rustc_errors",
- "rustc_index",
  "rustc_lexer",
- "rustc_target",
- "scoped-tls",
+ "rustc_parse",
  "serialize",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_pos",
 ]
@@ -4389,8 +4411,9 @@ dependencies = [
  "log",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_parse",
  "rustc_target",
- "smallvec",
+ "smallvec 1.0.0",
  "syntax",
  "syntax_expand",
  "syntax_pos",
diff --git a/README.md b/README.md
index c5468a29248..61d3c9e1157 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ The Rust build system has a Python script called `x.py` to bootstrap building
 the compiler. More information about it may be found by running `./x.py --help`
 or reading the [rustc guide][rustcguidebuild].
 
-[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html
+[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/building/how-to-build-and-run.html
 
 ### Building on *nix
 1. Make sure you have installed the dependencies:
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index d9580b59815..7b49cc0a929 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -448,12 +448,12 @@ Arguments:
 
         Flags {
             verbose: matches.opt_count("verbose"),
-            stage: matches.opt_str("stage").map(|j| j.parse().unwrap()),
+            stage: matches.opt_str("stage").map(|j| j.parse().expect("`stage` should be a number")),
             dry_run: matches.opt_present("dry-run"),
             on_fail: matches.opt_str("on-fail"),
             rustc_error_format: matches.opt_str("error-format"),
             keep_stage: matches.opt_strs("keep-stage")
-                .into_iter().map(|j| j.parse().unwrap())
+                .into_iter().map(|j| j.parse().expect("`keep-stage` should be a number"))
                 .collect(),
             host: split(&matches.opt_strs("host"))
                 .into_iter()
@@ -464,7 +464,7 @@ Arguments:
                 .map(|x| INTERNER.intern_string(x))
                 .collect::<Vec<_>>(),
             config: cfg_file,
-            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
+            jobs: matches.opt_str("jobs").map(|j| j.parse().expect("`jobs` should be a number")),
             cmd,
             incremental: matches.opt_present("incremental"),
             exclude: split(&matches.opt_strs("exclude"))
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 60f0dccdb07..a858ed42bad 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -570,7 +570,12 @@ impl Step for Clippy {
             let host_libs = builder
                 .stage_out(compiler, Mode::ToolRustc)
                 .join(builder.cargo_dir());
+            let target_libs = builder
+                .stage_out(compiler, Mode::ToolRustc)
+                .join(&self.host)
+                .join(builder.cargo_dir());
             cargo.env("HOST_LIBS", host_libs);
+            cargo.env("TARGET_LIBS", target_libs);
             // clippy tests need to find the driver
             cargo.env("CLIPPY_DRIVER_PATH", clippy);
 
diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 271c3258544..836f81a7816 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -318,7 +318,7 @@ jobs:
       # 32/64 bit MSVC and GNU deployment
       dist-x86_64-msvc:
         MSYS_BITS: 64
-        RUST_CONFIGURE_ARGS: >
+        RUST_CONFIGURE_ARGS: >-
           --build=x86_64-pc-windows-msvc
           --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
           --enable-full-tools
@@ -328,7 +328,7 @@ jobs:
         DEPLOY: 1
       dist-i686-msvc:
         MSYS_BITS: 32
-        RUST_CONFIGURE_ARGS: >
+        RUST_CONFIGURE_ARGS: >-
           --build=i686-pc-windows-msvc
           --target=i586-pc-windows-msvc
           --enable-full-tools
diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile
index b087ea7899f..ad675830b77 100644
--- a/src/ci/docker/dist-i686-linux/Dockerfile
+++ b/src/ci/docker/dist-i686-linux/Dockerfile
@@ -69,7 +69,7 @@ RUN ./build-python.sh
 
 # Now build LLVM+Clang 7, afterwards configuring further compilations to use the
 # clang/clang++ compilers.
-COPY dist-x86_64-linux/build-clang.sh /tmp/
+COPY dist-x86_64-linux/build-clang.sh dist-x86_64-linux/llvm-project-centos.patch /tmp/
 RUN ./build-clang.sh
 ENV CC=clang CXX=clang++
 
diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
index f04ee781571..c63ea6facca 100755
--- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
+++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh
@@ -4,17 +4,17 @@
 
 set -ex
 
-# Originally from https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
-curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
+# Originally from https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
+curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/clang%2Bllvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | \
   tar xJf -
-export PATH=`pwd`/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
+export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH
 
-git clone https://github.com/CraneStation/wasi-sysroot
+git clone https://github.com/CraneStation/wasi-libc
 
-cd wasi-sysroot
-git reset --hard e5f14be38362f1ab83302895a6e74b2ffd0e2302
+cd wasi-libc
+git reset --hard a94d2d04e7722b323573da2bd04e909a5763d35b
 make -j$(nproc) INSTALL_DIR=/wasm32-wasi install
 
 cd ..
-rm -rf reference-sysroot-wasi
+rm -rf wasi-libc
 rm -rf clang+llvm*
diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile
index a1a778c2b2c..2f2a10a0e90 100644
--- a/src/ci/docker/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/dist-x86_64-linux/Dockerfile
@@ -69,7 +69,7 @@ RUN ./build-python.sh
 
 # Now build LLVM+Clang 7, afterwards configuring further compilations to use the
 # clang/clang++ compilers.
-COPY dist-x86_64-linux/build-clang.sh /tmp/
+COPY dist-x86_64-linux/build-clang.sh dist-x86_64-linux/llvm-project-centos.patch /tmp/
 RUN ./build-clang.sh
 ENV CC=clang CXX=clang++
 
diff --git a/src/ci/docker/dist-x86_64-linux/build-clang.sh b/src/ci/docker/dist-x86_64-linux/build-clang.sh
index ac681b71686..518f6ef9b70 100755
--- a/src/ci/docker/dist-x86_64-linux/build-clang.sh
+++ b/src/ci/docker/dist-x86_64-linux/build-clang.sh
@@ -4,7 +4,7 @@ set -ex
 
 source shared.sh
 
-LLVM=llvmorg-8.0.0-rc2
+LLVM=llvmorg-9.0.0
 
 mkdir llvm-project
 cd llvm-project
@@ -12,6 +12,9 @@ cd llvm-project
 curl -L https://github.com/llvm/llvm-project/archive/$LLVM.tar.gz | \
   tar xzf - --strip-components=1
 
+yum install -y patch
+patch -Np1 < ../llvm-project-centos.patch
+
 mkdir clang-build
 cd clang-build
 
diff --git a/src/ci/docker/dist-x86_64-linux/llvm-project-centos.patch b/src/ci/docker/dist-x86_64-linux/llvm-project-centos.patch
new file mode 100644
index 00000000000..52650062cc4
--- /dev/null
+++ b/src/ci/docker/dist-x86_64-linux/llvm-project-centos.patch
@@ -0,0 +1,18 @@
+diff --git a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
+index 176d6d6abf3..a6d63bf24b8 100644
+--- a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
++++ b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
+@@ -33,6 +33,13 @@ namespace {
+ using namespace llvm;
+ using namespace clang;
+ 
++#define EPOLL_CLOEXEC -1
++#define IN_CLOEXEC -1
++#define O_CLOEXEC -1
++static int epoll_create1(int flags) { return -1; }
++static int inotify_init1(int flags) { return -1; }
++static int pipe2(int *fds, int flags) { return -1; }
++
+ /// Pipe for inter-thread synchronization - for epoll-ing on multiple
+ /// conditions. It is meant for uni-directional 1:1 signalling - specifically:
+ /// no multiple consumers, no data passing. Thread waiting for signal should
diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh
index e9b685718e6..b1e9bf92ca5 100755
--- a/src/ci/scripts/install-clang.sh
+++ b/src/ci/scripts/install-clang.sh
@@ -9,10 +9,10 @@ IFS=$'\n\t'
 source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 
 if isMacOS; then
-    curl -f "${MIRRORS_BASE}/clang%2Bllvm-7.0.0-x86_64-apple-darwin.tar.xz" | tar xJf -
+    curl -f "${MIRRORS_BASE}/clang%2Bllvm-9.0.0-x86_64-darwin-apple.tar.xz" | tar xJf -
 
-    ciCommandSetEnv CC "$(pwd)/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang"
-    ciCommandSetEnv CXX "$(pwd)/clang+llvm-7.0.0-x86_64-apple-darwin/bin/clang++"
+    ciCommandSetEnv CC "$(pwd)/clang+llvm-9.0.0-x86_64-darwin-apple/bin/clang"
+    ciCommandSetEnv CXX "$(pwd)/clang+llvm-9.0.0-x86_64-darwin-apple/bin/clang++"
 
     # Configure `AR` specifically so rustbuild doesn't try to infer it as
     # `clang-ar` by accident.
@@ -27,17 +27,18 @@ elif isWindows && [[ -z ${MINGW_URL+x} ]]; then
     # Note that the LLVM installer is an NSIS installer
     #
     # Original downloaded here came from
-    # http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe
-    # That installer was run through `wine` on Linux and then the resulting
-    # installation directory (found in `$HOME/.wine/drive_c/Program Files/LLVM`) was
-    # packaged up into a tarball. We've had issues otherwise that the installer will
-    # randomly hang, provide not a lot of useful information, pollute global state,
-    # etc. In general the tarball is just more confined and easier to deal with when
-    # working with various CI environments.
+    # http://releases.llvm.org/9.0.0/LLVM-9.0.0-win64.exe
+    # That installer was run through `wine ./installer.exe /S /NCRC` on Linux
+    # and then the resulting installation directory (found in
+    # `$HOME/.wine/drive_c/Program Files/LLVM`) was packaged up into a tarball.
+    # We've had issues otherwise that the installer will randomly hang, provide
+    # not a lot of useful information, pollute global state, etc. In general the
+    # tarball is just more confined and easier to deal with when working with
+    # various CI environments.
 
     mkdir -p citools
     cd citools
-    curl -f "${MIRRORS_BASE}/LLVM-7.0.0-win64.tar.gz" | tar xzf -
+    curl -f "${MIRRORS_BASE}/LLVM-9.0.0-win64.tar.gz" | tar xzf -
     ciCommandSetEnv RUST_CONFIGURE_ARGS \
         "${RUST_CONFIGURE_ARGS} --set llvm.clang-cl=$(pwd)/clang-rust/bin/clang-cl.exe"
 fi
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
-Subproject 941968db2fd9c85788a4f971c8e425d46b4cb73
+Subproject 75a5f9236c689a547fe207a10854f0775bce793
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 70c7acccd36..0dc81378e05 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -197,7 +197,11 @@ in software.
 ## prefer-dynamic
 
 By default, `rustc` prefers to statically link dependencies. This option will
-make it use dynamic linking instead.
+indicate that dynamic linking should be used if possible if both a static and
+dynamic versions of a library are available. There is an internal algorithm
+for determining whether or not it is possible to statically or dynamically
+link with a dependency. For example, `cdylib` crate types may only use static
+linkage.
 
 ## no-integrated-as
 
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 79b4f7542f9..577d03d1038 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -21,8 +21,7 @@ to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.
 <a id="option-l-search-path"></a>
 ## `-L`: add a directory to the library search path
 
-When looking for external crates or libraries, a directory passed to this flag
-will be searched.
+The `-L` flag adds a path to search for external crates and libraries.
 
 The kind of search path can optionally be specified with the form `-L
 KIND=PATH` where `KIND` may be one of:
@@ -262,9 +261,30 @@ This flag, when combined with other flags, makes them produce extra output.
 <a id="option-extern"></a>
 ## `--extern`: specify where an external library is located
 
-This flag allows you to pass the name and location of an external crate that
-will be linked into the crate you are building. This flag may be specified
-multiple times. The format of the value should be `CRATENAME=PATH`.
+This flag allows you to pass the name and location for an external crate of a
+direct dependency. Indirect dependencies (dependencies of dependencies) are
+located using the [`-L` flag](#option-l-search-path). The given crate name is
+added to the [extern prelude], which is the same as specifying `extern crate`
+within the root module. The given crate name does not need to match the name
+the library was built with.
+
+This flag may be specified multiple times. This flag takes an argument with
+either of the following formats:
+
+* `CRATENAME=PATH` — Indicates the given crate is found at the given path.
+* `CRATENAME` — Indicates the given crate may be found in the search path,
+  such as within the sysroot or via the `-L` flag.
+
+The same crate name may be specified multiple times for different crate types.
+If both an `rlib` and `dylib` are found, an internal algorithm is used to
+decide which to use for linking. The [`-C prefer-dynamic`
+flag][prefer-dynamic] may be used to influence which is used.
+
+If the same crate name is specified with and without a path, the one with the
+path is used and the pathless flag has no effect.
+
+[extern prelude]: ../reference/items/extern-crates.html#extern-prelude
+[prefer-dynamic]: codegen-options/index.md#prefer-dynamic
 
 <a id="option-sysroot"></a>
 ## `--sysroot`: Override the system root
diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md
index 5688e90ada1..dc5a9e44acf 100644
--- a/src/doc/rustc/src/lints/listing/deny-by-default.md
+++ b/src/doc/rustc/src/lints/listing/deny-by-default.md
@@ -45,53 +45,6 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
 ```
 
-## legacy-constructor-visibility
-
-[RFC 1506](https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md) modified some
-visibility rules, and changed the visibility of struct constructors. Some
-example code that triggers this lint:
-
-```rust,ignore
-mod m {
-    pub struct S(u8);
-    
-    fn f() {
-        // this is trying to use S from the 'use' line, but because the `u8` is
-        // not pub, it is private
-        ::S;
-    }
-}
-
-use m::S;
-```
-
-This will produce:
-
-```text
-error: private struct constructors are not usable through re-exports in outer modules
- --> src/main.rs:5:9
-  |
-5 |         ::S;
-  |         ^^^
-  |
-  = note: `#[deny(legacy_constructor_visibility)]` on by default
-  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-  = note: for more information, see issue #39207 <https://github.com/rust-lang/rust/issues/39207>
-```
-
-
-## legacy-directory-ownership
-
-The legacy_directory_ownership warning is issued when
-
-* There is a non-inline module with a `#[path]` attribute (e.g. `#[path = "foo.rs"] mod bar;`),
-* The module's file ("foo.rs" in the above example) is not named "mod.rs", and
-* The module's file contains a non-inline child module without a `#[path]` attribute.
-
-The warning can be fixed by renaming the parent module to "mod.rs" and moving
-it into its own directory if appropriate.
-
-
 ## missing-fragment-specifier
 
 The missing_fragment_specifier warning is issued when an unused pattern in a
@@ -169,39 +122,49 @@ error: literal out of range for u8
   |
 ```
 
-## parenthesized-params-in-types-and-modules
+## patterns-in-fns-without-body
 
-This lint detects incorrect parentheses. Some example code that triggers this
-lint:
+This lint detects patterns in functions without body were that were
+previously erroneously allowed. Some example code that triggers this lint:
 
-```rust,ignore
-let x = 5 as usize();
+```rust,compile_fail
+trait Trait {
+    fn foo(mut arg: u8);
+}
 ```
 
 This will produce:
 
 ```text
-error: parenthesized parameters may only be used with a trait
- --> src/main.rs:2:21
+warning: patterns aren't allowed in methods without bodies
+ --> src/main.rs:2:12
   |
-2 |   let x = 5 as usize();
-  |                     ^^
+2 |     fn foo(mut arg: u8);
+  |            ^^^^^^^
   |
-  = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
+  = note: `#[warn(patterns_in_fns_without_body)]` on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-  = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+  = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
 ```
 
-To fix it, remove the `()`s.
+To fix this, remove the pattern; it can be used in the implementation without
+being used in the definition. That is:
 
-## pub-use-of-private-extern-crate
+```rust
+trait Trait {
+    fn foo(arg: u8);
+}
 
-This lint detects a specific situation of re-exporting a private `extern crate`;
+impl Trait for i32 {
+    fn foo(mut arg: u8) {
+
+    }
+}
+```
 
-## safe-extern-statics
+## pub-use-of-private-extern-crate
 
-In older versions of Rust, there was a soundness issue where `extern static`s were allowed
-to be accessed in safe code. This lint now catches and denies this kind of code.
+This lint detects a specific situation of re-exporting a private `extern crate`;
 
 ## unknown-crate-types
 
diff --git a/src/doc/rustc/src/lints/listing/warn-by-default.md b/src/doc/rustc/src/lints/listing/warn-by-default.md
index 813d7c4bafe..77642a850fa 100644
--- a/src/doc/rustc/src/lints/listing/warn-by-default.md
+++ b/src/doc/rustc/src/lints/listing/warn-by-default.md
@@ -307,46 +307,6 @@ warning: path statement with no effect
   |
 ```
 
-## patterns-in-fns-without-body
-
-This lint detects patterns in functions without body were that were
-previously erroneously allowed. Some example code that triggers this lint:
-
-```rust
-trait Trait {
-    fn foo(mut arg: u8);
-}
-```
-
-This will produce:
-
-```text
-warning: patterns aren't allowed in methods without bodies
- --> src/main.rs:2:12
-  |
-2 |     fn foo(mut arg: u8);
-  |            ^^^^^^^
-  |
-  = note: `#[warn(patterns_in_fns_without_body)]` on by default
-  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-  = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
-```
-
-To fix this, remove the pattern; it can be used in the implementation without
-being used in the definition. That is:
-
-```rust
-trait Trait {
-    fn foo(arg: u8);
-}
-
-impl Trait for i32 {
-    fn foo(mut arg: u8) {
-
-    }
-}
-```
-
 ## plugin-as-library
 
 This lint detects when compiler plugins are used as ordinary library in
diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md
index 46528187c11..d4202f5b367 100644
--- a/src/doc/rustdoc/src/SUMMARY.md
+++ b/src/doc/rustdoc/src/SUMMARY.md
@@ -1,8 +1,10 @@
 # The Rustdoc Book
 
 - [What is rustdoc?](what-is-rustdoc.md)
+- [How to write documentation](how-to-write-documentation.md)
 - [Command-line arguments](command-line-arguments.md)
 - [The `#[doc]` attribute](the-doc-attribute.md)
 - [Documentation tests](documentation-tests.md)
+- [Lints](lints.md)
 - [Passes](passes.md)
 - [Unstable features](unstable-features.md)
diff --git a/src/doc/rustdoc/src/how-to-write-documentation.md b/src/doc/rustdoc/src/how-to-write-documentation.md
new file mode 100644
index 00000000000..dd3aa5d4b69
--- /dev/null
+++ b/src/doc/rustdoc/src/how-to-write-documentation.md
@@ -0,0 +1,82 @@
+# How to write documentation
+
+This chapter covers not only how to write documentation but specifically
+how to write **good** documentation.  Something to keep in mind when
+writing documentation is that your audience is not just yourself but others
+who simply don't have the context you do.  It is important to be as clear
+as you can, and as complete as possible.  As a rule of thumb: the more
+documentation you write for your crate the better.  If an item is public
+then it should be documented.
+
+## Basic structure
+
+It is recommended that each item's documentation follows this basic structure:
+
+```text
+[short sentence explaining what it is]
+
+[more detailed explanation]
+
+[at least one code example that users can copy/paste to try it]
+
+[even more advanced explanations if necessary]
+```
+
+This basic structure should be straightforward to follow when writing your
+documentation and, while you might think that a code example is trivial,
+the examples are really important because they can help your users to
+understand what an item is, how it is used, and for what purpose it exists.
+
+Let's see an example coming from the [standard library] by taking a look at the
+[`std::env::args()`][env::args] function:
+
+``````text
+Returns the arguments which this program was started with (normally passed
+via the command line).
+
+The first element is traditionally the path of the executable, but it can be
+set to arbitrary text, and may not even exist. This means this property should
+not be relied upon for security purposes.
+
+On Unix systems shell usually expands unquoted arguments with glob patterns
+(such as `*` and `?`). On Windows this is not done, and such arguments are
+passed as-is.
+
+# Panics
+
+The returned iterator will panic during iteration if any argument to the
+process is not valid unicode. If this is not desired,
+use the [`args_os`] function instead.
+
+# Examples
+
+```
+use std::env;
+
+// Prints each argument on a separate line
+for argument in env::args() {
+    println!("{}", argument);
+}
+```
+
+[`args_os`]: ./fn.args_os.html
+``````
+
+As you can see, it follows the structure detailed above: it starts with a short
+sentence explaining what the functions does, then it provides more information
+and finally provides a code example.
+
+## Markdown
+
+`rustdoc` is using the [commonmark markdown specification]. You might be
+interested into taking a look at their website to see what's possible to do.
+
+## Lints
+
+To be sure that you didn't miss any item without documentation or code examples,
+you can take a look at the rustdoc lints [here][rustdoc-lints].
+
+[standard library]: https://doc.rust-lang.org/stable/std/index.html
+[env::args]: https://doc.rust-lang.org/stable/std/env/fn.args.html
+[commonmark markdown specification]: https://commonmark.org/
+[rustdoc-lints]: lints.md
diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md
new file mode 100644
index 00000000000..beb2556872d
--- /dev/null
+++ b/src/doc/rustdoc/src/lints.md
@@ -0,0 +1,119 @@
+# Lints
+
+`rustdoc` provides lints to help you writing and testing your documentation. You
+can use them like any other lints by doing this:
+
+```rust,ignore
+#![allow(missing_docs)] // allowing the lint, no message
+#![warn(missing_docs)] // warn if there is missing docs
+#![deny(missing_docs)] // rustdoc will fail if there is missing docs
+```
+
+Here is the list of the lints provided by `rustdoc`:
+
+## intra_doc_link_resolution_failure
+
+This lint **warns by default** and is **nightly-only**. This lint detects when
+an intra-doc link fails to get resolved. For example:
+
+```rust
+/// I want to link to [`Inexistent`] but it doesn't exist!
+pub fn foo() {}
+```
+
+You'll get a warning saying:
+
+```text
+error: `[`Inexistent`]` cannot be resolved, ignoring it...
+```
+
+## missing_docs
+
+This lint is **allowed by default**. It detects items missing documentation.
+For example:
+
+```rust
+#![warn(missing_docs)]
+
+pub fn undocumented() {}
+# fn main() {}
+```
+
+The `undocumented` function will then have the following warning:
+
+```text
+warning: missing documentation for a function
+  --> your-crate/lib.rs:3:1
+   |
+ 3 | pub fn undocumented() {}
+   | ^^^^^^^^^^^^^^^^^^^^^
+```
+
+## missing_doc_code_examples
+
+This lint is **allowed by default**. It detects when a documentation block
+is missing a code example. For example:
+
+```rust
+#![warn(missing_doc_code_examples)]
+
+/// There is no code example!
+pub fn no_code_example() {}
+# fn main() {}
+```
+
+The `no_code_example` function will then have the following warning:
+
+```text
+warning: Missing code example in this documentation
+  --> your-crate/lib.rs:3:1
+   |
+LL | /// There is no code example!
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+```
+
+To fix the lint, you need to add a code example into the documentation block:
+
+```rust
+/// There is no code example!
+///
+/// ```
+/// println!("calling no_code_example...");
+/// no_code_example();
+/// println!("we called no_code_example!");
+/// ```
+pub fn no_code_example() {}
+```
+
+## private_doc_tests
+
+This lint is **allowed by default**. It detects documentation tests when they
+are on a private item. For example:
+
+```rust
+#![warn(private_doc_tests)]
+
+mod foo {
+    /// private doc test
+    ///
+    /// ```
+    /// assert!(false);
+    /// ```
+    fn bar() {}
+}
+# fn main() {}
+```
+
+Which will give:
+
+```text
+warning: Documentation test in private item
+  --> your-crate/lib.rs:4:1
+   |
+ 4 | /     /// private doc test
+ 5 | |     ///
+ 6 | |     /// ```
+ 7 | |     /// assert!(false);
+ 8 | |     /// ```
+   | |___________^
+```
diff --git a/src/doc/unstable-book/src/language-features/on-unimplemented.md b/src/doc/unstable-book/src/language-features/on-unimplemented.md
deleted file mode 100644
index 8db241e4b4e..00000000000
--- a/src/doc/unstable-book/src/language-features/on-unimplemented.md
+++ /dev/null
@@ -1,154 +0,0 @@
-# `on_unimplemented`
-
-The tracking issue for this feature is: [#29628]
-
-[#29628]: https://github.com/rust-lang/rust/issues/29628
-
-------------------------
-
-The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]`
-attribute, which allows trait definitions to add specialized notes to error
-messages when an implementation was expected but not found. You can refer
-to the trait's generic arguments by name and to the resolved type using
-`Self`.
-
-For example:
-
-```rust,compile_fail
-#![feature(on_unimplemented)]
-
-#[rustc_on_unimplemented="an iterator over elements of type `{A}` \
-    cannot be built from a collection of type `{Self}`"]
-trait MyIterator<A> {
-    fn next(&mut self) -> A;
-}
-
-fn iterate_chars<I: MyIterator<char>>(i: I) {
-    // ...
-}
-
-fn main() {
-    iterate_chars(&[1, 2, 3][..]);
-}
-```
-
-When the user compiles this, they will see the following;
-
-```txt
-error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
-  --> <anon>:14:5
-   |
-14 |     iterate_chars(&[1, 2, 3][..]);
-   |     ^^^^^^^^^^^^^ an iterator over elements of type `char` cannot be built from a collection of type `&[{integer}]`
-   |
-   = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
-   = note: required by `iterate_chars`
-```
-
-`on_unimplemented` also supports advanced filtering for better targeting
-of messages, as well as modifying specific parts of the error message. You
-target the text of:
-
- - the main error message (`message`)
- - the label (`label`)
- - an extra note (`note`)
-
-For example, the following attribute
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    message="message",
-    label="label",
-    note="note"
-)]
-trait MyIterator<A> {
-    fn next(&mut self) -> A;
-}
-```
-
-Would generate the following output:
-
-```text
-error[E0277]: message
-  --> <anon>:14:5
-   |
-14 |     iterate_chars(&[1, 2, 3][..]);
-   |     ^^^^^^^^^^^^^ label
-   |
-   = note: note
-   = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
-   = note: required by `iterate_chars`
-```
-
-To allow more targeted error messages, it is possible to filter the
-application of these fields based on a variety of attributes when using
-`on`:
-
- - `crate_local`: whether the code causing the trait bound to not be
-   fulfilled is part of the user's crate. This is used to avoid suggesting
-   code changes that would require modifying a dependency.
- - Any of the generic arguments that can be substituted in the text can be
-   referred by name as well for filtering, like `Rhs="i32"`, except for
-   `Self`.
- - `_Self`: to filter only on a particular calculated trait resolution, like
-   `Self="std::iter::Iterator<char>"`. This is needed because `Self` is a
-   keyword which cannot appear in attributes.
- - `direct`: user-specified rather than derived obligation.
- - `from_method`: usable both as boolean (whether the flag is present, like
-   `crate_local`) or matching against a particular method. Currently used
-   for `try`.
- - `from_desugaring`: usable both as boolean (whether the flag is present)
-   or matching against a particular desugaring. The desugaring is identified
-   with its variant name in the `DesugaringKind` enum.
-
-For example, the `Iterator` trait can be annotated in the following way:
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    on(
-        _Self="&str",
-        note="call `.chars()` or `.as_bytes()` on `{Self}"
-    ),
-    message="`{Self}` is not an iterator",
-    label="`{Self}` is not an iterator",
-    note="maybe try calling `.iter()` or a similar method"
-)]
-pub trait Iterator {}
-```
-
-Which would produce the following outputs:
-
-```text
-error[E0277]: `Foo` is not an iterator
- --> src/main.rs:4:16
-  |
-4 |     for foo in Foo {}
-  |                ^^^ `Foo` is not an iterator
-  |
-  = note: maybe try calling `.iter()` or a similar method
-  = help: the trait `std::iter::Iterator` is not implemented for `Foo`
-  = note: required by `std::iter::IntoIterator::into_iter`
-
-error[E0277]: `&str` is not an iterator
- --> src/main.rs:5:16
-  |
-5 |     for foo in "" {}
-  |                ^^ `&str` is not an iterator
-  |
-  = note: call `.chars()` or `.bytes() on `&str`
-  = help: the trait `std::iter::Iterator` is not implemented for `&str`
-  = note: required by `std::iter::IntoIterator::into_iter`
-```
-
-If you need to filter on multiple attributes, you can use `all`, `any` or
-`not` in the following way:
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    on(
-        all(_Self="&str", T="std::string::String"),
-        note="you can coerce a `{T}` into a `{Self}` by writing `&*variable`"
-    )
-)]
-pub trait From<T>: Sized { /* ... */ }
-```
diff --git a/src/doc/unstable-book/src/language-features/re-rebalance-coherence.md b/src/doc/unstable-book/src/language-features/re-rebalance-coherence.md
deleted file mode 100644
index 1e74652a890..00000000000
--- a/src/doc/unstable-book/src/language-features/re-rebalance-coherence.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# `re_rebalance_coherence`
-
-The tracking issue for this feature is: [#55437]
-
-[#55437]: https://github.com/rust-lang/rust/issues/55437
-
-------------------------
-
-The `re_rebalance_coherence` feature tweaks the rules regarding which trait
-impls are allowed in crates.
-The following rule is used:
-
-Given `impl<P1..=Pn> Trait<T1..=Tn> for T0`, an impl is valid only if at
-least one of the following is true:
-- `Trait` is a local trait
-- All of
-  - At least one of the types `T0..=Tn` must be a local type. Let `Ti` be the
-    first such type.
-  - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti` (excluding
-    `Ti`)
-
-
-See the [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2451-re-rebalancing-coherence.md) for details.
diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
index 66a3c8e5554..39c24fb10e5 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -14,8 +14,7 @@ TEST_DIR = os.path.abspath(
     os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
 
 TEMPLATE = """\
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 {error_deriving}
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index 48f9865b870..a0c9263673d 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -90,7 +90,7 @@ impl<T> Clone for Iter<'_, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T: 'a> {
     // We do *not* exclusively own the entire list here, references to node's `element`
-    // have been handed out by the iterator!  So be careful when using this; the methods
+    // have been handed out by the iterator! So be careful when using this; the methods
     // called must be aware that there can be aliasing pointers to `element`.
     list: &'a mut LinkedList<T>,
     head: Option<NonNull<Node<T>>>,
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 8f3dfabd888..7795083e058 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -835,7 +835,8 @@ impl<T> VecDeque<T> {
         }
     }
 
-    /// Shortens the `VecDeque`, dropping excess elements from the back.
+    /// Shortens the `VecDeque`, keeping the first `len` elements and dropping
+    /// the rest.
     ///
     /// If `len` is greater than the `VecDeque`'s current length, this has no
     /// effect.
@@ -855,8 +856,31 @@ impl<T> VecDeque<T> {
     /// ```
     #[stable(feature = "deque_extras", since = "1.16.0")]
     pub fn truncate(&mut self, len: usize) {
-        for _ in len..self.len() {
-            self.pop_back();
+        // Safe because:
+        //
+        // * Any slice passed to `drop_in_place` is valid; the second case has
+        //   `len <= front.len()` and returning on `len > self.len()` ensures
+        //   `begin <= back.len()` in the first case
+        // * The head of the VecDeque is moved before calling `drop_in_place`,
+        //   so no value is dropped twice if `drop_in_place` panics
+        unsafe {
+            if len > self.len() {
+                return;
+            }
+            let num_dropped = self.len() - len;
+            let (front, back) = self.as_mut_slices();
+            if len > front.len() {
+                let begin = len - front.len();
+                let drop_back = back.get_unchecked_mut(begin..) as *mut _;
+                self.head = self.wrap_sub(self.head, num_dropped);
+                ptr::drop_in_place(drop_back);
+            } else {
+                let drop_back = back as *mut _;
+                let drop_front = front.get_unchecked_mut(len..) as *mut _;
+                self.head = self.wrap_sub(self.head, num_dropped);
+                ptr::drop_in_place(drop_front);
+                ptr::drop_in_place(drop_back);
+            }
         }
     }
 
@@ -1117,7 +1141,7 @@ impl<T> VecDeque<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn clear(&mut self) {
-        self.drain(..);
+        self.truncate(0);
     }
 
     /// Returns `true` if the `VecDeque` contains an element equal to the
diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs
index d578ee0dac4..09009ff516a 100644
--- a/src/liballoc/collections/vec_deque/tests.rs
+++ b/src/liballoc/collections/vec_deque/tests.rs
@@ -385,6 +385,41 @@ fn test_clone_from() {
 }
 
 #[test]
+fn test_vec_deque_truncate_drop() {
+    static mut DROPS: u32 = 0;
+    #[derive(Clone)]
+    struct Elem(i32);
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe {
+                DROPS += 1;
+            }
+        }
+    }
+
+    let v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
+    for push_front in 0..=v.len() {
+        let v = v.clone();
+        let mut tester = VecDeque::with_capacity(5);
+        for (index, elem) in v.into_iter().enumerate() {
+            if index < push_front {
+                tester.push_front(elem);
+            } else {
+                tester.push_back(elem);
+            }
+        }
+        assert_eq!(unsafe { DROPS }, 0);
+        tester.truncate(3);
+        assert_eq!(unsafe { DROPS }, 2);
+        tester.truncate(0);
+        assert_eq!(unsafe { DROPS }, 5);
+        unsafe {
+            DROPS = 0;
+        }
+    }
+}
+
+#[test]
 fn issue_53529() {
     use crate::boxed::Box;
 
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 94379afc2bd..ddfa6797a57 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -116,7 +116,7 @@
 #![feature(unsize)]
 #![feature(unsized_locals)]
 #![feature(allocator_internals)]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(rustc_const_unstable)]
 #![feature(slice_partition_dedup)]
 #![feature(maybe_uninit_extra, maybe_uninit_slice)]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index f1c4c32e116..a11f9e8c145 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -280,7 +280,7 @@ struct RcBox<T: ?Sized> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Rc<T: ?Sized> {
     ptr: NonNull<RcBox<T>>,
-    phantom: PhantomData<T>,
+    phantom: PhantomData<RcBox<T>>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 0e5746d0d9d..f7dff4c21f7 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -687,7 +687,7 @@ impl String {
     /// checked:
     ///
     /// * The memory at `ptr` needs to have been previously allocated by the
-    ///   same allocator the standard library uses.
+    ///   same allocator the standard library uses, with a required alignment of exactly 1.
     /// * `length` needs to be less than or equal to `capacity`.
     /// * `capacity` needs to be the correct value.
     ///
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 80d6c6e0d43..4b10f089c29 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -195,7 +195,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Arc<T: ?Sized> {
     ptr: NonNull<ArcInner<T>>,
-    phantom: PhantomData<T>,
+    phantom: PhantomData<ArcInner<T>>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libarena/Cargo.toml b/src/libarena/Cargo.toml
index 2643912f6d7..5158aab8b7d 100644
--- a/src/libarena/Cargo.toml
+++ b/src/libarena/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 rustc_data_structures = { path = "../librustc_data_structures" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 5d0333d5226..1b06baeb711 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -1,5 +1,7 @@
 //! Memory allocation APIs
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
 use crate::cmp;
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index e2704e807d1..39a5dd7263c 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -182,6 +182,7 @@ impl dyn Any {
     #[inline]
     pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
         if self.is::<T>() {
+            // SAFETY: just checked whether we are pointing to the correct type
             unsafe {
                 Some(&*(self as *const dyn Any as *const T))
             }
@@ -217,6 +218,7 @@ impl dyn Any {
     #[inline]
     pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
+            // SAFETY: just checked whether we are pointing to the correct type
             unsafe {
                 Some(&mut *(self as *mut dyn Any as *mut T))
             }
@@ -424,7 +426,11 @@ impl TypeId {
     #[rustc_const_unstable(feature="const_type_id")]
     pub const fn of<T: ?Sized + 'static>() -> TypeId {
         TypeId {
+            #[cfg(bootstrap)]
+            // SAFETY: going away soon
             t: unsafe { intrinsics::type_id::<T>() },
+            #[cfg(not(bootstrap))]
+            t: intrinsics::type_id::<T>(),
         }
     }
 }
diff --git a/src/libcore/array/iter.rs b/src/libcore/array/iter.rs
index 11803238407..307e9b90ee2 100644
--- a/src/libcore/array/iter.rs
+++ b/src/libcore/array/iter.rs
@@ -51,7 +51,7 @@ where
     /// iterator (either via `IntoIterator` for arrays or via another way).
     #[unstable(feature = "array_value_iter", issue = "65798")]
     pub fn new(array: [T; N]) -> Self {
-        // The transmute here is actually safe. The docs of `MaybeUninit`
+        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
         // promise:
         //
         // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
@@ -84,10 +84,10 @@ where
     /// Returns an immutable slice of all elements that have not been yielded
     /// yet.
     fn as_slice(&self) -> &[T] {
-        // This transmute is safe. As mentioned in `new`, `MaybeUninit` retains
+        let slice = &self.data[self.alive.clone()];
+        // SAFETY: This transmute is safe. As mentioned in `new`, `MaybeUninit` retains
         // the size and alignment of `T`. Furthermore, we know that all
         // elements within `alive` are properly initialized.
-        let slice = &self.data[self.alive.clone()];
         unsafe {
             mem::transmute::<&[MaybeUninit<T>], &[T]>(slice)
         }
@@ -117,7 +117,8 @@ where
         let idx = self.alive.start;
         self.alive.start += 1;
 
-        // Read the element from the array. This is safe: `idx` is an index
+        // Read the element from the array.
+        // SAFETY: This is safe: `idx` is an index
         // into the "alive" region of the array. Reading this element means
         // that `data[idx]` is regarded as dead now (i.e. do not touch). As
         // `idx` was the start of the alive-zone, the alive zone is now
@@ -163,7 +164,8 @@ where
         // + 1]`.
         self.alive.end -= 1;
 
-        // Read the element from the array. This is safe: `alive.end` is an
+        // Read the element from the array.
+        // SAFETY: This is safe: `alive.end` is an
         // index into the "alive" region of the array. Compare the previous
         // comment that states that the alive region is
         // `data[alive.start..alive.end + 1]`. Reading this element means that
@@ -226,6 +228,7 @@ where
     [T; N]: LengthAtMost32,
 {
     fn clone(&self) -> Self {
+        // SAFETY: each point of unsafety is documented inside the unsafe block
         unsafe {
             // This creates a new uninitialized array. Note that the `assume_init`
             // refers to the array, not the individual elements. And it is Ok if
diff --git a/src/libcore/array/mod.rs b/src/libcore/array/mod.rs
index e1ec8b795d0..74a7d062d3f 100644
--- a/src/libcore/array/mod.rs
+++ b/src/libcore/array/mod.rs
@@ -156,6 +156,7 @@ where
     fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
         if slice.len() == N {
             let ptr = slice.as_ptr() as *const [T; N];
+            // SAFETY: ok because we just checked that the length fits
             unsafe { Ok(&*ptr) }
         } else {
             Err(TryFromSliceError(()))
@@ -173,6 +174,7 @@ where
     fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
         if slice.len() == N {
             let ptr = slice.as_mut_ptr() as *mut [T; N];
+            // SAFETY: ok because we just checked that the length fits
             unsafe { Ok(&mut *ptr) }
         } else {
             Err(TryFromSliceError(()))
diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs
index 4087333e2cf..9b588525bd6 100644
--- a/src/libcore/ascii.rs
+++ b/src/libcore/ascii.rs
@@ -135,6 +135,7 @@ impl FusedIterator for EscapeDefault {}
 #[stable(feature = "ascii_escape_display", since = "1.39.0")]
 impl fmt::Display for EscapeDefault {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // SAFETY: ok because `escape_default` created only valid utf-8 data
         f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) })
     }
 }
diff --git a/src/libcore/benches/ascii.rs b/src/libcore/benches/ascii.rs
index a337c467131..e921dd1ba06 100644
--- a/src/libcore/benches/ascii.rs
+++ b/src/libcore/benches/ascii.rs
@@ -118,6 +118,7 @@ benches! {
     }
 
     fn case07_fake_simd_u32(bytes: &mut [u8]) {
+        // SAFETY: transmuting a sequence of `u8` to `u32` is always fine
         let (before, aligned, after) = unsafe {
             bytes.align_to_mut::<u32>()
         };
@@ -142,6 +143,7 @@ benches! {
     }
 
     fn case08_fake_simd_u64(bytes: &mut [u8]) {
+        // SAFETY: transmuting a sequence of `u8` to `u64` is always fine
         let (before, aligned, after) = unsafe {
             bytes.align_to_mut::<u64>()
         };
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index fda103a52d8..87d8e7aff05 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -137,9 +137,11 @@
 //! use std::cell::Cell;
 //! use std::ptr::NonNull;
 //! use std::intrinsics::abort;
+//! use std::marker::PhantomData;
 //!
 //! struct Rc<T: ?Sized> {
-//!     ptr: NonNull<RcBox<T>>
+//!     ptr: NonNull<RcBox<T>>,
+//!     phantom: PhantomData<RcBox<T>>,
 //! }
 //!
 //! struct RcBox<T: ?Sized> {
@@ -151,7 +153,10 @@
 //! impl<T: ?Sized> Clone for Rc<T> {
 //!     fn clone(&self) -> Rc<T> {
 //!         self.inc_strong();
-//!         Rc { ptr: self.ptr }
+//!         Rc {
+//!             ptr: self.ptr,
+//!             phantom: PhantomData,
+//!         }
 //!     }
 //! }
 //!
@@ -182,6 +187,8 @@
 //! ```
 //!
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::cmp::Ordering;
diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs
index c456e14db12..28f52074495 100644
--- a/src/libcore/char/convert.rs
+++ b/src/libcore/char/convert.rs
@@ -224,6 +224,7 @@ impl TryFrom<u32> for char {
         if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
             Err(CharTryFromError(()))
         } else {
+            // SAFETY: checked that it's a legal unicode value
             Ok(unsafe { from_u32_unchecked(i) })
         }
     }
diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs
index b71c9c2c40b..ae09251c776 100644
--- a/src/libcore/char/decode.rs
+++ b/src/libcore/char/decode.rs
@@ -87,7 +87,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
         };
 
         if u < 0xD800 || 0xDFFF < u {
-            // not a surrogate
+            // SAFETY: not a surrogate
             Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
         } else if u >= 0xDC00 {
             // a trailing surrogate
@@ -107,6 +107,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
 
             // all ok, so lets decode it.
             let c = (((u - 0xD800) as u32) << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
+            // SAFETY: we checked that it's a legal unicode value
             Some(Ok(unsafe { from_u32_unchecked(c) }))
         }
     }
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index 971d89e0044..c048bab287d 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -438,6 +438,7 @@ impl char {
     #[inline]
     pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
         let code = self as u32;
+        // SAFETY: each arm checks the size of the slice and only uses `get_unchecked` unsafe ops
         unsafe {
             let len = if code < MAX_ONE_B && !dst.is_empty() {
                 *dst.get_unchecked_mut(0) = code as u8;
@@ -507,6 +508,7 @@ impl char {
     #[inline]
     pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
         let mut code = self as u32;
+        // SAFETY: each arm checks whether there are enough bits to write into
         unsafe {
             if (code & 0xFFFF) == code && !dst.is_empty() {
                 // The BMP falls through (assuming non-surrogate, as it should)
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 16045f64d46..5058e58d0eb 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -205,11 +205,12 @@ pub trait AsMut<T: ?Sized> {
 /// A value-to-value conversion that consumes the input value. The
 /// opposite of [`From`].
 ///
-/// One should only implement [`Into`] if a conversion to a type outside the current crate is
-/// required. Otherwise one should always prefer implementing [`From`] over [`Into`] because
-/// implementing [`From`] automatically provides one with a implementation of [`Into`] thanks to
-/// the blanket implementation in the standard library. [`From`] cannot do these type of
-/// conversions because of Rust's orphaning rules.
+/// One should avoid implementing [`Into`] and implement [`From`] instead.
+/// Implementing [`From`] automatically provides one with an implementation of [`Into`]
+/// thanks to the blanket implementation in the standard library.
+///
+/// Prefer using [`Into`] over [`From`] when specifying trait bounds on a generic function
+/// to ensure that types that only implement [`Into`] can be used as well.
 ///
 /// **Note: This trait must not fail**. If the conversion can fail, use [`TryInto`].
 ///
@@ -218,13 +219,13 @@ pub trait AsMut<T: ?Sized> {
 /// - [`From`]`<T> for U` implies `Into<U> for T`
 /// - [`Into`] is reflexive, which means that `Into<T> for T` is implemented
 ///
-/// # Implementing [`Into`] for conversions to external types
+/// # Implementing [`Into`] for conversions to external types in old versions of Rust
 ///
-/// If the destination type is not part of the current crate
-/// then you can't implement [`From`] directly.
+/// Prior to Rust 1.40, if the destination type was not part of the current crate
+/// then you couldn't implement [`From`] directly.
 /// For example, take this code:
 ///
-/// ```compile_fail
+/// ```
 /// struct Wrapper<T>(Vec<T>);
 /// impl<T> From<Wrapper<T>> for Vec<T> {
 ///     fn from(w: Wrapper<T>) -> Vec<T> {
@@ -232,9 +233,8 @@ pub trait AsMut<T: ?Sized> {
 ///     }
 /// }
 /// ```
-/// This will fail to compile because we cannot implement a trait for a type
-/// if both the trait and the type are not defined by the current crate.
-/// This is due to Rust's orphaning rules. To bypass this, you can implement [`Into`] directly:
+/// This will fail to compile in older versions of the language because Rust's orphaning rules
+/// used to be a little bit more strict. To bypass this, you could implement [`Into`] directly:
 ///
 /// ```
 /// struct Wrapper<T>(Vec<T>);
@@ -249,9 +249,6 @@ pub trait AsMut<T: ?Sized> {
 /// (as [`From`] does with [`Into`]). Therefore, you should always try to implement [`From`]
 /// and then fall back to [`Into`] if [`From`] can't be implemented.
 ///
-/// Prefer using [`Into`] over [`From`] when specifying trait bounds on a generic function
-/// to ensure that types that only implement [`Into`] can be used as well.
-///
 /// # Examples
 ///
 /// [`String`] implements [`Into`]`<`[`Vec`]`<`[`u8`]`>>`:
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index 569c667ac0a..499dd0facd3 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -315,6 +315,7 @@ impl<'f> Clone for VaListImpl<'f> {
     #[inline]
     fn clone(&self) -> Self {
         let mut dest = crate::mem::MaybeUninit::uninit();
+        // SAFETY: we write to the `MaybeUninit`, thus it is initialized and `assume_init` is legal
         unsafe {
             va_copy(dest.as_mut_ptr(), self);
             dest.assume_init()
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index a2fff913ac7..b52b56b1bdb 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -2,6 +2,8 @@ use crate::fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
 use crate::mem::MaybeUninit;
 use crate::num::flt2dec;
 
+// ignore-tidy-undocumented-unsafe
+
 // Don't inline this so callers don't use the stack space this function
 // requires unless they have to.
 #[inline(never)]
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 0e83a282b18..5a039144f66 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1,5 +1,7 @@
 //! Utilities for formatting and printing strings.
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::cell::{UnsafeCell, Cell, RefCell, Ref, RefMut};
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 3b5c9fbff25..3c7aefc090f 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -1,5 +1,7 @@
 //! Integer and floating-point number formatting
 
+// ignore-tidy-undocumented-unsafe
+
 
 use crate::fmt;
 use crate::ops::{Div, Rem, Sub};
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 020e085abf8..0082363692d 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -79,6 +79,8 @@
 //! }
 //! ```
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 19aeafd882e..194d9e6e2f8 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -1,5 +1,7 @@
 //! An implementation of SipHash.
 
+// ignore-tidy-undocumented-unsafe
+
 #![allow(deprecated)] // the types in this module are deprecated
 
 use crate::marker::PhantomData;
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 368a2f16b28..f68a3e5a76f 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -2,6 +2,8 @@
 
 //! Hints to compiler that affects how code should be emitted or optimized.
 
+// ignore-tidy-undocumented-unsafe
+
 use crate::intrinsics;
 
 /// Informs the compiler that this point in the code is not reachable, enabling
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 3b8edc2ad61..39d571006e6 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -517,8 +517,18 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
         // overflow handling
         loop {
             let mul = n.checked_mul(step);
-            if unsafe { intrinsics::likely(mul.is_some()) } {
-                return self.iter.nth(mul.unwrap() - 1);
+            #[cfg(bootstrap)]
+            {
+                // SAFETY: going away soon
+                if unsafe { intrinsics::likely(mul.is_some()) } {
+                    return self.iter.nth(mul.unwrap() - 1);
+                }
+            }
+            #[cfg(not(bootstrap))]
+            {
+                if intrinsics::likely(mul.is_some()) {
+                    return self.iter.nth(mul.unwrap() - 1);
+                }
             }
             let div_n = usize::MAX / n;
             let div_step = usize::MAX / step;
diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs
index 430ceacdd9f..14d9d5499b8 100644
--- a/src/libcore/iter/adapters/zip.rs
+++ b/src/libcore/iter/adapters/zip.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-undocumented-unsafe
+
 use crate::cmp;
 
 use super::super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen};
diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs
index 00a86417058..bbdb169cac0 100644
--- a/src/libcore/iter/traits/collect.rs
+++ b/src/libcore/iter/traits/collect.rs
@@ -205,6 +205,7 @@ pub trait FromIterator<A>: Sized {
 ///         .collect()
 /// }
 /// ```
+#[rustc_diagnostic_item = "IntoIterator"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait IntoIterator {
     /// The type of the elements being iterated over.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 1b67b05c730..ca431627147 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -89,7 +89,7 @@
 #![feature(nll)]
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(optin_builtin_traits)]
 #![feature(prelude_import)]
 #![feature(repr_simd, platform_intrinsics)]
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 8ccd31c95d5..726d187d2e9 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -26,31 +26,29 @@ macro_rules! panic {
 /// For details, see `std::macros`.
 #[cfg(not(bootstrap))]
 #[macro_export]
-#[allow_internal_unstable(core_panic, panic_internals)]
+#[allow_internal_unstable(core_panic,
+    // FIXME(anp, eddyb) `core_intrinsics` is used here to allow calling
+    // the `caller_location` intrinsic, but once  `#[track_caller]` is implemented,
+    // `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
+    core_intrinsics,
+)]
 #[stable(feature = "core", since = "1.6.0")]
 macro_rules! panic {
     () => (
         $crate::panic!("explicit panic")
     );
-    ($msg:expr) => ({
-        const LOC: &$crate::panic::Location<'_> = &$crate::panic::Location::internal_constructor(
-            $crate::file!(),
-            $crate::line!(),
-            $crate::column!(),
-        );
-        $crate::panicking::panic($msg, LOC)
-    });
+    ($msg:expr) => (
+        $crate::panicking::panic($msg, $crate::intrinsics::caller_location())
+    );
     ($msg:expr,) => (
         $crate::panic!($msg)
     );
-    ($fmt:expr, $($arg:tt)+) => ({
-        const LOC: &$crate::panic::Location<'_> = &$crate::panic::Location::internal_constructor(
-            $crate::file!(),
-            $crate::line!(),
-            $crate::column!(),
-        );
-        $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+), LOC)
-    });
+    ($fmt:expr, $($arg:tt)+) => (
+        $crate::panicking::panic_fmt(
+            $crate::format_args!($fmt, $($arg)+),
+            $crate::intrinsics::caller_location(),
+        )
+    );
 }
 
 /// Asserts that two expressions are equal to each other (using [`PartialEq`]).
@@ -1276,6 +1274,10 @@ pub(crate) mod builtin {
     }
 
     /// Inline assembly.
+    ///
+    /// Read the [unstable book] for the usage.
+    ///
+    /// [unstable book]: ../unstable-book/library-features/asm.html
     #[unstable(feature = "asm", issue = "29722",
                reason = "inline assembly is not stable enough for use and is subject to change")]
     #[rustc_builtin_macro]
diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs
index 792ce9dfad4..e05b40052ee 100644
--- a/src/libcore/mem/maybe_uninit.rs
+++ b/src/libcore/mem/maybe_uninit.rs
@@ -1,6 +1,8 @@
 use crate::intrinsics;
 use crate::mem::ManuallyDrop;
 
+// ignore-tidy-undocumented-unsafe
+
 /// A wrapper type to construct uninitialized instances of `T`.
 ///
 /// # Initialization invariant
@@ -254,10 +256,48 @@ impl<T> MaybeUninit<T> {
     /// [type]: union.MaybeUninit.html
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[inline(always)]
+    #[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "maybe_uninit_uninit")]
     pub const fn uninit() -> MaybeUninit<T> {
         MaybeUninit { uninit: () }
     }
 
+    /// Create a new array of `MaybeUninit<T>` items, in an uninitialized state.
+    ///
+    /// Note: in a future Rust version this method may become unnecessary
+    /// when array literal syntax allows
+    /// [repeating const expressions](https://github.com/rust-lang/rust/issues/49147).
+    /// The example below could then use `let mut buf = [MaybeUninit::<u8>::uninit(); 32];`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)]
+    ///
+    /// use std::mem::MaybeUninit;
+    ///
+    /// extern "C" {
+    ///     fn read_into_buffer(ptr: *mut u8, max_len: usize) -> usize;
+    /// }
+    ///
+    /// /// Returns a (possibly smaller) slice of data that was actually read
+    /// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
+    ///     unsafe {
+    ///         let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
+    ///         MaybeUninit::slice_get_ref(&buf[..len])
+    ///     }
+    /// }
+    ///
+    /// let mut buf: [MaybeUninit<u8>; 32] = MaybeUninit::uninit_array();
+    /// let data = read(&mut buf);
+    /// ```
+    #[unstable(feature = "maybe_uninit_uninit_array", issue = "0")]
+    #[inline(always)]
+    pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
+        unsafe {
+            MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init()
+        }
+    }
+
     /// A promotable constant, equivalent to `uninit()`.
     #[unstable(feature = "internal_uninit_const", issue = "0",
         reason = "hack to work around promotability")]
@@ -300,6 +340,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[inline]
+    #[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "maybe_uninit_zeroed")]
     pub fn zeroed() -> MaybeUninit<T> {
         let mut u = MaybeUninit::<T>::uninit();
         unsafe {
@@ -440,6 +481,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[inline(always)]
+    #[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "assume_init")]
     pub unsafe fn assume_init(self) -> T {
         intrinsics::panic_if_uninhabited::<T>();
         ManuallyDrop::into_inner(self.value)
@@ -509,35 +551,212 @@ impl<T> MaybeUninit<T> {
         self.as_ptr().read()
     }
 
-    /// Gets a reference to the contained value.
+    /// Gets a shared reference to the contained value.
+    ///
+    /// This can be useful when we want to access a `MaybeUninit` that has been
+    /// initialized but don't have ownership of the `MaybeUninit` (preventing the use
+    /// of `.assume_init()`).
     ///
     /// # Safety
     ///
-    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
-    /// state. Calling this when the content is not yet fully initialized causes undefined
-    /// behavior.
+    /// Calling this when the content is not yet fully initialized causes undefined
+    /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
+    /// is in an initialized state.
+    ///
+    /// # Examples
+    ///
+    /// ### Correct usage of this method:
+    ///
+    /// ```rust
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut x = MaybeUninit::<Vec<u32>>::uninit();
+    /// // Initialize `x`:
+    /// unsafe { x.as_mut_ptr().write(vec![1, 2, 3]); }
+    /// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
+    /// // create a shared reference to it:
+    /// let x: &Vec<u32> = unsafe {
+    ///     // Safety: `x` has been initialized.
+    ///     x.get_ref()
+    /// };
+    /// assert_eq!(x, &vec![1, 2, 3]);
+    /// ```
+    ///
+    /// ### *Incorrect* usages of this method:
+    ///
+    /// ```rust,no_run
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let x = MaybeUninit::<Vec<u32>>::uninit();
+    /// let x_vec: &Vec<u32> = unsafe { x.get_ref() };
+    /// // We have created a reference to an uninitialized vector! This is undefined behavior.
+    /// ```
+    ///
+    /// ```rust,no_run
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::{cell::Cell, mem::MaybeUninit};
+    ///
+    /// let b = MaybeUninit::<Cell<bool>>::uninit();
+    /// // Initialize the `MaybeUninit` using `Cell::set`:
+    /// unsafe {
+    ///     b.get_ref().set(true);
+    ///  // ^^^^^^^^^^^
+    ///  // Reference to an uninitialized `Cell<bool>`: UB!
+    /// }
+    /// ```
     #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
     #[inline(always)]
     pub unsafe fn get_ref(&self) -> &T {
+        intrinsics::panic_if_uninhabited::<T>();
         &*self.value
     }
 
-    /// Gets a mutable reference to the contained value.
+    /// Gets a mutable (unique) reference to the contained value.
+    ///
+    /// This can be useful when we want to access a `MaybeUninit` that has been
+    /// initialized but don't have ownership of the `MaybeUninit` (preventing the use
+    /// of `.assume_init()`).
     ///
     /// # Safety
     ///
-    /// It is up to the caller to guarantee that the `MaybeUninit<T>` really is in an initialized
-    /// state. Calling this when the content is not yet fully initialized causes undefined
-    /// behavior.
+    /// Calling this when the content is not yet fully initialized causes undefined
+    /// behavior: it is up to the caller to guarantee that the `MaybeUninit<T>` really
+    /// is in an initialized state. For instance, `.get_mut()` cannot be used to
+    /// initialize a `MaybeUninit`.
+    ///
+    /// # Examples
+    ///
+    /// ### Correct usage of this method:
+    ///
+    /// ```rust
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// # unsafe extern "C" fn initialize_buffer(buf: *mut [u8; 2048]) { *buf = [0; 2048] }
+    /// # #[cfg(FALSE)]
+    /// extern "C" {
+    ///     /// Initializes *all* the bytes of the input buffer.
+    ///     fn initialize_buffer(buf: *mut [u8; 2048]);
+    /// }
+    ///
+    /// let mut buf = MaybeUninit::<[u8; 2048]>::uninit();
+    ///
+    /// // Initialize `buf`:
+    /// unsafe { initialize_buffer(buf.as_mut_ptr()); }
+    /// // Now we know that `buf` has been initialized, so we could `.assume_init()` it.
+    /// // However, using `.assume_init()` may trigger a `memcpy` of the 2048 bytes.
+    /// // To assert our buffer has been initialized without copying it, we upgrade
+    /// // the `&mut MaybeUninit<[u8; 2048]>` to a `&mut [u8; 2048]`:
+    /// let buf: &mut [u8; 2048] = unsafe {
+    ///     // Safety: `buf` has been initialized.
+    ///     buf.get_mut()
+    /// };
+    ///
+    /// // Now we can use `buf` as a normal slice:
+    /// buf.sort_unstable();
+    /// assert!(
+    ///     buf.chunks(2).all(|chunk| chunk[0] <= chunk[1]),
+    ///     "buffer is sorted",
+    /// );
+    /// ```
+    ///
+    /// ### *Incorrect* usages of this method:
+    ///
+    /// You cannot use `.get_mut()` to initialize a value:
+    ///
+    /// ```rust,no_run
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::mem::MaybeUninit;
+    ///
+    /// let mut b = MaybeUninit::<bool>::uninit();
+    /// unsafe {
+    ///     *b.get_mut() = true;
+    ///     // We have created a (mutable) reference to an uninitialized `bool`!
+    ///     // This is undefined behavior.
+    /// }
+    /// ```
+    ///
+    /// For instance, you cannot [`Read`] into an uninitialized buffer:
+    ///
+    /// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
+    ///
+    /// ```rust,no_run
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::{io, mem::MaybeUninit};
+    ///
+    /// fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
+    /// {
+    ///     let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
+    ///     reader.read_exact(unsafe { buffer.get_mut() })?;
+    ///                             // ^^^^^^^^^^^^^^^^
+    ///                             // (mutable) reference to uninitialized memory!
+    ///                             // This is undefined behavior.
+    ///     Ok(unsafe { buffer.assume_init() })
+    /// }
+    /// ```
+    ///
+    /// Nor can you use direct field access to do field-by-field gradual initialization:
+    ///
+    /// ```rust,no_run
+    /// #![feature(maybe_uninit_ref)]
+    /// use std::{mem::MaybeUninit, ptr};
+    ///
+    /// struct Foo {
+    ///     a: u32,
+    ///     b: u8,
+    /// }
+    ///
+    /// let foo: Foo = unsafe {
+    ///     let mut foo = MaybeUninit::<Foo>::uninit();
+    ///     ptr::write(&mut foo.get_mut().a as *mut u32, 1337);
+    ///                  // ^^^^^^^^^^^^^
+    ///                  // (mutable) reference to uninitialized memory!
+    ///                  // This is undefined behavior.
+    ///     ptr::write(&mut foo.get_mut().b as *mut u8, 42);
+    ///                  // ^^^^^^^^^^^^^
+    ///                  // (mutable) reference to uninitialized memory!
+    ///                  // This is undefined behavior.
+    ///     foo.assume_init()
+    /// };
+    /// ```
     // FIXME(#53491): We currently rely on the above being incorrect, i.e., we have references
     // to uninitialized data (e.g., in `libcore/fmt/float.rs`).  We should make
     // a final decision about the rules before stabilization.
     #[unstable(feature = "maybe_uninit_ref", issue = "63568")]
     #[inline(always)]
     pub unsafe fn get_mut(&mut self) -> &mut T {
+        intrinsics::panic_if_uninhabited::<T>();
         &mut *self.value
     }
 
+    /// Assuming all the elements are initialized, get a slice to them.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
+    /// really are in an initialized state.
+    /// Calling this when the content is not yet fully initialized causes undefined behavior.
+    #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")]
+    #[inline(always)]
+    pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] {
+        &*(slice as *const [Self] as *const [T])
+    }
+
+    /// Assuming all the elements are initialized, get a mutable slice to them.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
+    /// really are in an initialized state.
+    /// Calling this when the content is not yet fully initialized causes undefined behavior.
+    #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")]
+    #[inline(always)]
+    pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] {
+        &mut *(slice as *mut [Self] as *mut [T])
+    }
+
     /// Gets a pointer to the first element of the array.
     #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
     #[inline(always)]
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index c7da56aad30..dc7c36ff03c 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -93,6 +93,8 @@ pub fn forget<T>(t: T) {
 #[inline]
 #[unstable(feature = "forget_unsized", issue = "0")]
 pub fn forget_unsized<T: ?Sized>(t: T) {
+    // SAFETY: the forget intrinsic could be safe, but there's no point in making it safe since
+    // we'll be implementing this function soon via `ManuallyDrop`
     unsafe { intrinsics::forget(t) }
 }
 
@@ -266,7 +268,11 @@ pub const fn size_of<T>() -> usize {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
+    #[cfg(bootstrap)]
+    // SAFETY: going away soon
     unsafe { intrinsics::size_of_val(val) }
+    #[cfg(not(bootstrap))]
+    intrinsics::size_of_val(val)
 }
 
 /// Returns the [ABI]-required minimum alignment of a type.
@@ -310,7 +316,11 @@ pub fn min_align_of<T>() -> usize {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(reason = "use `align_of_val` instead", since = "1.2.0")]
 pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
+    #[cfg(bootstrap)]
+    // SAFETY: going away soon
     unsafe { intrinsics::min_align_of_val(val) }
+    #[cfg(not(bootstrap))]
+    intrinsics::min_align_of_val(val)
 }
 
 /// Returns the [ABI]-required minimum alignment of a type.
@@ -350,8 +360,9 @@ pub const fn align_of<T>() -> usize {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
-    unsafe { intrinsics::min_align_of_val(val) }
+    min_align_of_val(val)
 }
 
 /// Returns `true` if dropping values of type `T` matters.
@@ -457,6 +468,7 @@ pub const fn needs_drop<T>() -> bool {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated_in_future)]
 #[allow(deprecated)]
+#[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "mem_zeroed")]
 pub unsafe fn zeroed<T>() -> T {
     intrinsics::panic_if_uninhabited::<T>();
     intrinsics::init()
@@ -485,6 +497,7 @@ pub unsafe fn zeroed<T>() -> T {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated_in_future)]
 #[allow(deprecated)]
+#[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "mem_uninitialized")]
 pub unsafe fn uninitialized<T>() -> T {
     intrinsics::panic_if_uninhabited::<T>();
     intrinsics::uninit()
@@ -508,6 +521,8 @@ pub unsafe fn uninitialized<T>() -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn swap<T>(x: &mut T, y: &mut T) {
+    // SAFETY: the raw pointers have been created from safe mutable references satisfying all the
+    // constraints on `ptr::swap_nonoverlapping_one`
     unsafe {
         ptr::swap_nonoverlapping_one(x, y);
     }
@@ -822,7 +837,11 @@ impl<T> fmt::Debug for Discriminant<T> {
 /// ```
 #[stable(feature = "discriminant_value", since = "1.21.0")]
 pub fn discriminant<T>(v: &T) -> Discriminant<T> {
+    #[cfg(bootstrap)]
+    // SAFETY: going away soon
     unsafe {
         Discriminant(intrinsics::discriminant_value(v), PhantomData)
     }
+    #[cfg(not(bootstrap))]
+    Discriminant(intrinsics::discriminant_value(v), PhantomData)
 }
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index ed89852dc48..64146302626 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -58,6 +58,8 @@ mod fpu_precision {
     pub struct FPUControlWord(u16);
 
     fn set_cw(cw: u16) {
+        // SAFETY: the `fldcw` instruction has been audited to be able to work correctly with
+        // any `u16`
         unsafe { asm!("fldcw $0" :: "m" (cw) :: "volatile") }
     }
 
@@ -74,6 +76,8 @@ mod fpu_precision {
 
         // Get the original value of the control word to restore it later, when the
         // `FPUControlWord` structure is dropped
+        // SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with
+        // any `u16`
         unsafe { asm!("fnstcw $0" : "=*m" (&cw) ::: "volatile") }
 
         // Set the control word to the desired precision. This is achieved by masking away the old
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 5730088c4d9..7662bba6b5e 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -414,6 +414,7 @@ impl f32 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn to_bits(self) -> u32 {
+        // SAFETY: `u32` is a plain old datatype so we can always transmute to it
         unsafe { mem::transmute(self) }
     }
 
@@ -456,6 +457,7 @@ impl f32 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn from_bits(v: u32) -> Self {
+        // SAFETY: `u32` is a plain old datatype so we can always transmute from it
         // It turns out the safety issues with sNaN were overblown! Hooray!
         unsafe { mem::transmute(v) }
     }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 2bdeda340dc..4a2a35dfb09 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -427,6 +427,7 @@ impl f64 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn to_bits(self) -> u64 {
+        // SAFETY: `u64` is a plain old datatype so we can always transmute to it
         unsafe { mem::transmute(self) }
     }
 
@@ -469,6 +470,7 @@ impl f64 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn from_bits(v: u64) -> Self {
+        // SAFETY: `u64` is a plain old datatype so we can always transmute from it
         // It turns out the safety issues with sNaN were overblown! Hooray!
         unsafe { mem::transmute(v) }
     }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index b4ade704144..b5d61a3fd4e 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -71,6 +71,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
                 #[inline]
                 pub fn new(n: $Int) -> Option<Self> {
                     if n != 0 {
+                        // SAFETY: we just checked that there's no `0`
                         Some(unsafe { $Ty(n) })
                     } else {
                         None
@@ -234,7 +235,6 @@ depending on the target pointer size.
 "}
 }
 
-// `Int` + `SignedInt` implemented for signed integers
 macro_rules! int_impl {
     ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr, $Min:expr, $Max:expr, $Feature:expr,
      $EndFeature:expr, $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
@@ -703,6 +703,7 @@ $EndFeature, "
                 if rhs == 0 || (self == Self::min_value() && rhs == -1) {
                     None
                 } else {
+                    // SAFETY: div by zero and by INT_MIN have been checked above
                     Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                 }
             }
@@ -759,6 +760,7 @@ $EndFeature, "
                 if rhs == 0 || (self == Self::min_value() && rhs == -1) {
                     None
                 } else {
+                    // SAFETY: div by zero and by INT_MIN have been checked above
                     Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                 }
             }
@@ -1329,6 +1331,8 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shl(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -1358,6 +1362,8 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shr(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -2113,6 +2119,8 @@ assert_eq!(
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+                // SAFETY: integers are plain old datatypes so we can always transmute them to
+                // arrays of bytes
                 unsafe { mem::transmute(self) }
             }
         }
@@ -2221,6 +2229,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+                // SAFETY: integers are plain old datatypes so we can always transmute to them
                 unsafe { mem::transmute(bytes) }
             }
         }
@@ -2293,7 +2302,6 @@ impl isize {
          usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
 }
 
-// `Int` + `UnsignedInt` implemented for unsigned integers
 macro_rules! uint_impl {
     ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr,
         $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
@@ -2748,6 +2756,8 @@ assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
             pub fn checked_div(self, rhs: Self) -> Option<Self> {
                 match rhs {
                     0 => None,
+                    // SAFETY: div by zero has been checked above and unsigned types have no other
+                    // failure modes for division
                     rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }),
                 }
             }
@@ -2799,6 +2809,8 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
                 if rhs == 0 {
                     None
                 } else {
+                    // SAFETY: div by zero has been checked above and unsigned types have no other
+                    // failure modes for division
                     Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                 }
             }
@@ -3248,6 +3260,8 @@ assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shl(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -3279,6 +3293,8 @@ assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shr(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -3775,11 +3791,11 @@ assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
         fn one_less_than_next_power_of_two(self) -> Self {
             if self <= 1 { return 0; }
 
-            // Because `p > 0`, it cannot consist entirely of leading zeros.
+            let p = self - 1;
+            // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
             // That means the shift is always in-bounds, and some processors
             // (such as intel pre-haswell) have more efficient ctlz
             // intrinsics when the argument is non-zero.
-            let p = self - 1;
             let z = unsafe { intrinsics::ctlz_nonzero(p) };
             <$SelfT>::max_value() >> z
         }
@@ -3925,6 +3941,8 @@ assert_eq!(
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+                // SAFETY: integers are plain old datatypes so we can always transmute them to
+                // arrays of bytes
                 unsafe { mem::transmute(self) }
             }
         }
@@ -4033,6 +4051,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+                // SAFETY: integers are plain old datatypes so we can always transmute to them
                 unsafe { mem::transmute(bytes) }
             }
         }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index f0ac5e749f6..958f31c0fd2 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -133,6 +133,8 @@
 //! [`Box<T>`]: ../../std/boxed/struct.Box.html
 //! [`i32`]: ../../std/primitive.i32.html
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::iter::{FromIterator, FusedIterator, TrustedLen};
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 685b749776b..b88dc336097 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -20,6 +20,8 @@
 //! one function. Currently, the actual symbol is declared in the standard
 //! library, but the location of this may change over time.
 
+// ignore-tidy-undocumented-unsafe
+
 #![allow(dead_code, missing_docs)]
 #![unstable(feature = "core_panic",
             reason = "internal details of the implementation of the `panic!` \
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index be057ed6d59..1219fd09a9d 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -552,6 +552,7 @@ impl<P: Deref> Pin<P> {
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_ref(&self) -> Pin<&P::Target> {
+        // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&*self.pointer) }
     }
 
@@ -610,6 +611,7 @@ impl<P: DerefMut> Pin<P> {
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_mut(&mut self) -> Pin<&mut P::Target> {
+        // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&mut *self.pointer) }
     }
 
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 1355ce1aa43..5a75730cf2b 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -18,6 +18,10 @@
 //! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
 //! * All pointers (except for the null pointer) are valid for all operations of
 //!   [size zero][zst].
+//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer
+//!   be *dereferencable*: the memory range of the given size starting at the pointer must all be
+//!   within the bounds of a single allocated object. Note that in Rust,
+//!   every (stack-allocated) variable is considered a separate allocated object.
 //! * All accesses performed by functions in this module are *non-atomic* in the sense
 //!   of [atomic operations] used to synchronize between threads. This means it is
 //!   undefined behavior to perform two concurrent accesses to the same location from different
@@ -61,6 +65,8 @@
 //! [`write_volatile`]: ./fn.write_volatile.html
 //! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::intrinsics;
@@ -221,10 +227,15 @@ pub(crate) struct FatPtr<T> {
     pub(crate) len: usize,
 }
 
-/// Forms a slice from a pointer and a length.
+/// Forms a raw slice from a pointer and a length.
 ///
 /// The `len` argument is the number of **elements**, not the number of bytes.
 ///
+/// This function is safe, but actually using the return value is unsafe.
+/// See the documentation of [`from_raw_parts`] for slice safety requirements.
+///
+/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
+///
 /// # Examples
 ///
 /// ```rust
@@ -243,12 +254,16 @@ pub fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
     unsafe { Repr { raw: FatPtr { data, len } }.rust }
 }
 
-/// Performs the same functionality as [`from_raw_parts`], except that a
-/// mutable slice is returned.
+/// Performs the same functionality as [`slice_from_raw_parts`], except that a
+/// raw mutable slice is returned, as opposed to a raw immutable slice.
 ///
-/// See the documentation of [`from_raw_parts`] for more details.
+/// See the documentation of [`slice_from_raw_parts`] for more details.
 ///
-/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
+/// This function is safe, but actually using the return value is unsafe.
+/// See the documentation of [`from_raw_parts_mut`] for slice safety requirements.
+///
+/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
+/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
 #[inline]
 #[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")]
 pub fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index 7dcd57f1f98..7599991f0f1 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -7,6 +7,8 @@ use crate::mem;
 use crate::ptr::Unique;
 use crate::cmp::Ordering;
 
+// ignore-tidy-undocumented-unsafe
+
 /// `*mut T` but non-zero and covariant.
 ///
 /// This is often the correct thing to use when building data structures using
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index 3521dd79979..11a3aed1ab4 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -5,6 +5,8 @@ use crate::marker::{PhantomData, Unsize};
 use crate::mem;
 use crate::ptr::NonNull;
 
+// ignore-tidy-undocumented-unsafe
+
 /// A wrapper around a raw non-null `*mut T` that indicates that the possessor
 /// of this wrapper owns the referent. Useful for building abstractions like
 /// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs
index 45ab016c496..2a2169dd348 100644
--- a/src/libcore/slice/memchr.rs
+++ b/src/libcore/slice/memchr.rs
@@ -1,6 +1,8 @@
 // Original implementation taken from rust-memchr.
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
+// ignore-tidy-undocumented-unsafe
+
 use crate::cmp;
 use crate::mem;
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index cdada1252d2..c8fe9f98613 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-filelength
+// ignore-tidy-undocumented-unsafe
 
 //! Slice management and manipulation.
 //!
@@ -5272,18 +5273,24 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 ///
 /// # Safety
 ///
-/// This function is unsafe as there is no guarantee that the given pointer is
-/// valid for `len` elements, nor whether the lifetime inferred is a suitable
-/// lifetime for the returned slice.
+/// Behavior is undefined if any of the following conditions are violated:
 ///
-/// `data` must be non-null and aligned, even for zero-length slices. One
-/// reason for this is that enum layout optimizations may rely on references
-/// (including slices of any length) being aligned and non-null to distinguish
-/// them from other data. You can obtain a pointer that is usable as `data`
-/// for zero-length slices using [`NonNull::dangling()`].
+/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
+///   and it must be properly aligned. This means in particular:
 ///
-/// The total size of the slice must be no larger than `isize::MAX` **bytes**
-/// in memory. See the safety documentation of [`pointer::offset`].
+///     * The entire memory range of this slice must be contained within a single allocated object!
+///       Slices can never span across multiple allocated objects.
+///     * `data` must be non-null and aligned even for zero-length slices. One
+///       reason for this is that enum layout optimizations may rely on references
+///       (including slices of any length) being aligned and non-null to distinguish
+///       them from other data. You can obtain a pointer that is usable as `data`
+///       for zero-length slices using [`NonNull::dangling()`].
+///
+/// * The memory referenced by the returned slice must not be mutated for the duration
+///   of lifetime `'a`, except inside an `UnsafeCell`.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+///   See the safety documentation of [`pointer::offset`].
 ///
 /// # Caveat
 ///
@@ -5305,6 +5312,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 /// assert_eq!(slice[0], 42);
 /// ```
 ///
+/// [valid]: ../../std/ptr/index.html#safety
 /// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
 /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
 #[inline]
@@ -5312,28 +5320,45 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
     debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
     debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
-                  "attempt to create slice covering half the address space");
+                  "attempt to create slice covering at least half the address space");
     &*ptr::slice_from_raw_parts(data, len)
 }
 
 /// Performs the same functionality as [`from_raw_parts`], except that a
 /// mutable slice is returned.
 ///
-/// This function is unsafe for the same reasons as [`from_raw_parts`], as well
-/// as not being able to provide a non-aliasing guarantee of the returned
-/// mutable slice. `data` must be non-null and aligned even for zero-length
-/// slices as with [`from_raw_parts`]. The total size of the slice must be no
-/// larger than `isize::MAX` **bytes** in memory.
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `data` must be [valid] for writes for `len * mem::size_of::<T>()` many bytes,
+///   and it must be properly aligned. This means in particular:
 ///
-/// See the documentation of [`from_raw_parts`] for more details.
+///     * The entire memory range of this slice must be contained within a single allocated object!
+///       Slices can never span across multiple allocated objects.
+///     * `data` must be non-null and aligned even for zero-length slices. One
+///       reason for this is that enum layout optimizations may rely on references
+///       (including slices of any length) being aligned and non-null to distinguish
+///       them from other data. You can obtain a pointer that is usable as `data`
+///       for zero-length slices using [`NonNull::dangling()`].
 ///
+/// * The memory referenced by the returned slice must not be accessed through any other pointer
+///   (not derived from the return value) for the duration of lifetime `'a`.
+///   Both read and write accesses are forbidden.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+///   See the safety documentation of [`pointer::offset`].
+///
+/// [valid]: ../../std/ptr/index.html#safety
+/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
+/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
 /// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
     debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
     debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
-                  "attempt to create slice covering half the address space");
+                  "attempt to create slice covering at least half the address space");
     &mut *ptr::slice_from_raw_parts_mut(data, len)
 }
 
diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs
index 2f2170f7ff1..a719a51b616 100644
--- a/src/libcore/slice/sort.rs
+++ b/src/libcore/slice/sort.rs
@@ -6,6 +6,8 @@
 //! Unstable sorting is compatible with libcore because it doesn't allocate memory, unlike our
 //! stable sorting implementation.
 
+// ignore-tidy-undocumented-unsafe
+
 use crate::cmp;
 use crate::mem::{self, MaybeUninit};
 use crate::ptr;
diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs
index e8f747f1a67..762de0489a9 100644
--- a/src/libcore/str/lossy.rs
+++ b/src/libcore/str/lossy.rs
@@ -3,6 +3,8 @@ use crate::str as core_str;
 use crate::fmt::{self, Write};
 use crate::mem;
 
+// ignore-tidy-undocumented-unsafe
+
 /// Lossy UTF-8 string.
 #[unstable(feature = "str_internals", issue = "0")]
 pub struct Utf8Lossy {
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 1968919f554..25b7eec5b33 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-filelength
+// ignore-tidy-undocumented-unsafe
 
 //! String manipulation.
 //!
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index ad9d956fda1..a494274118a 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -3,6 +3,8 @@
 //! For more details, see the traits [`Pattern`], [`Searcher`],
 //! [`ReverseSearcher`], and [`DoubleEndedSearcher`].
 
+// ignore-tidy-undocumented-unsafe
+
 #![unstable(feature = "pattern",
             reason = "API not fully fleshed out and ready to be stabilized",
             issue = "27721")]
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 73d5abf1aed..d311cb16b64 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -112,6 +112,8 @@
 //! println!("live threads: {}", old_thread_count + 1);
 //! ```
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
index c41d35efced..a35897e9bc1 100644
--- a/src/libcore/tests/num/flt2dec/mod.rs
+++ b/src/libcore/tests/num/flt2dec/mod.rs
@@ -85,6 +85,8 @@ fn ldexp_f64(a: f64, b: i32) -> f64 {
     extern {
         fn ldexp(x: f64, n: i32) -> f64;
     }
+    // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
+    // cause undefined behavior
     unsafe { ldexp(a, b) }
 }
 
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 5a0e4388e03..57fc1a7b760 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -920,7 +920,7 @@ impl fmt::Debug for Duration {
             if end == 0 {
                 write!(f, "{}", integer_part)
             } else {
-                // We are only writing ASCII digits into the buffer and it was
+                // SAFETY: We are only writing ASCII digits into the buffer and it was
                 // initialized with '0's, so it contains valid UTF8.
                 let s = unsafe {
                     crate::str::from_utf8_unchecked(&buf[..end])
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index d22420e76dc..24b19028ac1 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -35,7 +35,7 @@ impl InnerOffset {
 
 /// A piece is a portion of the format string which represents the next part
 /// to emit. These are emitted as a stream by the `Parser` class.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Piece<'a> {
     /// A literal string which should directly be emitted
     String(&'a str),
@@ -45,7 +45,7 @@ pub enum Piece<'a> {
 }
 
 /// Representation of an argument specification.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub struct Argument<'a> {
     /// Where to find this argument
     pub position: Position,
@@ -54,7 +54,7 @@ pub struct Argument<'a> {
 }
 
 /// Specification for the formatting of an argument in the format string.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub struct FormatSpec<'a> {
     /// Optionally specified character to fill alignment with.
     pub fill: Option<char>,
@@ -74,10 +74,12 @@ pub struct FormatSpec<'a> {
     /// this argument, this can be empty or any number of characters, although
     /// it is required to be one word.
     pub ty: &'a str,
+    /// The span of the descriptor string (for diagnostics).
+    pub ty_span: Option<InnerSpan>,
 }
 
 /// Enum describing where an argument for a format can be located.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Position {
     /// The argument is implied to be located at an index
     ArgumentImplicitlyIs(usize),
@@ -97,7 +99,7 @@ impl Position {
 }
 
 /// Enum of alignments which are supported.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Alignment {
     /// The value will be aligned to the left.
     AlignLeft,
@@ -111,7 +113,7 @@ pub enum Alignment {
 
 /// Various flags which can be applied to format strings. The meaning of these
 /// flags is defined by the formatters themselves.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Flag {
     /// A `+` will be used to denote positive numbers.
     FlagSignPlus,
@@ -131,7 +133,7 @@ pub enum Flag {
 
 /// A count is used for the precision and width parameters of an integer, and
 /// can reference either an argument or a literal integer.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
 pub enum Count {
     /// The count is specified explicitly.
     CountIs(usize),
@@ -475,6 +477,7 @@ impl<'a> Parser<'a> {
             width: CountImplied,
             width_span: None,
             ty: &self.input[..0],
+            ty_span: None,
         };
         if !self.consume(':') {
             return spec;
@@ -548,6 +551,7 @@ impl<'a> Parser<'a> {
                 spec.precision_span = sp;
             }
         }
+        let ty_span_start = self.cur.peek().map(|(pos, _)| *pos);
         // Optional radix followed by the actual format specifier
         if self.consume('x') {
             if self.consume('?') {
@@ -567,6 +571,12 @@ impl<'a> Parser<'a> {
             spec.ty = "?";
         } else {
             spec.ty = self.word();
+            let ty_span_end = self.cur.peek().map(|(pos, _)| *pos);
+            if !spec.ty.is_empty() {
+                spec.ty_span = ty_span_start
+                    .and_then(|s| ty_span_end.map(|e| (s, e)))
+                    .map(|(start, end)| self.to_span_index(start).to(self.to_span_index(end)));
+            }
         }
         spec
     }
diff --git a/src/libfmt_macros/tests.rs b/src/libfmt_macros/tests.rs
index e2ddb8810e9..81359033eda 100644
--- a/src/libfmt_macros/tests.rs
+++ b/src/libfmt_macros/tests.rs
@@ -2,7 +2,7 @@ use super::*;
 
 fn same(fmt: &'static str, p: &[Piece<'static>]) {
     let parser = Parser::new(fmt, None, vec![], false);
-    assert!(parser.collect::<Vec<Piece<'static>>>() == p);
+    assert_eq!(parser.collect::<Vec<Piece<'static>>>(), p);
 }
 
 fn fmtdflt() -> FormatSpec<'static> {
@@ -15,6 +15,7 @@ fn fmtdflt() -> FormatSpec<'static> {
         precision_span: None,
         width_span: None,
         ty: "",
+        ty_span: None,
     };
 }
 
@@ -82,7 +83,7 @@ fn format_position_nothing_else() {
 #[test]
 fn format_type() {
     same(
-        "{3:a}",
+        "{3:x}",
         &[NextArgument(Argument {
             position: ArgumentIs(3),
             format: FormatSpec {
@@ -93,7 +94,8 @@ fn format_type() {
                 width: CountImplied,
                 precision_span: None,
                 width_span: None,
-                ty: "a",
+                ty: "x",
+                ty_span: None,
             },
         })]);
 }
@@ -112,6 +114,7 @@ fn format_align_fill() {
                 precision_span: None,
                 width_span: None,
                 ty: "",
+                ty_span: None,
             },
         })]);
     same(
@@ -127,6 +130,7 @@ fn format_align_fill() {
                 precision_span: None,
                 width_span: None,
                 ty: "",
+                ty_span: None,
             },
         })]);
     same(
@@ -142,6 +146,7 @@ fn format_align_fill() {
                 precision_span: None,
                 width_span: None,
                 ty: "abcd",
+                ty_span: Some(InnerSpan::new(6, 10)),
             },
         })]);
 }
@@ -150,7 +155,7 @@ fn format_counts() {
     use syntax_pos::{GLOBALS, Globals, edition};
     GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
     same(
-        "{:10s}",
+        "{:10x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
             format: FormatSpec {
@@ -161,11 +166,12 @@ fn format_counts() {
                 width: CountIs(10),
                 precision_span: None,
                 width_span: None,
-                ty: "s",
+                ty: "x",
+                ty_span: None,
             },
         })]);
     same(
-        "{:10$.10s}",
+        "{:10$.10x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
             format: FormatSpec {
@@ -176,11 +182,12 @@ fn format_counts() {
                 width: CountIsParam(10),
                 precision_span: None,
                 width_span: Some(InnerSpan::new(3, 6)),
-                ty: "s",
+                ty: "x",
+                ty_span: None,
             },
         })]);
     same(
-        "{:.*s}",
+        "{:.*x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(1),
             format: FormatSpec {
@@ -191,11 +198,12 @@ fn format_counts() {
                 width: CountImplied,
                 precision_span: Some(InnerSpan::new(3, 5)),
                 width_span: None,
-                ty: "s",
+                ty: "x",
+                ty_span: None,
             },
         })]);
     same(
-        "{:.10$s}",
+        "{:.10$x}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
             format: FormatSpec {
@@ -206,11 +214,12 @@ fn format_counts() {
                 width: CountImplied,
                 precision_span: Some(InnerSpan::new(3, 7)),
                 width_span: None,
-                ty: "s",
+                ty: "x",
+                ty_span: None,
             },
         })]);
     same(
-        "{:a$.b$s}",
+        "{:a$.b$?}",
         &[NextArgument(Argument {
             position: ArgumentImplicitlyIs(0),
             format: FormatSpec {
@@ -221,7 +230,8 @@ fn format_counts() {
                 width: CountIsName(Symbol::intern("a")),
                 precision_span: None,
                 width_span: None,
-                ty: "s",
+                ty: "?",
+                ty_span: None,
             },
         })]);
     });
@@ -241,6 +251,7 @@ fn format_flags() {
                 precision_span: None,
                 width_span: None,
                 ty: "",
+                ty_span: None,
             },
         })]);
     same(
@@ -256,13 +267,14 @@ fn format_flags() {
                 precision_span: None,
                 width_span: None,
                 ty: "",
+                ty_span: None,
             },
         })]);
 }
 #[test]
 fn format_mixture() {
     same(
-        "abcd {3:a} efg",
+        "abcd {3:x} efg",
         &[
             String("abcd "),
             NextArgument(Argument {
@@ -275,7 +287,8 @@ fn format_mixture() {
                     width: CountImplied,
                     precision_span: None,
                     width_span: None,
-                    ty: "a",
+                    ty: "x",
+                    ty_span: None,
                 },
             }),
             String(" efg"),
diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs
index 5509f47bc88..bc9dd2edaf2 100644
--- a/src/libpanic_abort/lib.rs
+++ b/src/libpanic_abort/lib.rs
@@ -21,6 +21,7 @@
 // Rust's "try" function, but if we're aborting on panics we just call the
 // function as there's nothing else we need to do here.
 #[rustc_std_internal_symbol]
+#[allow(improper_ctypes)]
 pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                               data: *mut u8,
                                               _data_ptr: *mut usize,
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index d2a0ef7b1dd..7de347446ad 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -69,6 +69,7 @@ mod dwarf;
 // hairy and tightly coupled, for more information see the compiler's
 // implementation of this.
 #[no_mangle]
+#[allow(improper_ctypes)]
 pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                                   data: *mut u8,
                                                   data_ptr: *mut usize,
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index de67f46eba6..92b94af75d7 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -39,5 +39,5 @@ parking_lot = "0.9"
 byteorder = { version = "1.3" }
 chalk-engine = { version = "0.9.0", default-features=false }
 rustc_fs_util = { path = "../librustc_fs_util" }
-smallvec = { version = "0.6.8", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "0.4"
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 3daf0fc9df7..9b13a910c61 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -304,7 +304,7 @@ impl DropArena {
         // Move the content to the arena by copying it and then forgetting
         // the content of the SmallVec
         vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
-        mem::forget(vec.drain());
+        mem::forget(vec.drain(..));
 
         // Record the destructors after doing the allocation as that may panic
         // and would cause `object`'s destuctor to run twice if it was recorded before
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index dea8d70aaf4..cea790375fc 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -525,7 +525,7 @@ impl<'tcx> DepNodeParams<'tcx> for CrateNum {
     }
 
     fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
-        tcx.crate_name(*self).as_str().to_string()
+        tcx.crate_name(*self).to_string()
     }
 }
 
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 3e35add9616..f40b892a06b 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -335,7 +335,7 @@ This works because `Box` is a pointer, so its size is well-known.
 "##,
 
 E0080: r##"
-This error indicates that the compiler was unable to sensibly evaluate an
+This error indicates that the compiler was unable to sensibly evaluate a
 constant expression that had to be evaluated. Attempting to divide by 0
 or causing integer overflow are two ways to induce this error. For example:
 
@@ -607,7 +607,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -639,7 +639,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -669,7 +669,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -2336,6 +2336,7 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
     E0657, // `impl Trait` can only capture lifetimes bound at the fn level
     E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
+    E0703, // invalid ABI
 //  E0707, // multiple elided lifetimes used in arguments of `async fn`
     E0708, // `async` non-`move` closures with parameters are not currently
            // supported
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index d4d7af92fe3..025494e3fd7 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -40,10 +40,10 @@ pub enum NonMacroAttrKind {
     Tool,
     /// Single-segment custom attribute registered by a derive macro (`#[serde(default)]`).
     DeriveHelper,
+    /// Single-segment custom attribute registered with `#[register_attr]`.
+    Registered,
     /// Single-segment custom attribute registered by a legacy plugin (`register_attribute`).
     LegacyPluginHelper,
-    /// Single-segment custom attribute not registered in any way (`#[my_attr]`).
-    Custom,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
@@ -329,8 +329,24 @@ impl NonMacroAttrKind {
             NonMacroAttrKind::Builtin => "built-in attribute",
             NonMacroAttrKind::Tool => "tool attribute",
             NonMacroAttrKind::DeriveHelper => "derive helper attribute",
+            NonMacroAttrKind::Registered => "explicitly registered attribute",
             NonMacroAttrKind::LegacyPluginHelper => "legacy plugin helper attribute",
-            NonMacroAttrKind::Custom => "custom attribute",
+        }
+    }
+
+    pub fn article(self) -> &'static str {
+        match self {
+            NonMacroAttrKind::Registered => "an",
+            _ => "a",
+        }
+    }
+
+    /// Users of some attributes cannot mark them as used, so they are considered always used.
+    pub fn is_used(self) -> bool {
+        match self {
+            NonMacroAttrKind::Tool | NonMacroAttrKind::DeriveHelper => true,
+            NonMacroAttrKind::Builtin | NonMacroAttrKind::Registered |
+            NonMacroAttrKind::LegacyPluginHelper => false,
         }
     }
 }
@@ -389,6 +405,7 @@ impl<Id> Res<Id> {
     pub fn article(&self) -> &'static str {
         match *self {
             Res::Def(kind, _) => kind.article(),
+            Res::NonMacroAttr(kind) => kind.article(),
             Res::Err => "an",
             _ => "a",
         }
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 920635d8387..29e3f713276 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -45,7 +45,7 @@ pub enum FnKind<'a> {
     ItemFn(Ident, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
 
     /// `fn foo(&self)`
-    Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]),
+    Method(Ident, &'a FnSig, Option<&'a Visibility>, &'a [Attribute]),
 
     /// `|x, y| {}`
     Closure(&'a [Attribute]),
@@ -481,13 +481,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_ty(typ);
             visitor.visit_nested_body(body);
         }
-        ItemKind::Fn(ref declaration, header, ref generics, body_id) => {
+        ItemKind::Fn(ref sig, ref generics, body_id) => {
             visitor.visit_fn(FnKind::ItemFn(item.ident,
                                             generics,
-                                            header,
+                                            sig.header,
                                             &item.vis,
                                             &item.attrs),
-                             declaration,
+                             &sig.decl,
                              body_id,
                              item.span,
                              item.hir_id)
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 6b6032516ca..2c8e14f2add 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -44,8 +44,7 @@ use crate::hir::def::{Namespace, Res, DefKind, PartialRes, PerNS};
 use crate::hir::{GenericArg, ConstArg};
 use crate::hir::ptr::P;
 use crate::lint;
-use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
-                    ELIDED_LIFETIMES_IN_PATHS};
+use crate::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
 use crate::middle::cstore::CrateStore;
 use crate::session::Session;
 use crate::session::config::nightly_options;
@@ -65,9 +64,8 @@ use syntax::ast;
 use syntax::ptr::P as AstP;
 use syntax::ast::*;
 use syntax::errors;
-use syntax::expand::SpecialDerives;
 use syntax::print::pprust;
-use syntax::parse::token::{self, Nonterminal, Token};
+use syntax::token::{self, Nonterminal, Token};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::sess::ParseSess;
 use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
@@ -184,9 +182,9 @@ pub trait Resolver {
         ns: Namespace,
     ) -> (ast::Path, Res<NodeId>);
 
-    fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool;
-
     fn lint_buffer(&mut self) -> &mut lint::LintBuffer;
+
+    fn next_node_id(&mut self) -> NodeId;
 }
 
 type NtToTokenstream = fn(&Nonterminal, &ParseSess, Span) -> TokenStream;
@@ -301,7 +299,6 @@ enum ParamMode {
 
 enum ParenthesizedGenericArgs {
     Ok,
-    Warn,
     Err,
 }
 
@@ -677,7 +674,8 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn next_id(&mut self) -> hir::HirId {
-        self.lower_node_id(self.sess.next_node_id())
+        let node_id = self.resolver.next_node_id();
+        self.lower_node_id(node_id)
     }
 
     fn lower_res(&mut self, res: Res<NodeId>) -> Res {
@@ -786,7 +784,7 @@ impl<'a> LoweringContext<'a> {
         hir_name: ParamName,
         parent_index: DefIndex,
     ) -> hir::GenericParam {
-        let node_id = self.sess.next_node_id();
+        let node_id = self.resolver.next_node_id();
 
         // Get the name we'll use to make the def-path. Note
         // that collisions are ok here and this shouldn't
@@ -1000,14 +998,20 @@ impl<'a> LoweringContext<'a> {
         // Note that we explicitly do not walk the path. Since we don't really
         // lower attributes (we use the AST version) there is nowhere to keep
         // the `HirId`s. We don't actually need HIR version of attributes anyway.
+        let kind = match attr.kind {
+            AttrKind::Normal(ref item) => {
+                AttrKind::Normal(AttrItem {
+                    path: item.path.clone(),
+                    tokens: self.lower_token_stream(item.tokens.clone()),
+                })
+            }
+            AttrKind::DocComment(comment) => AttrKind::DocComment(comment)
+        };
+
         Attribute {
-            item: AttrItem {
-                path: attr.path.clone(),
-                tokens: self.lower_token_stream(attr.tokens.clone()),
-            },
+            kind,
             id: attr.id,
             style: attr.style,
-            is_sugared_doc: attr.is_sugared_doc,
             span: attr.span,
         }
     }
@@ -1105,7 +1109,7 @@ impl<'a> LoweringContext<'a> {
                     // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
                     // constructing the HIR for `impl bounds...` and then lowering that.
 
-                    let impl_trait_node_id = self.sess.next_node_id();
+                    let impl_trait_node_id = self.resolver.next_node_id();
                     let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
                     self.resolver.definitions().create_def_with_parent(
                         parent_def_index,
@@ -1116,9 +1120,10 @@ impl<'a> LoweringContext<'a> {
                     );
 
                     self.with_dyn_type_scope(false, |this| {
+                        let node_id = this.resolver.next_node_id();
                         let ty = this.lower_ty(
                             &Ty {
-                                id: this.sess.next_node_id(),
+                                id: node_id,
                                 kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
                                 span: constraint.span,
                             },
@@ -1212,8 +1217,8 @@ impl<'a> LoweringContext<'a> {
                                     &NodeMap::default(),
                                     ImplTraitContext::disallowed(),
                                 ),
-                                unsafety: this.lower_unsafety(f.unsafety),
-                                abi: f.abi,
+                                unsafety: f.unsafety,
+                                abi: this.lower_abi(f.abi),
                                 decl: this.lower_fn_decl(&f.decl, None, false, None),
                                 param_names: this.lower_fn_params_to_names(&f.decl),
                             }))
@@ -1585,7 +1590,7 @@ impl<'a> LoweringContext<'a> {
                         name,
                     }));
 
-                    let def_node_id = self.context.sess.next_node_id();
+                    let def_node_id = self.context.resolver.next_node_id();
                     let hir_id =
                         self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id);
                     self.context.resolver.definitions().create_def_with_parent(
@@ -1698,29 +1703,19 @@ impl<'a> LoweringContext<'a> {
                     };
                     let parenthesized_generic_args = match partial_res.base_res() {
                         // `a::b::Trait(Args)`
-                        Res::Def(DefKind::Trait, _)
-                            if i + 1 == proj_start => ParenthesizedGenericArgs::Ok,
+                        Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
+                            ParenthesizedGenericArgs::Ok
+                        }
                         // `a::b::Trait(Args)::TraitItem`
-                        Res::Def(DefKind::Method, _)
-                        | Res::Def(DefKind::AssocConst, _)
-                        | Res::Def(DefKind::AssocTy, _)
-                            if i + 2 == proj_start =>
-                        {
+                        Res::Def(DefKind::Method, _) |
+                        Res::Def(DefKind::AssocConst, _) |
+                        Res::Def(DefKind::AssocTy, _) if i + 2 == proj_start => {
                             ParenthesizedGenericArgs::Ok
                         }
                         // Avoid duplicated errors.
                         Res::Err => ParenthesizedGenericArgs::Ok,
                         // An error
-                        Res::Def(DefKind::Struct, _)
-                        | Res::Def(DefKind::Enum, _)
-                        | Res::Def(DefKind::Union, _)
-                        | Res::Def(DefKind::TyAlias, _)
-                        | Res::Def(DefKind::Variant, _) if i + 1 == proj_start =>
-                        {
-                            ParenthesizedGenericArgs::Err
-                        }
-                        // A warning for now, for compatibility reasons.
-                        _ => ParenthesizedGenericArgs::Warn,
+                        _ => ParenthesizedGenericArgs::Err,
                     };
 
                     let num_lifetimes = type_def_id.map_or(0, |def_id| {
@@ -1783,7 +1778,7 @@ impl<'a> LoweringContext<'a> {
                 segment,
                 param_mode,
                 0,
-                ParenthesizedGenericArgs::Warn,
+                ParenthesizedGenericArgs::Err,
                 itctx.reborrow(),
                 None,
             ));
@@ -1859,15 +1854,6 @@ impl<'a> LoweringContext<'a> {
                 }
                 GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
                     ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
-                    ParenthesizedGenericArgs::Warn => {
-                        self.resolver.lint_buffer().buffer_lint(
-                            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
-                            CRATE_NODE_ID,
-                            data.span,
-                            msg.into(),
-                        );
-                        (hir::GenericArgs::none(), true)
-                    }
                     ParenthesizedGenericArgs::Err => {
                         let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
                         err.span_label(data.span, "only `Fn` traits may use parentheses");
@@ -2095,13 +2081,6 @@ impl<'a> LoweringContext<'a> {
         }, ids)
     }
 
-    fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
-        match m {
-            Mutability::Mutable => hir::MutMutable,
-            Mutability::Immutable => hir::MutImmutable,
-        }
-    }
-
     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
         // as they are not explicit in HIR/Ty function signatures.
@@ -2671,7 +2650,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_>) -> hir::MutTy {
         hir::MutTy {
             ty: self.lower_ty(&mt.ty, itctx),
-            mutbl: self.lower_mutability(mt.mutbl),
+            mutbl: mt.mutbl,
         }
     }
 
@@ -2772,7 +2751,7 @@ impl<'a> LoweringContext<'a> {
             }
             PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
             PatKind::Ref(ref inner, mutbl) => {
-                hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
+                hir::PatKind::Ref(self.lower_pat(inner), mutbl)
             }
             PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => hir::PatKind::Range(
                 P(self.lower_expr(e1)),
@@ -3252,7 +3231,7 @@ impl<'a> LoweringContext<'a> {
             Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
 
             None => (
-                self.sess.next_node_id(),
+                self.resolver.next_node_id(),
                 "`&` without an explicit lifetime name cannot be used here",
                 "explicit lifetime name needed here",
             ),
@@ -3289,7 +3268,7 @@ impl<'a> LoweringContext<'a> {
                     span,
                     "expected 'implicit elided lifetime not allowed' error",
                 );
-                let id = self.sess.next_node_id();
+                let id = self.resolver.next_node_id();
                 self.new_named_lifetime(id, span, hir::LifetimeName::Error)
             }
             // `PassThrough` is the normal case.
@@ -3385,7 +3364,7 @@ pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
     // either in std or core, i.e. has either a `::std::ops::Range` or
     // `::core::ops::Range` prefix.
     fn is_range_path(path: &Path) -> bool {
-        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.as_str().to_string()).collect();
+        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
         let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
 
         // "{{root}}" is the equivalent of `::` prefix in `Path`.
@@ -3426,7 +3405,7 @@ pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
         ExprKind::Call(ref func, _) => {
             if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
                 if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
-                    let new_call = segment.ident.as_str() == "new";
+                    let new_call = segment.ident.name == sym::new;
                     return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
                 }
             }
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 73db762a64b..62f3eaef244 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -64,7 +64,6 @@ impl LoweringContext<'_> {
                 hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
             }
             ExprKind::AddrOf(m, ref ohs) => {
-                let m = self.lower_mutability(m);
                 let ohs = P(self.lower_expr(ohs));
                 hir::ExprKind::AddrOf(m, ohs)
             }
@@ -474,7 +473,6 @@ impl LoweringContext<'_> {
         async_gen_kind: hir::AsyncGeneratorKind,
         body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
     ) -> hir::ExprKind {
-        let capture_clause = self.lower_capture_clause(capture_clause);
         let output = match ret_ty {
             Some(ty) => FunctionRetTy::Ty(ty),
             None => FunctionRetTy::Default(span),
@@ -495,7 +493,7 @@ impl LoweringContext<'_> {
             decl,
             body_id,
             span,
-            Some(hir::GeneratorMovability::Static)
+            Some(hir::Movability::Static)
         );
         let generator = hir::Expr {
             hir_id: self.lower_node_id(closure_node_id),
@@ -595,7 +593,7 @@ impl LoweringContext<'_> {
         };
 
         // `::std::task::Poll::Ready(result) => break result`
-        let loop_node_id = self.sess.next_node_id();
+        let loop_node_id = self.resolver.next_node_id();
         let loop_hir_id = self.lower_node_id(loop_node_id);
         let ready_arm = {
             let x_ident = Ident::with_dummy_span(sym::result);
@@ -701,7 +699,6 @@ impl LoweringContext<'_> {
                 generator_kind,
                 movability,
             );
-            let capture_clause = this.lower_capture_clause(capture_clause);
             this.current_item = prev;
             hir::ExprKind::Closure(
                 capture_clause,
@@ -713,20 +710,13 @@ impl LoweringContext<'_> {
         })
     }
 
-    fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
-        match c {
-            CaptureBy::Value => hir::CaptureByValue,
-            CaptureBy::Ref => hir::CaptureByRef,
-        }
-    }
-
     fn generator_movability_for_fn(
         &mut self,
         decl: &FnDecl,
         fn_decl_span: Span,
         generator_kind: Option<hir::GeneratorKind>,
         movability: Movability,
-    ) -> Option<hir::GeneratorMovability> {
+    ) -> Option<hir::Movability> {
         match generator_kind {
             Some(hir::GeneratorKind::Gen) =>  {
                 if !decl.inputs.is_empty() {
@@ -737,10 +727,7 @@ impl LoweringContext<'_> {
                         "generators cannot have explicit parameters"
                     );
                 }
-                Some(match movability {
-                    Movability::Movable => hir::GeneratorMovability::Movable,
-                    Movability::Static => hir::GeneratorMovability::Static,
-                })
+                Some(movability)
             },
             Some(hir::GeneratorKind::Async(_)) => {
                 bug!("non-`async` closure body turned `async` during lowering");
@@ -811,7 +798,7 @@ impl LoweringContext<'_> {
                 this.expr(fn_decl_span, async_body, ThinVec::new())
             });
             hir::ExprKind::Closure(
-                this.lower_capture_clause(capture_clause),
+                capture_clause,
                 fn_decl,
                 body_id,
                 fn_decl_span,
@@ -1350,7 +1337,7 @@ impl LoweringContext<'_> {
     }
 
     fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> hir::Expr {
-        self.expr(span, hir::ExprKind::AddrOf(hir::MutMutable, e), ThinVec::new())
+        self.expr(span, hir::ExprKind::AddrOf(hir::Mutability::Mutable, e), ThinVec::new())
     }
 
     fn expr_unit(&mut self, sp: Span) -> hir::Expr {
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 9da87090c79..aafdd78e3e8 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -12,14 +12,14 @@ use crate::hir::def::{Res, DefKind};
 use crate::util::nodemap::NodeMap;
 
 use rustc_data_structures::thin_vec::ThinVec;
+use rustc_target::spec::abi;
 
 use std::collections::BTreeSet;
 use smallvec::SmallVec;
 use syntax::attr;
 use syntax::ast::*;
 use syntax::visit::{self, Visitor};
-use syntax::expand::SpecialDerives;
-use syntax::source_map::{respan, DesugaringKind, Spanned};
+use syntax::source_map::{respan, DesugaringKind};
 use syntax::symbol::{kw, sym};
 use syntax_pos::Span;
 
@@ -227,13 +227,7 @@ impl LoweringContext<'_> {
     pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
         let mut ident = i.ident;
         let mut vis = self.lower_visibility(&i.vis, None);
-        let mut attrs = self.lower_attrs_extendable(&i.attrs);
-        if self.resolver.has_derives(i.id, SpecialDerives::PARTIAL_EQ | SpecialDerives::EQ) {
-            // Add `#[structural_match]` if the item derived both `PartialEq` and `Eq`.
-            let ident = Ident::new(sym::structural_match, i.span);
-            attrs.push(attr::mk_attr_outer(attr::mk_word_item(ident)));
-        }
-        let attrs = attrs.into();
+        let attrs = self.lower_attrs(&i.attrs);
 
         if let ItemKind::MacroDef(ref def) = i.kind {
             if !def.legacy || attr::contains_name(&i.attrs, sym::macro_export) {
@@ -295,7 +289,7 @@ impl LoweringContext<'_> {
                             ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
                         }
                     ),
-                    self.lower_mutability(m),
+                    m,
                     self.lower_const_body(e),
                 )
             }
@@ -312,7 +306,7 @@ impl LoweringContext<'_> {
                     self.lower_const_body(e)
                 )
             }
-            ItemKind::Fn(ref decl, header, ref generics, ref body) => {
+            ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
                 let fn_def_id = self.resolver.definitions().local_def_id(id);
                 self.with_new_scopes(|this| {
                     this.current_item = Some(ident.span);
@@ -323,7 +317,7 @@ impl LoweringContext<'_> {
                     // declaration (decl), not the return types.
                     let body_id = this.lower_maybe_async_body(&decl, header.asyncness.node, body);
 
-                    let (generics, fn_decl) = this.add_in_band_defs(
+                    let (generics, decl) = this.add_in_band_defs(
                         generics,
                         fn_def_id,
                         AnonymousLifetimeMode::PassThrough,
@@ -334,13 +328,8 @@ impl LoweringContext<'_> {
                             header.asyncness.node.opt_return_id()
                         ),
                     );
-
-                    hir::ItemKind::Fn(
-                        fn_decl,
-                        this.lower_fn_header(header),
-                        generics,
-                        body_id,
-                    )
+                    let sig = hir::FnSig { decl, header: this.lower_fn_header(header) };
+                    hir::ItemKind::Fn(sig, generics, body_id)
                 })
             }
             ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
@@ -444,8 +433,8 @@ impl LoweringContext<'_> {
                 );
 
                 hir::ItemKind::Impl(
-                    self.lower_unsafety(unsafety),
-                    self.lower_impl_polarity(polarity),
+                    unsafety,
+                    polarity,
                     self.lower_defaultness(defaultness, true /* [1] */),
                     generics,
                     trait_ref,
@@ -460,8 +449,8 @@ impl LoweringContext<'_> {
                     .map(|item| self.lower_trait_item_ref(item))
                     .collect();
                 hir::ItemKind::Trait(
-                    self.lower_is_auto(is_auto),
-                    self.lower_unsafety(unsafety),
+                    is_auto,
+                    unsafety,
                     self.lower_generics(generics, ImplTraitContext::disallowed()),
                     bounds,
                     items,
@@ -533,7 +522,7 @@ impl LoweringContext<'_> {
                     let ident = *ident;
                     let mut path = path.clone();
                     for seg in &mut path.segments {
-                        seg.id = self.sess.next_node_id();
+                        seg.id = self.resolver.next_node_id();
                     }
                     let span = path.span;
 
@@ -610,7 +599,7 @@ impl LoweringContext<'_> {
 
                     // Give the segments new node-ids since they are being cloned.
                     for seg in &mut prefix.segments {
-                        seg.id = self.sess.next_node_id();
+                        seg.id = self.resolver.next_node_id();
                     }
 
                     // Each `use` import is an item and thus are owners of the
@@ -730,7 +719,7 @@ impl LoweringContext<'_> {
                 }
                 ForeignItemKind::Static(ref t, m) => {
                     hir::ForeignItemKind::Static(
-                        self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_mutability(m))
+                        self.lower_ty(t, ImplTraitContext::disallowed()), m)
                 }
                 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
                 ForeignItemKind::Macro(_) => panic!("macro shouldn't exist here"),
@@ -742,7 +731,7 @@ impl LoweringContext<'_> {
 
     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
         hir::ForeignMod {
-            abi: fm.abi,
+            abi: self.lower_abi(fm.abi),
             items: fm.items
                 .iter()
                 .map(|x| self.lower_foreign_item(x))
@@ -1022,13 +1011,6 @@ impl LoweringContext<'_> {
         }
     }
 
-    fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
-        match i {
-            ImplPolarity::Positive => hir::ImplPolarity::Positive,
-            ImplPolarity::Negative => hir::ImplPolarity::Negative,
-        }
-    }
-
     fn record_body(&mut self, params: HirVec<hir::Param>, value: hir::Expr) -> hir::BodyId {
         let body = hir::Body {
             generator_kind: self.generator_kind,
@@ -1266,11 +1248,11 @@ impl LoweringContext<'_> {
     fn lower_method_sig(
         &mut self,
         generics: &Generics,
-        sig: &MethodSig,
+        sig: &FnSig,
         fn_def_id: DefId,
         impl_trait_return_allow: bool,
         is_async: Option<NodeId>,
-    ) -> (hir::Generics, hir::MethodSig) {
+    ) -> (hir::Generics, hir::FnSig) {
         let header = self.lower_fn_header(sig.header);
         let (generics, decl) = self.add_in_band_defs(
             generics,
@@ -1283,37 +1265,36 @@ impl LoweringContext<'_> {
                 is_async,
             ),
         );
-        (generics, hir::MethodSig { header, decl })
-    }
-
-    fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {
-        match a {
-            IsAuto::Yes => hir::IsAuto::Yes,
-            IsAuto::No => hir::IsAuto::No,
-        }
+        (generics, hir::FnSig { header, decl })
     }
 
     fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
         hir::FnHeader {
-            unsafety: self.lower_unsafety(h.unsafety),
+            unsafety: h.unsafety,
             asyncness: self.lower_asyncness(h.asyncness.node),
-            constness: self.lower_constness(h.constness),
-            abi: h.abi,
+            constness: h.constness.node,
+            abi: self.lower_abi(h.abi),
         }
     }
 
-    pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
-        match u {
-            Unsafety::Unsafe => hir::Unsafety::Unsafe,
-            Unsafety::Normal => hir::Unsafety::Normal,
-        }
+    pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
+        abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
+            self.error_on_invalid_abi(abi);
+            abi::Abi::Rust
+        })
     }
 
-    fn lower_constness(&mut self, c: Spanned<Constness>) -> hir::Constness {
-        match c.node {
-            Constness::Const => hir::Constness::Const,
-            Constness::NotConst => hir::Constness::NotConst,
-        }
+    fn error_on_invalid_abi(&self, abi: Abi) {
+        struct_span_err!(
+            self.sess,
+            abi.span,
+            E0703,
+            "invalid ABI: found `{}`",
+            abi.symbol
+        )
+        .span_label(abi.span, "invalid ABI")
+        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
+        .emit();
     }
 
     fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs
index f670d5abe85..f25f3b5741a 100644
--- a/src/librustc/hir/map/blocks.rs
+++ b/src/librustc/hir/map/blocks.rs
@@ -158,25 +158,25 @@ impl<'a> FnLikeNode<'a> {
 
     pub fn body(self) -> ast::BodyId {
         self.handle(|i: ItemFnParts<'a>| i.body,
-                    |_, _, _: &'a ast::MethodSig, _, body: ast::BodyId, _, _| body,
+                    |_, _, _: &'a ast::FnSig, _, body: ast::BodyId, _, _| body,
                     |c: ClosureParts<'a>| c.body)
     }
 
     pub fn decl(self) -> &'a FnDecl {
         self.handle(|i: ItemFnParts<'a>| &*i.decl,
-                    |_, _, sig: &'a ast::MethodSig, _, _, _, _| &sig.decl,
+                    |_, _, sig: &'a ast::FnSig, _, _, _, _| &sig.decl,
                     |c: ClosureParts<'a>| c.decl)
     }
 
     pub fn span(self) -> Span {
         self.handle(|i: ItemFnParts<'_>| i.span,
-                    |_, _, _: &'a ast::MethodSig, _, _, span, _| span,
+                    |_, _, _: &'a ast::FnSig, _, _, span, _| span,
                     |c: ClosureParts<'_>| c.span)
     }
 
     pub fn id(self) -> ast::HirId {
         self.handle(|i: ItemFnParts<'_>| i.id,
-                    |id, _, _: &'a ast::MethodSig, _, _, _, _| id,
+                    |id, _, _: &'a ast::FnSig, _, _, _, _| id,
                     |c: ClosureParts<'_>| c.id)
     }
 
@@ -199,7 +199,7 @@ impl<'a> FnLikeNode<'a> {
         let closure = |c: ClosureParts<'a>| {
             FnKind::Closure(c.attrs)
         };
-        let method = |_, ident: Ident, sig: &'a ast::MethodSig, vis, _, _, attrs| {
+        let method = |_, ident: Ident, sig: &'a ast::FnSig, vis, _, _, attrs| {
             FnKind::Method(ident, sig, vis, attrs)
         };
         self.handle(item, method, closure)
@@ -209,7 +209,7 @@ impl<'a> FnLikeNode<'a> {
         I: FnOnce(ItemFnParts<'a>) -> A,
         M: FnOnce(ast::HirId,
                   Ident,
-                  &'a ast::MethodSig,
+                  &'a ast::FnSig,
                   Option<&'a ast::Visibility>,
                   ast::BodyId,
                   Span,
@@ -219,16 +219,16 @@ impl<'a> FnLikeNode<'a> {
     {
         match self.node {
             map::Node::Item(i) => match i.kind {
-                ast::ItemKind::Fn(ref decl, header, ref generics, block) =>
+                ast::ItemKind::Fn(ref sig, ref generics, block) =>
                     item_fn(ItemFnParts {
                         id: i.hir_id,
                         ident: i.ident,
-                        decl: &decl,
+                        decl: &sig.decl,
                         body: block,
                         vis: &i.vis,
                         span: i.span,
                         attrs: &i.attrs,
-                        header,
+                        header: sig.header,
                         generics,
                     }),
                 _ => bug!("item FnLikeNode that is not fn-like"),
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index e9970e30bf9..d858e00a2e9 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -4,7 +4,7 @@ use crate::hir::def_id::DefIndex;
 use syntax::ast::*;
 use syntax::visit;
 use syntax::symbol::{kw, sym};
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax_pos::hygiene::ExpnId;
 use syntax_pos::Span;
 
@@ -100,7 +100,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
 
         // Pick the def data. This need not be unique, but the more
         // information we encapsulate into, the better
-        let def_data = match i.kind {
+        let def_data = match &i.kind {
             ItemKind::Impl(..) => DefPathData::Impl,
             ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
                 return visit::walk_item(self, i);
@@ -109,19 +109,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
             ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
             ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
-            ItemKind::Fn(
-                ref decl,
-                ref header,
-                ref generics,
-                ref body,
-            ) if header.asyncness.node.is_async() => {
+            ItemKind::Fn(sig, generics, body) if sig.header.asyncness.node.is_async() => {
                 return self.visit_async_fn(
                     i.id,
                     i.ident.name,
                     i.span,
-                    header,
+                    &sig.header,
                     generics,
-                    decl,
+                    &sig.decl,
                     body,
                 )
             }
@@ -228,7 +223,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
 
     fn visit_impl_item(&mut self, ii: &'a ImplItem) {
         let def_data = match ii.kind {
-            ImplItemKind::Method(MethodSig {
+            ImplItemKind::Method(FnSig {
                 ref header,
                 ref decl,
             }, ref body) if header.asyncness.node.is_async() => {
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index be8d82173e4..1e444e8a5b8 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -19,7 +19,7 @@ use std::hash::Hash;
 use syntax::ast;
 use syntax_pos::symbol::{Symbol, sym};
 use syntax_pos::hygiene::ExpnId;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::Span;
 
 /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
 /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
@@ -310,10 +310,6 @@ pub enum DefPathData {
     AnonConst,
     /// An `impl Trait` type node.
     ImplTrait,
-    /// Identifies a piece of crate metadata that is global to a whole crate
-    /// (as opposed to just one item). `GlobalMetaData` components are only
-    /// supposed to show up right below the crate root.
-    GlobalMetaData(Symbol),
 }
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug,
@@ -444,9 +440,6 @@ impl Definitions {
         self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
         self.set_invocation_parent(ExpnId::root(), root_index);
 
-        // Allocate some other `DefIndex`es that always must exist.
-        GlobalMetaDataKind::allocate_def_indices(self);
-
         root_index
     }
 
@@ -553,8 +546,7 @@ impl DefPathData {
             TypeNs(name) |
             ValueNs(name) |
             MacroNs(name) |
-            LifetimeNs(name) |
-            GlobalMetaData(name) => Some(name),
+            LifetimeNs(name) => Some(name),
 
             Impl |
             CrateRoot |
@@ -572,8 +564,7 @@ impl DefPathData {
             TypeNs(name) |
             ValueNs(name) |
             MacroNs(name) |
-            LifetimeNs(name) |
-            GlobalMetaData(name) => {
+            LifetimeNs(name) => {
                 name
             }
             // Note that this does not show up in user print-outs.
@@ -591,78 +582,3 @@ impl DefPathData {
         self.as_symbol().to_string()
     }
 }
-
-// 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 `DefIndex`es in the `DefTable`.
-macro_rules! define_global_metadata_kind {
-    (pub enum GlobalMetaDataKind {
-        $($variant:ident),*
-    }) => (
-        pub enum GlobalMetaDataKind {
-            $($variant),*
-        }
-
-        impl GlobalMetaDataKind {
-            fn allocate_def_indices(definitions: &mut Definitions) {
-                $({
-                    let instance = GlobalMetaDataKind::$variant;
-                    definitions.create_def_with_parent(
-                        CRATE_DEF_INDEX,
-                        ast::DUMMY_NODE_ID,
-                        DefPathData::GlobalMetaData(instance.name()),
-                        ExpnId::root(),
-                        DUMMY_SP
-                    );
-
-                    // Make sure calling `def_index` does not crash.
-                    instance.def_index(&definitions.table);
-                })*
-            }
-
-            pub fn def_index(&self, def_path_table: &DefPathTable) -> DefIndex {
-                let def_key = DefKey {
-                    parent: Some(CRATE_DEF_INDEX),
-                    disambiguated_data: DisambiguatedDefPathData {
-                        data: DefPathData::GlobalMetaData(self.name()),
-                        disambiguator: 0,
-                    }
-                };
-
-                // These `DefKey`s are all right after the root,
-                // so a linear search is fine.
-                let index = def_path_table.index_to_key
-                                          .iter()
-                                          .position(|k| *k == def_key)
-                                          .unwrap();
-
-                DefIndex::from(index)
-            }
-
-            fn name(&self) -> Symbol {
-
-                let string = match *self {
-                    $(
-                        GlobalMetaDataKind::$variant => {
-                            concat!("{{GlobalMetaData::", stringify!($variant), "}}")
-                        }
-                    )*
-                };
-
-                Symbol::intern(string)
-            }
-        }
-    )
-}
-
-define_global_metadata_kind!(pub enum GlobalMetaDataKind {
-    Krate,
-    CrateDeps,
-    DylibDependencyFormats,
-    LangItems,
-    LangItemsMissing,
-    NativeLibraries,
-    SourceMap,
-    Impls,
-    ExportedSymbols
-});
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index acadd77cc36..d7b1676c1d4 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -49,21 +49,21 @@ impl<'hir> Entry<'hir> {
         match self.node {
             Node::Item(ref item) => {
                 match item.kind {
-                    ItemKind::Fn(ref fn_decl, _, _, _) => Some(fn_decl),
+                    ItemKind::Fn(ref sig, _, _) => Some(&sig.decl),
                     _ => None,
                 }
             }
 
             Node::TraitItem(ref item) => {
                 match item.kind {
-                    TraitItemKind::Method(ref method_sig, _) => Some(&method_sig.decl),
+                    TraitItemKind::Method(ref sig, _) => Some(&sig.decl),
                     _ => None
                 }
             }
 
             Node::ImplItem(ref item) => {
                 match item.kind {
-                    ImplItemKind::Method(ref method_sig, _) => Some(&method_sig.decl),
+                    ImplItemKind::Method(ref sig, _) => Some(&sig.decl),
                     _ => None,
                 }
             }
@@ -85,7 +85,7 @@ impl<'hir> Entry<'hir> {
                 match item.kind {
                     ItemKind::Const(_, body) |
                     ItemKind::Static(.., body) |
-                    ItemKind::Fn(_, _, _, body) => Some(body),
+                    ItemKind::Fn(.., body) => Some(body),
                     _ => None,
                 }
             }
@@ -605,7 +605,7 @@ impl<'hir> Map<'hir> {
                 Node::TraitItem(ref trait_item) => Some(&trait_item.generics),
                 Node::Item(ref item) => {
                     match item.kind {
-                        ItemKind::Fn(_, _, ref generics, _) |
+                        ItemKind::Fn(_, ref generics, _) |
                         ItemKind::TyAlias(_, ref generics) |
                         ItemKind::Enum(_, ref generics) |
                         ItemKind::Struct(_, ref generics) |
@@ -702,9 +702,9 @@ impl<'hir> Map<'hir> {
                 ..
             }) => true,
             Node::Item(&Item {
-                kind: ItemKind::Fn(_, header, ..),
+                kind: ItemKind::Fn(ref sig, ..),
                 ..
-            }) => header.constness == Constness::Const,
+            }) => sig.header.constness == Constness::Const,
             _ => false,
         }
     }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 0edc41e6b48..bbd3b40e1be 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -3,9 +3,7 @@
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
 
 pub use self::BlockCheckMode::*;
-pub use self::CaptureClause::*;
 pub use self::FunctionRetTy::*;
-pub use self::Mutability::*;
 pub use self::PrimTy::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
@@ -23,6 +21,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use syntax::source_map::Spanned;
 use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
 use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
+pub use syntax::ast::{Mutability, Constness, Unsafety, Movability, CaptureBy, IsAuto, ImplPolarity};
 use syntax::attr::{InlineAttr, OptimizeAttr};
 use syntax::symbol::{Symbol, kw};
 use syntax::tokenstream::TokenStream;
@@ -1053,30 +1052,6 @@ pub enum PatKind {
     Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
-         RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Mutability {
-    MutMutable,
-    MutImmutable,
-}
-
-impl Mutability {
-    /// Returns `MutMutable` only if both `self` and `other` are mutable.
-    pub fn and(self, other: Self) -> Self {
-        match self {
-            MutMutable => other,
-            MutImmutable => MutImmutable,
-        }
-    }
-
-    pub fn invert(self) -> Self {
-        match self {
-            MutMutable => MutImmutable,
-            MutImmutable => MutMutable,
-        }
-    }
-}
-
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum BinOpKind {
     /// The `+` operator (addition).
@@ -1616,6 +1591,11 @@ pub enum ExprKind {
     /// and the remaining elements are the rest of the arguments.
     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
     /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
+    ///
+    /// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with
+    /// the `hir_id` of the `MethodCall` node itself.
+    ///
+    /// [`type_dependent_def_id`]: ../ty/struct.TypeckTables.html#method.type_dependent_def_id
     MethodCall(P<PathSegment>, Span, HirVec<Expr>),
     /// A tuple (e.g., `(a, b, c, d)`).
     Tup(HirVec<Expr>),
@@ -1647,8 +1627,8 @@ pub enum ExprKind {
     /// The `Span` is the argument block `|...|`.
     ///
     /// This may also be a generator literal or an `async block` as indicated by the
-    /// `Option<GeneratorMovability>`.
-    Closure(CaptureClause, P<FnDecl>, BodyId, Span, Option<GeneratorMovability>),
+    /// `Option<Movability>`.
+    Closure(CaptureBy, P<FnDecl>, BodyId, Span, Option<Movability>),
     /// A block (e.g., `'label: { ... }`).
     Block(P<Block>, Option<Label>),
 
@@ -1698,6 +1678,10 @@ pub enum ExprKind {
 }
 
 /// Represents an optionally `Self`-qualified value/type path or associated extension.
+///
+/// To resolve the path to a `DefId`, call [`qpath_res`].
+///
+/// [`qpath_res`]: ../ty/struct.TypeckTables.html#method.qpath_res
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum QPath {
     /// Path to a definition, optionally "fully-qualified" with a `Self`
@@ -1817,17 +1801,6 @@ pub struct Destination {
     pub target_id: Result<HirId, LoopIdError>,
 }
 
-/// Whether a generator contains self-references, causing it to be `!Unpin`.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
-         RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum GeneratorMovability {
-    /// May contain self-references, `!Unpin`.
-    Static,
-
-    /// Must not contain self-references, `Unpin`.
-    Movable,
-}
-
 /// The yield kind that caused an `ExprKind::Yield`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum YieldSource {
@@ -1846,12 +1819,6 @@ impl fmt::Display for YieldSource {
     }
 }
 
-#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum CaptureClause {
-    CaptureByValue,
-    CaptureByRef,
-}
-
 // N.B., if you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
@@ -1860,9 +1827,10 @@ pub struct MutTy {
     pub mutbl: Mutability,
 }
 
-/// Represents a method's signature in a trait declaration or implementation.
+/// Represents a function's signature in a trait declaration,
+/// trait implementation, or a free function.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct MethodSig {
+pub struct FnSig {
     pub header: FnHeader,
     pub decl: P<FnDecl>,
 }
@@ -1905,7 +1873,7 @@ pub enum TraitItemKind {
     /// An associated constant with an optional value (otherwise `impl`s must contain a value).
     Const(P<Ty>, Option<BodyId>),
     /// A method with an optional body.
-    Method(MethodSig, TraitMethod),
+    Method(FnSig, TraitMethod),
     /// An associated type with (possibly empty) bounds and optional concrete
     /// type.
     Type(GenericBounds, Option<P<Ty>>),
@@ -1939,7 +1907,7 @@ pub enum ImplItemKind {
     /// of the expression.
     Const(P<Ty>, BodyId),
     /// A method implementation with the given signature and body.
-    Method(MethodSig, BodyId),
+    Method(FnSig, BodyId),
     /// An associated type.
     TyAlias(P<Ty>),
     /// An associated `type = impl Trait`.
@@ -2154,13 +2122,6 @@ impl ImplicitSelfKind {
     }
 }
 
-/// Is the trait definition an auto trait?
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum IsAuto {
-    Yes,
-    No
-}
-
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, HashStable,
          Ord, RustcEncodable, RustcDecodable, Debug)]
 pub enum IsAsync {
@@ -2168,19 +2129,6 @@ pub enum IsAsync {
     NotAsync,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
-         RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum Unsafety {
-    Unsafe,
-    Normal,
-}
-
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub enum Constness {
-    Const,
-    NotConst,
-}
-
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Defaultness {
     Default { has_value: bool },
@@ -2207,33 +2155,6 @@ impl Defaultness {
     }
 }
 
-impl fmt::Display for Unsafety {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(match self {
-            Unsafety::Normal => "normal",
-            Unsafety::Unsafe => "unsafe",
-        })
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, HashStable)]
-pub enum ImplPolarity {
-    /// `impl Trait for Type`
-    Positive,
-    /// `impl !Trait for Type`
-    Negative,
-}
-
-impl fmt::Debug for ImplPolarity {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(match self {
-            ImplPolarity::Positive => "positive",
-            ImplPolarity::Negative => "negative",
-        })
-    }
-}
-
-
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum FunctionRetTy {
     /// Return type is not specified.
@@ -2509,7 +2430,7 @@ pub enum ItemKind {
     /// A `const` item.
     Const(P<Ty>, BodyId),
     /// A function declaration.
-    Fn(P<FnDecl>, FnHeader, Generics, BodyId),
+    Fn(FnSig, Generics, BodyId),
     /// A module.
     Mod(Mod),
     /// An external module, e.g. `extern { .. }`.
@@ -2574,7 +2495,7 @@ impl ItemKind {
 
     pub fn generics(&self) -> Option<&Generics> {
         Some(match *self {
-            ItemKind::Fn(_, _, ref generics, _) |
+            ItemKind::Fn(_, ref generics, _) |
             ItemKind::TyAlias(_, ref generics) |
             ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) |
             ItemKind::Enum(_, ref generics) |
@@ -2667,7 +2588,7 @@ pub struct Upvar {
     pub span: Span
 }
 
-pub type CaptureModeMap = NodeMap<CaptureClause>;
+pub type CaptureModeMap = NodeMap<CaptureBy>;
 
  // The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
  // has length > 0 if the trait is found through an chain of imports, starting with the
diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs
index feb0d97822c..97228c8f240 100644
--- a/src/librustc/hir/pat_util.rs
+++ b/src/librustc/hir/pat_util.rs
@@ -169,10 +169,11 @@ impl hir::Pat {
         self.each_binding(|annotation, _, _, _| {
             match annotation {
                 hir::BindingAnnotation::Ref => match result {
-                    None | Some(hir::MutImmutable) => result = Some(hir::MutImmutable),
+                    None | Some(hir::Mutability::Immutable) =>
+                        result = Some(hir::Mutability::Immutable),
                     _ => {}
                 }
-                hir::BindingAnnotation::RefMut => result = Some(hir::MutMutable),
+                hir::BindingAnnotation::RefMut => result = Some(hir::Mutability::Mutable),
                 _ => {}
             }
         });
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 64b355f6ec9..ba618a1da8c 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -295,8 +295,8 @@ impl<'a> State<'a> {
             hir::TyKind::Ptr(ref mt) => {
                 self.s.word("*");
                 match mt.mutbl {
-                    hir::MutMutable => self.word_nbsp("mut"),
-                    hir::MutImmutable => self.word_nbsp("const"),
+                    hir::Mutability::Mutable => self.word_nbsp("mut"),
+                    hir::Mutability::Immutable => self.word_nbsp("const"),
                 }
                 self.print_type(&mt.ty);
             }
@@ -390,7 +390,7 @@ impl<'a> State<'a> {
             }
             hir::ForeignItemKind::Static(ref t, m) => {
                 self.head(visibility_qualified(&item.vis, "static"));
-                if m == hir::MutMutable {
+                if m == hir::Mutability::Mutable {
                     self.word_space("mut");
                 }
                 self.print_ident(item.ident);
@@ -506,7 +506,7 @@ impl<'a> State<'a> {
             }
             hir::ItemKind::Static(ref ty, m, expr) => {
                 self.head(visibility_qualified(&item.vis, "static"));
-                if m == hir::MutMutable {
+                if m == hir::Mutability::Mutable {
                     self.word_space("mut");
                 }
                 self.print_ident(item.ident);
@@ -533,10 +533,10 @@ impl<'a> State<'a> {
                 self.s.word(";");
                 self.end(); // end the outer cbox
             }
-            hir::ItemKind::Fn(ref decl, header, ref param_names, body) => {
+            hir::ItemKind::Fn(ref sig, ref param_names, body) => {
                 self.head("");
-                self.print_fn(decl,
-                              header,
+                self.print_fn(&sig.decl,
+                              sig.header,
                               Some(item.ident.name),
                               param_names,
                               &item.vis,
@@ -564,7 +564,7 @@ impl<'a> State<'a> {
             }
             hir::ItemKind::GlobalAsm(ref ga) => {
                 self.head(visibility_qualified(&item.vis, "global asm"));
-                self.s.word(ga.asm.as_str().to_string());
+                self.s.word(ga.asm.to_string());
                 self.end()
             }
             hir::ItemKind::TyAlias(ref ty, ref generics) => {
@@ -835,7 +835,7 @@ impl<'a> State<'a> {
     }
     pub fn print_method_sig(&mut self,
                             ident: ast::Ident,
-                            m: &hir::MethodSig,
+                            m: &hir::FnSig,
                             generics: &hir::Generics,
                             vis: &hir::Visibility,
                             arg_names: &[ast::Ident],
@@ -1628,11 +1628,11 @@ impl<'a> State<'a> {
                 match binding_mode {
                     hir::BindingAnnotation::Ref => {
                         self.word_nbsp("ref");
-                        self.print_mutability(hir::MutImmutable);
+                        self.print_mutability(hir::Mutability::Immutable);
                     }
                     hir::BindingAnnotation::RefMut => {
                         self.word_nbsp("ref");
-                        self.print_mutability(hir::MutMutable);
+                        self.print_mutability(hir::Mutability::Mutable);
                     }
                     hir::BindingAnnotation::Unannotated => {}
                     hir::BindingAnnotation::Mutable => {
@@ -1734,9 +1734,7 @@ impl<'a> State<'a> {
                     _ => false,
                 };
                 self.s.word("&");
-                if mutbl == hir::MutMutable {
-                    self.s.word("mut ");
-                }
+                self.s.word(mutbl.prefix_str());
                 if is_range_inner {
                     self.popen();
                 }
@@ -1855,7 +1853,7 @@ impl<'a> State<'a> {
         self.commasep(Inconsistent, &decl.inputs, |s, ty| {
             s.ibox(INDENT_UNIT);
             if let Some(arg_name) = arg_names.get(i) {
-                s.s.word(arg_name.as_str().to_string());
+                s.s.word(arg_name.to_string());
                 s.s.word(":");
                 s.s.space();
             } else if let Some(body_id) = body_id {
@@ -1911,10 +1909,10 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) {
+    pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) {
         match capture_clause {
-            hir::CaptureByValue => self.word_space("move"),
-            hir::CaptureByRef => {},
+            hir::CaptureBy::Value => self.word_space("move"),
+            hir::CaptureBy::Ref => {},
         }
     }
 
@@ -2063,8 +2061,8 @@ impl<'a> State<'a> {
 
     pub fn print_mutability(&mut self, mutbl: hir::Mutability) {
         match mutbl {
-            hir::MutMutable => self.word_nbsp("mut"),
-            hir::MutImmutable => {},
+            hir::Mutability::Mutable => self.word_nbsp("mut"),
+            hir::Mutability::Immutable => {},
         }
     }
 
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 957dab39414..a5b131520c2 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -309,11 +309,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
         // position that belongs to it, as opposed to hashing the first
         // position past it.
         let span = self.data();
-
-        if span.hi < span.lo {
-            return std_hash::Hash::hash(&TAG_INVALID_SPAN, hasher);
-        }
-
         let (file_lo, line_lo, col_lo) = match hcx.source_map()
                                                   .byte_pos_to_line_and_col(span.lo) {
             Some(pos) => pos,
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 4fd4e25f641..b3d82e5522c 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -8,9 +8,9 @@ use std::mem;
 
 use syntax::ast;
 use syntax::feature_gate;
-use syntax::parse::token;
-use syntax::symbol::LocalInternedString;
+use syntax::token;
 use syntax::tokenstream;
+use syntax_pos::symbol::SymbolStr;
 use syntax_pos::SourceFile;
 
 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
@@ -18,7 +18,7 @@ use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
 use smallvec::SmallVec;
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher};
 
-impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
+impl<'a> HashStable<StableHashingContext<'a>> for SymbolStr {
     #[inline]
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         let str = self as &str;
@@ -26,13 +26,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
     }
 }
 
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
-    type KeyType = LocalInternedString;
+impl<'a> ToStableHashKey<StableHashingContext<'a>> for SymbolStr {
+    type KeyType = SymbolStr;
 
     #[inline]
     fn to_stable_hash_key(&self,
                           _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
+                          -> SymbolStr {
         self.clone()
     }
 }
@@ -45,12 +45,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
 }
 
 impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::Name {
-    type KeyType = LocalInternedString;
+    type KeyType = SymbolStr;
 
     #[inline]
     fn to_stable_hash_key(&self,
                           _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
+                          -> SymbolStr {
         self.as_str()
     }
 }
@@ -124,7 +124,6 @@ for ::syntax::attr::StabilityLevel {
 
 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion });
 
-
 impl_stable_hash_for!(enum ::syntax::attr::IntType {
     SignedInt(int_ty),
     UnsignedInt(uint_ty)
@@ -136,6 +135,11 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
     Unsuffixed
 });
 
+impl_stable_hash_for!(enum ::syntax::ast::LitFloatType {
+    Suffixed(float_ty),
+    Unsuffixed
+});
+
 impl_stable_hash_for!(struct ::syntax::ast::Lit {
     kind,
     token,
@@ -148,8 +152,7 @@ impl_stable_hash_for!(enum ::syntax::ast::LitKind {
     Byte(value),
     Char(value),
     Int(value, lit_int_type),
-    Float(value, float_ty),
-    FloatUnsuffixed(value),
+    Float(value, lit_float_type),
     Bool(value),
     Err(value)
 });
@@ -165,6 +168,10 @@ impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
 impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, ident });
 impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
 impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
+impl_stable_hash_for!(enum ::syntax::ast::Movability { Static, Movable });
+impl_stable_hash_for!(enum ::syntax::ast::CaptureBy { Value, Ref });
+impl_stable_hash_for!(enum ::syntax::ast::IsAuto { Yes, No });
+impl_stable_hash_for!(enum ::syntax::ast::ImplPolarity { Positive, Negative });
 
 impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
@@ -177,7 +184,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
         let filtered: SmallVec<[&ast::Attribute; 8]> = self
             .iter()
             .filter(|attr| {
-                !attr.is_sugared_doc &&
+                !attr.is_doc_comment() &&
                 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
             })
             .collect();
@@ -207,19 +214,16 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         // Make sure that these have been filtered out.
         debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
-        debug_assert!(!self.is_sugared_doc);
-
-        let ast::Attribute {
-            ref item,
-            id: _,
-            style,
-            is_sugared_doc: _,
-            span,
-        } = *self;
-
-        item.hash_stable(hcx, hasher);
-        style.hash_stable(hcx, hasher);
-        span.hash_stable(hcx, hasher);
+        debug_assert!(!self.is_doc_comment());
+
+        let ast::Attribute { kind, id: _, style, span } = self;
+        if let ast::AttrKind::Normal(item) = kind {
+            item.hash_stable(hcx, hasher);
+            style.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        } else {
+            unreachable!();
+        }
     }
 }
 
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 498600f1e90..38edef50c96 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -897,11 +897,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             } else {
                 r.push(' ');
             }
-            s.push_highlighted(format!(
-                "&{}{}",
-                r,
-                if mutbl == hir::MutMutable { "mut " } else { "" }
-            ));
+            s.push_highlighted(format!("&{}{}", r, mutbl.prefix_str()));
             s.push_normal(ty.to_string());
         }
 
@@ -1234,8 +1230,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
         }
 
+        // In some (most?) cases cause.body_id points to actual body, but in some cases
+        // it's a actual definition. According to the comments (e.g. in
+        // librustc_typeck/check/compare_method.rs:compare_predicate_entailment) the latter
+        // is relied upon by some other code. This might (or might not) need cleanup.
+        let body_owner_def_id = self.tcx.hir().opt_local_def_id(cause.body_id)
+            .unwrap_or_else(|| {
+                self.tcx.hir().body_owner_def_id(hir::BodyId { hir_id: cause.body_id })
+            });
         self.check_and_note_conflicting_crates(diag, terr, span);
-        self.tcx.note_and_explain_type_err(diag, terr, span);
+        self.tcx.note_and_explain_type_err(diag, terr, span, body_owner_def_id);
 
         // It reads better to have the error origin as the final
         // thing.
diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
index f4751e591bf..db5557204e4 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -31,10 +31,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             if let Some(hir_id) = self.tcx().hir().as_local_hir_id(def_id) {
                 let fndecl = match self.tcx().hir().get(hir_id) {
                     Node::Item(&hir::Item {
-                        kind: hir::ItemKind::Fn(ref fndecl, ..),
+                        kind: hir::ItemKind::Fn(ref m, ..),
                         ..
-                    }) => &fndecl,
-                    Node::TraitItem(&hir::TraitItem {
+                    })
+                    | Node::TraitItem(&hir::TraitItem {
                         kind: hir::TraitItemKind::Method(ref m, ..),
                         ..
                     })
diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md
index ea7fffe9dc1..d789fb0de10 100644
--- a/src/librustc/infer/region_constraints/README.md
+++ b/src/librustc/infer/region_constraints/README.md
@@ -1,3 +1,3 @@
 For info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check.html
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 5c871bb6b69..f8a592d22c1 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -7,7 +7,7 @@
 use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo};
 use crate::middle::stability;
 use crate::session::Session;
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use syntax::ast;
 use syntax::edition::Edition;
 use syntax::source_map::Span;
@@ -178,16 +178,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    pub SAFE_EXTERN_STATICS,
-    Deny,
-    "safe access to extern statics was erroneously allowed",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
-        edition: None,
-    };
-}
-
-declare_lint! {
     pub SAFE_PACKED_BORROWS,
     Warn,
     "safe borrows of fields of packed structs were was erroneously allowed",
@@ -199,7 +189,7 @@ declare_lint! {
 
 declare_lint! {
     pub PATTERNS_IN_FNS_WITHOUT_BODY,
-    Warn,
+    Deny,
     "patterns in functions without body were erroneously allowed",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
@@ -208,27 +198,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    pub LEGACY_DIRECTORY_OWNERSHIP,
-    Deny,
-    "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
-     not named `mod.rs`",
-     @future_incompatible = FutureIncompatibleInfo {
-         reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
-         edition: None,
-     };
-}
-
-declare_lint! {
-    pub LEGACY_CONSTRUCTOR_VISIBILITY,
-    Deny,
-    "detects use of struct constructors that would be invisible with new visibility rules",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
-        edition: None,
-    };
-}
-
-declare_lint! {
     pub MISSING_FRAGMENT_SPECIFIER,
     Deny,
     "detects missing fragment specifiers in unused `macro_rules!` patterns",
@@ -239,16 +208,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
-    Deny,
-    "detects parenthesized generic parameters in type and module names",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
-        edition: None,
-    };
-}
-
-declare_lint! {
     pub LATE_BOUND_LIFETIME_ARGUMENTS,
     Warn,
     "detects generic lifetime arguments in path segments with late bound lifetime parameters",
@@ -373,16 +332,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    pub DUPLICATE_MACRO_EXPORTS,
-    Deny,
-    "detects duplicate macro exports",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
-        edition: Some(Edition::Edition2018),
-    };
-}
-
-declare_lint! {
     pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
     Warn,
     "failures in resolving intra-doc link targets"
@@ -459,7 +408,7 @@ declare_lint! {
 pub mod parser {
     declare_lint! {
         pub ILL_FORMED_ATTRIBUTE_INPUT,
-        Warn,
+        Deny,
         "ill-formed attribute inputs that were previously accepted and used in practice",
         @future_incompatible = super::FutureIncompatibleInfo {
             reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
@@ -498,16 +447,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    pub NESTED_IMPL_TRAIT,
-    Warn,
-    "nested occurrence of `impl Trait` type",
-    @future_incompatible = FutureIncompatibleInfo {
-        reference: "issue #59014 <https://github.com/rust-lang/rust/issues/59014>",
-        edition: None,
-    };
-}
-
-declare_lint! {
     pub MUTABLE_BORROW_RESERVATION_CONFLICT,
     Warn,
     "reservation of a two-phased borrow conflicts with other shared borrows",
@@ -556,13 +495,9 @@ declare_lint_pass! {
         INVALID_TYPE_PARAM_DEFAULT,
         CONST_ERR,
         RENAMED_AND_REMOVED_LINTS,
-        SAFE_EXTERN_STATICS,
         SAFE_PACKED_BORROWS,
         PATTERNS_IN_FNS_WITHOUT_BODY,
-        LEGACY_DIRECTORY_OWNERSHIP,
-        LEGACY_CONSTRUCTOR_VISIBILITY,
         MISSING_FRAGMENT_SPECIFIER,
-        PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
         LATE_BOUND_LIFETIME_ARGUMENTS,
         ORDER_DEPENDENT_TRAIT_OBJECTS,
         DEPRECATED,
@@ -578,7 +513,6 @@ declare_lint_pass! {
         ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
         UNSTABLE_NAME_COLLISIONS,
         IRREFUTABLE_LET_PATTERNS,
-        DUPLICATE_MACRO_EXPORTS,
         INTRA_DOC_LINK_RESOLUTION_FAILURE,
         MISSING_DOC_CODE_EXAMPLES,
         PRIVATE_DOC_TESTS,
@@ -590,7 +524,6 @@ declare_lint_pass! {
         parser::META_VARIABLE_MISUSE,
         DEPRECATED_IN_FUTURE,
         AMBIGUOUS_ASSOCIATED_ITEMS,
-        NESTED_IMPL_TRAIT,
         MUTABLE_BORROW_RESERVATION_CONFLICT,
         INDIRECT_STRUCTURAL_MATCH,
         SOFT_UNSTABLE,
@@ -604,13 +537,11 @@ pub enum BuiltinLintDiagnostics {
     Normal,
     BareTraitObject(Span, /* is_global */ bool),
     AbsPathWithModule(Span),
-    DuplicatedMacroExports(ast::Ident, Span, Span),
     ProcMacroDeriveResolutionFallback(Span),
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
     ElidedLifetimesInPaths(usize, Span, bool, Span, String),
     UnknownCrateTypes(Span, String, String),
     UnusedImports(String, Vec<(Span, String)>),
-    NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
     RedundantImport(Vec<(Span, bool)>, ast::Ident),
     DeprecatedMacro(Option<Symbol>, Span),
 }
@@ -651,7 +582,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion(
     };
     db.span_suggestion(
         replace_span,
-        &format!("indicate the anonymous lifetime{}", pluralise!(n)),
+        &format!("indicate the anonymous lifetime{}", pluralize!(n)),
         suggestion,
         Applicability::MachineApplicable
     );
@@ -687,10 +618,6 @@ impl BuiltinLintDiagnostics {
                 };
                 db.span_suggestion(span, "use `crate`", sugg, app);
             }
-            BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => {
-                db.span_label(later_span, format!("`{}` already exported", ident));
-                db.span_note(earlier_span, "previous macro export is now shadowed");
-            }
             BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
                 db.span_label(span, "names from parent modules are not \
                                      accessible without an explicit import");
@@ -723,12 +650,6 @@ impl BuiltinLintDiagnostics {
                     );
                 }
             }
-            BuiltinLintDiagnostics::NestedImplTrait {
-                outer_impl_trait_span, inner_impl_trait_span
-            } => {
-                db.span_label(outer_impl_trait_span, "outer `impl Trait`");
-                db.span_label(inner_impl_trait_span, "nested `impl Trait` here");
-            }
             BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
                 for (span, is_imported) in spans {
                     let introduced = if is_imported { "imported" } else { "defined" };
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index eef1cee8db3..721baad2563 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -699,6 +699,9 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
 
     /// Check if a `DefId`'s path matches the given absolute type path usage.
     ///
+    /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`;
+    /// inherent `impl` blocks are matched with the name of the type.
+    ///
     /// # Examples
     ///
     /// ```rust,ignore (no context or def id available)
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index a08722e9402..1c5f86f4801 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -131,7 +131,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
                     }
                 }
             }
-            TyKind::Rptr(_, MutTy { ty: inner_ty, mutbl: Mutability::MutImmutable }) => {
+            TyKind::Rptr(_, MutTy { ty: inner_ty, mutbl: Mutability::Immutable }) => {
                 if let Some(impl_did) = cx.tcx.impl_of_method(ty.hir_id.owner_def_id()) {
                     if cx.tcx.impl_trait_ref(impl_did).is_some() {
                         return;
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index cbf336fdbe2..3510fe4d123 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -67,7 +67,7 @@ use crate::ty::adjustment;
 use crate::ty::{self, DefIdTree, Ty, TyCtxt};
 use crate::ty::fold::TypeFoldable;
 
-use crate::hir::{MutImmutable, MutMutable, PatKind};
+use crate::hir::{Mutability, PatKind};
 use crate::hir::pat_util::EnumerateAndAdjustIterator;
 use crate::hir;
 use syntax::ast::{self, Name};
@@ -226,8 +226,8 @@ pub type McResult<T> = Result<T, ()>;
 impl MutabilityCategory {
     pub fn from_mutbl(m: hir::Mutability) -> MutabilityCategory {
         let ret = match m {
-            MutImmutable => McImmutable,
-            MutMutable => McDeclared
+            Mutability::Immutable => McImmutable,
+            Mutability::Mutable => McDeclared
         };
         debug!("MutabilityCategory::{}({:?}) => {:?}",
                "from_mutbl", m, ret);
@@ -274,7 +274,7 @@ impl MutabilityCategory {
                     let bm = *tables.pat_binding_modes()
                                     .get(p.hir_id)
                                     .expect("missing binding mode");
-                    if bm == ty::BindByValue(hir::MutMutable) {
+                    if bm == ty::BindByValue(Mutability::Mutable) {
                         McDeclared
                     } else {
                         McImmutable
@@ -663,8 +663,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                     span,
                     cat,
                     mutbl: match self.tcx.static_mutability(def_id).unwrap() {
-                        hir::MutImmutable => McImmutable,
-                        hir::MutMutable => McDeclared,
+                        Mutability::Immutable => McImmutable,
+                        Mutability::Mutable => McDeclared,
                     },
                     ty:expr_ty,
                     note: NoteNone
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 8be64bf64b5..f77f5a72e60 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -33,7 +33,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item, attrs: CodegenFnAt
     }
 
     match item.kind {
-        hir::ItemKind::Fn(_, header, ..) if header.is_const() => {
+        hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => {
             return true;
         }
         hir::ItemKind::Impl(..) |
@@ -225,8 +225,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
             // If we are building an executable, only explicitly extern
             // types need to be exported.
             if let Node::Item(item) = *node {
-                let reachable = if let hir::ItemKind::Fn(_, header, ..) = item.kind {
-                    header.abi != Abi::Rust
+                let reachable = if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
+                    sig.header.abi != Abi::Rust
                 } else {
                     false
                 };
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index a122d84a5aa..f37d9b2827b 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -17,7 +17,7 @@ use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use crate::rustc::lint;
 use crate::session::Session;
 use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -460,8 +460,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         match item.kind {
-            hir::ItemKind::Fn(ref decl, _, ref generics, _) => {
-                self.visit_early_late(None, decl, generics, |this| {
+            hir::ItemKind::Fn(ref sig, ref generics, _) => {
+                self.visit_early_late(None, &sig.decl, generics, |this| {
                     intravisit::walk_item(this, item);
                 });
             }
@@ -1524,8 +1524,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             {
                 match parent {
                     Node::Item(item) => {
-                        if let hir::ItemKind::Fn(decl, _, _, _) = &item.kind {
-                            find_arg_use_span(&decl.inputs);
+                        if let hir::ItemKind::Fn(sig, _, _) = &item.kind {
+                            find_arg_use_span(&sig.decl.inputs);
                         }
                     },
                     Node::ImplItem(impl_item) => {
@@ -3044,7 +3044,7 @@ pub fn report_missing_lifetime_specifiers(
         span,
         E0106,
         "missing lifetime specifier{}",
-        pluralise!(count)
+        pluralize!(count)
     )
 }
 
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 93d0627ac6e..fabb0a59da8 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -22,8 +22,9 @@ use syntax::attr::{self, Stability, Deprecation, RustcDeprecation};
 use crate::ty::{self, TyCtxt};
 use crate::util::nodemap::{FxHashSet, FxHashMap};
 
-use std::mem::replace;
 use std::cmp::Ordering;
+use std::mem::replace;
+use std::num::NonZeroU32;
 
 #[derive(PartialEq, Clone, Copy, Debug)]
 pub enum StabilityLevel {
@@ -441,7 +442,7 @@ impl<'tcx> Index<'tcx> {
                 let stability = tcx.intern_stability(Stability {
                     level: attr::StabilityLevel::Unstable {
                         reason: Some(Symbol::intern(reason)),
-                        issue: 27812,
+                        issue: NonZeroU32::new(27812),
                         is_soft: false,
                     },
                     feature: sym::rustc_private,
@@ -488,7 +489,7 @@ pub fn report_unstable(
     sess: &Session,
     feature: Symbol,
     reason: Option<Symbol>,
-    issue: u32,
+    issue: Option<NonZeroU32>,
     is_soft: bool,
     span: Span,
     soft_handler: impl FnOnce(&'static lint::Lint, Span, &str),
@@ -520,7 +521,7 @@ pub fn report_unstable(
             soft_handler(lint::builtin::SOFT_UNSTABLE, span, &msg)
         } else {
             emit_feature_err(
-                &sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg
+                &sess.parse_sess, feature, span, GateIssue::Library(issue), &msg
             );
         }
     }
@@ -637,7 +638,7 @@ pub enum EvalResult {
     Deny {
         feature: Symbol,
         reason: Option<Symbol>,
-        issue: u32,
+        issue: Option<NonZeroU32>,
         is_soft: bool,
     },
     /// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
@@ -758,7 +759,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 // the `-Z force-unstable-if-unmarked` flag present (we're
                 // compiling a compiler crate), then let this missing feature
                 // annotation slide.
-                if feature == sym::rustc_private && issue == 27812 {
+                if feature == sym::rustc_private && issue == NonZeroU32::new(27812) {
                     if self.sess.opts.debugging_opts.force_unstable_if_unmarked {
                         return EvalResult::Allow;
                     }
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index ac16b8b884c..7b29fb26e74 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -439,7 +439,7 @@ impl<'tcx, Tag> Scalar<Tag> {
         Ok(b as u64)
     }
 
-    pub fn to_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> {
+    pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> {
         let b = self.to_bits(cx.data_layout().pointer_size)?;
         Ok(b as u64)
     }
@@ -465,7 +465,7 @@ impl<'tcx, Tag> Scalar<Tag> {
         Ok(b as i64)
     }
 
-    pub fn to_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> {
+    pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> {
         let sz = cx.data_layout().pointer_size;
         let b = self.to_bits(sz)?;
         let b = sign_extend(b, sz) as i128;
@@ -592,8 +592,8 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
     }
 
     #[inline(always)]
-    pub fn to_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
-        self.not_undef()?.to_usize(cx)
+    pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
+        self.not_undef()?.to_machine_usize(cx)
     }
 
     #[inline(always)]
@@ -612,8 +612,8 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
     }
 
     #[inline(always)]
-    pub fn to_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> {
-        self.not_undef()?.to_isize(cx)
+    pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> {
+        self.not_undef()?.to_machine_isize(cx)
     }
 }
 
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index f7e0d0131de..fd2063e2da9 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -491,8 +491,8 @@ pub enum Mutability {
 impl From<Mutability> for hir::Mutability {
     fn from(m: Mutability) -> Self {
         match m {
-            Mutability::Mut => hir::MutMutable,
-            Mutability::Not => hir::MutImmutable,
+            Mutability::Mut => hir::Mutability::Mutable,
+            Mutability::Not => hir::Mutability::Immutable,
         }
     }
 }
@@ -1665,6 +1665,15 @@ pub enum FakeReadCause {
     /// Therefore, we insert a "fake read" here to ensure that we get
     /// appropriate errors.
     ForLet,
+
+    /// If we have an index expression like
+    ///
+    /// (*x)[1][{ x = y; 4}]
+    ///
+    /// then the first bounds check is invalidated when we evaluate the second
+    /// index expression. Thus we create a fake borrow of `x` across the second
+    /// indexer, which will cause a borrow check error.
+    ForIndex,
 }
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
@@ -1764,9 +1773,8 @@ impl_stable_hash_for!(struct Static<'tcx> {
     def_id
 });
 
-#[derive(
-    Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable,
-)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub enum ProjectionElem<V, T> {
     Deref,
     Field(Field, T),
@@ -2161,7 +2169,7 @@ pub enum AggregateKind<'tcx> {
     Adt(&'tcx AdtDef, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>),
 
     Closure(DefId, SubstsRef<'tcx>),
-    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
@@ -2701,7 +2709,6 @@ pub enum UnsafetyViolationKind {
     General,
     /// Permitted both in `const fn`s and regular `fn`s.
     GeneralAndConstFn,
-    ExternStatic(hir::HirId),
     BorrowPacked(hir::HirId),
 }
 
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index 58f99667cb3..a54635c3d51 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -486,7 +486,7 @@ impl CodegenUnitNameBuilder<'tcx> {
         if self.tcx.sess.opts.debugging_opts.human_readable_cgu_names {
             cgu_name
         } else {
-            let cgu_name = &cgu_name.as_str()[..];
+            let cgu_name = &cgu_name.as_str();
             Symbol::intern(&CodegenUnit::mangle_name(cgu_name))
         }
     }
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index e87aabf9a05..c65f2b04786 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -276,17 +276,17 @@ impl<'tcx> BinOp {
 impl BorrowKind {
     pub fn to_mutbl_lossy(self) -> hir::Mutability {
         match self {
-            BorrowKind::Mut { .. } => hir::MutMutable,
-            BorrowKind::Shared => hir::MutImmutable,
+            BorrowKind::Mut { .. } => hir::Mutability::Mutable,
+            BorrowKind::Shared => hir::Mutability::Immutable,
 
             // We have no type corresponding to a unique imm borrow, so
             // use `&mut`. It gives all the capabilities of an `&uniq`
             // and hence is a safe "over approximation".
-            BorrowKind::Unique => hir::MutMutable,
+            BorrowKind::Unique => hir::Mutability::Mutable,
 
             // We have no type corresponding to a shallow borrow, so use
             // `&` as an approximation.
-            BorrowKind::Shallow => hir::MutImmutable,
+            BorrowKind::Shallow => hir::Mutability::Immutable,
         }
     }
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 86ed2419e04..bd7b77b0abb 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -93,7 +93,7 @@ rustc_queries! {
         /// Maps DefId's that have an associated `mir::Body` to the result
         /// of the MIR qualify_consts pass. The actual meaning of
         /// the value isn't known except to the pass itself.
-        query mir_const_qualif(key: DefId) -> (u8, &'tcx BitSet<mir::Local>) {
+        query mir_const_qualif(key: DefId) -> u8 {
             desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
             cache_on_disk_if { key.is_local() }
         }
@@ -228,12 +228,6 @@ rustc_queries! {
             cycle_delay_bug
         }
 
-        query trivial_dropck_outlives(ty: Ty<'tcx>) -> bool {
-            anon
-            no_force
-            desc { "checking if `{:?}` has trivial dropck", ty }
-        }
-
         query adt_dtorck_constraint(
             _: DefId
         ) -> Result<DtorckConstraint<'tcx>, NoSolution> {}
diff --git a/src/librustc/session/code_stats.rs b/src/librustc/session/code_stats.rs
index 0f535249b5e..5baf0c5948f 100644
--- a/src/librustc/session/code_stats.rs
+++ b/src/librustc/session/code_stats.rs
@@ -1,6 +1,7 @@
 use rustc_target::abi::{Align, Size};
 use rustc_data_structures::fx::{FxHashSet};
 use std::cmp::{self, Ordering};
+use rustc_data_structures::sync::Lock;
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct VariantInfo {
@@ -44,13 +45,13 @@ pub struct TypeSizeInfo {
     pub variants: Vec<VariantInfo>,
 }
 
-#[derive(PartialEq, Eq, Debug, Default)]
+#[derive(Default)]
 pub struct CodeStats {
-    type_sizes: FxHashSet<TypeSizeInfo>,
+    type_sizes: Lock<FxHashSet<TypeSizeInfo>>,
 }
 
 impl CodeStats {
-    pub fn record_type_size<S: ToString>(&mut self,
+    pub fn record_type_size<S: ToString>(&self,
                                          kind: DataTypeKind,
                                          type_desc: S,
                                          align: Align,
@@ -73,11 +74,12 @@ impl CodeStats {
             opt_discr_size: opt_discr_size.map(|s| s.bytes()),
             variants,
         };
-        self.type_sizes.insert(info);
+        self.type_sizes.borrow_mut().insert(info);
     }
 
     pub fn print_type_sizes(&self) {
-        let mut sorted: Vec<_> = self.type_sizes.iter().collect();
+        let type_sizes = self.type_sizes.borrow();
+        let mut sorted: Vec<_> = type_sizes.iter().collect();
 
         // Primary sort: large-to-small.
         // Secondary sort: description (dictionary order)
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2bcddeaf196..4a14960aa69 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1,10 +1,13 @@
 //! Contains infrastructure for configuring the compiler, including parsing
 //! command-line options.
 
+// ignore-tidy-filelength
+
 use crate::lint;
 use crate::middle::cstore;
 use crate::session::{early_error, early_warn, Session};
 use crate::session::search_paths::SearchPath;
+use crate::hir::map as hir_map;
 
 use rustc_data_structures::fx::FxHashSet;
 
@@ -440,6 +443,8 @@ top_level_options!(
         // `true` if we're emitting JSON blobs about each artifact produced
         // by the compiler.
         json_artifact_notifications: bool [TRACKED],
+
+        pretty: Option<(PpMode, Option<UserIdentifiedItem>)> [UNTRACKED],
     }
 );
 
@@ -621,6 +626,7 @@ impl Default for Options {
             remap_path_prefix: Vec::new(),
             edition: DEFAULT_EDITION,
             json_artifact_notifications: false,
+            pretty: None,
         }
     }
 }
@@ -1800,7 +1806,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "",
             "extern",
             "Specify where an external rust library is located",
-            "NAME=PATH",
+            "NAME[=PATH]",
         ),
         opt::multi_s(
             "",
@@ -2164,7 +2170,6 @@ fn collect_print_requests(
     cg: &mut CodegenOptions,
     dopts: &mut DebuggingOptions,
     matches: &getopts::Matches,
-    is_unstable_enabled: bool,
     error_format: ErrorOutputType,
 ) -> Vec<PrintRequest> {
     let mut prints = Vec::<PrintRequest>::new();
@@ -2206,7 +2211,7 @@ fn collect_print_requests(
         "tls-models" => PrintRequest::TlsModels,
         "native-static-libs" => PrintRequest::NativeStaticLibs,
         "target-spec-json" => {
-            if is_unstable_enabled {
+            if dopts.unstable_options {
                 PrintRequest::TargetSpec
             } else {
                 early_error(
@@ -2370,7 +2375,6 @@ fn parse_externs(
     matches: &getopts::Matches,
     debugging_opts: &DebuggingOptions,
     error_format: ErrorOutputType,
-    is_unstable_enabled: bool,
 ) -> Externs {
     if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
         early_error(
@@ -2392,13 +2396,6 @@ fn parse_externs(
         let name = parts.next().unwrap_or_else(||
             early_error(error_format, "--extern value must not be empty"));
         let location = parts.next().map(|s| s.to_string());
-        if location.is_none() && !is_unstable_enabled {
-            early_error(
-                error_format,
-                "the `-Z unstable-options` flag must also be passed to \
-                 enable `--extern crate_name` without `=path`",
-            );
-        };
 
         let entry = externs
             .entry(name.to_owned())
@@ -2483,12 +2480,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
-    let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
     let prints = collect_print_requests(
         &mut cg,
         &mut debugging_opts,
         matches,
-        is_unstable_enabled,
         error_format,
     );
 
@@ -2521,12 +2516,14 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
-    let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled);
+    let externs = parse_externs(matches, &debugging_opts, error_format);
 
     let crate_name = matches.opt_str("crate-name");
 
     let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
 
+    let pretty = parse_pretty(matches, &debugging_opts, error_format);
+
     Options {
         crate_types,
         optimize: opt_level,
@@ -2557,6 +2554,73 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         remap_path_prefix,
         edition,
         json_artifact_notifications,
+        pretty,
+    }
+}
+
+fn parse_pretty(
+    matches: &getopts::Matches,
+    debugging_opts: &DebuggingOptions,
+    efmt: ErrorOutputType,
+) -> Option<(PpMode, Option<UserIdentifiedItem>)> {
+    let pretty = if debugging_opts.unstable_options {
+        matches.opt_default("pretty", "normal").map(|a| {
+            // stable pretty-print variants only
+            parse_pretty_inner(efmt, &a, false)
+        })
+    } else {
+        None
+    };
+
+    return if pretty.is_none() {
+        debugging_opts.unpretty.as_ref().map(|a| {
+            // extended with unstable pretty-print variants
+            parse_pretty_inner(efmt, &a, true)
+        })
+    } else {
+        pretty
+    };
+
+    fn parse_pretty_inner(
+        efmt: ErrorOutputType,
+        name: &str,
+        extended: bool,
+    ) -> (PpMode, Option<UserIdentifiedItem>) {
+        use PpMode::*;
+        use PpSourceMode::*;
+        let mut split = name.splitn(2, '=');
+        let first = split.next().unwrap();
+        let opt_second = split.next();
+        let first = match (first, extended) {
+            ("normal", _) => PpmSource(PpmNormal),
+            ("identified", _) => PpmSource(PpmIdentified),
+            ("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
+            ("expanded", _) => PpmSource(PpmExpanded),
+            ("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
+            ("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
+            ("hir", true) => PpmHir(PpmNormal),
+            ("hir,identified", true) => PpmHir(PpmIdentified),
+            ("hir,typed", true) => PpmHir(PpmTyped),
+            ("hir-tree", true) => PpmHirTree(PpmNormal),
+            ("mir", true) => PpmMir,
+            ("mir-cfg", true) => PpmMirCFG,
+            _ => {
+                if extended {
+                    early_error(efmt, &format!("argument to `unpretty` must be one of `normal`, \
+                                        `expanded`, `identified`, `expanded,identified`, \
+                                        `expanded,hygiene`, `everybody_loops`, \
+                                        `hir`, `hir,identified`, `hir,typed`, `hir-tree`, \
+                                        `mir` or `mir-cfg`; got {}",
+                                        name));
+                } else {
+                    early_error(efmt, &format!("argument to `pretty` must be one of `normal`, \
+                                        `expanded`, `identified`, or `expanded,identified`; got {}",
+                                        name));
+                }
+            }
+        };
+        let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
+        (first, opt_second)
     }
 }
 
@@ -2667,6 +2731,151 @@ impl fmt::Display for CrateType {
     }
 }
 
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum PpSourceMode {
+    PpmNormal,
+    PpmEveryBodyLoops,
+    PpmExpanded,
+    PpmIdentified,
+    PpmExpandedIdentified,
+    PpmExpandedHygiene,
+    PpmTyped,
+}
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum PpMode {
+    PpmSource(PpSourceMode),
+    PpmHir(PpSourceMode),
+    PpmHirTree(PpSourceMode),
+    PpmMir,
+    PpmMirCFG,
+}
+
+impl PpMode {
+    pub fn needs_ast_map(&self, opt_uii: &Option<UserIdentifiedItem>) -> bool {
+        use PpMode::*;
+        use PpSourceMode::*;
+        match *self {
+            PpmSource(PpmNormal) |
+            PpmSource(PpmEveryBodyLoops) |
+            PpmSource(PpmIdentified) => opt_uii.is_some(),
+
+            PpmSource(PpmExpanded) |
+            PpmSource(PpmExpandedIdentified) |
+            PpmSource(PpmExpandedHygiene) |
+            PpmHir(_) |
+            PpmHirTree(_) |
+            PpmMir |
+            PpmMirCFG => true,
+            PpmSource(PpmTyped) => panic!("invalid state"),
+        }
+    }
+
+    pub fn needs_analysis(&self) -> bool {
+        use PpMode::*;
+        match *self {
+            PpmMir | PpmMirCFG => true,
+            _ => false,
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub enum UserIdentifiedItem {
+    ItemViaNode(ast::NodeId),
+    ItemViaPath(Vec<String>),
+}
+
+impl FromStr for UserIdentifiedItem {
+    type Err = ();
+    fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
+        use UserIdentifiedItem::*;
+        Ok(s.parse()
+            .map(ast::NodeId::from_u32)
+            .map(ItemViaNode)
+            .unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect())))
+    }
+}
+
+pub enum NodesMatchingUII<'a> {
+    NodesMatchingDirect(std::option::IntoIter<ast::NodeId>),
+    NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
+}
+
+impl<'a> Iterator for NodesMatchingUII<'a> {
+    type Item = ast::NodeId;
+
+    fn next(&mut self) -> Option<ast::NodeId> {
+        use NodesMatchingUII::*;
+        match self {
+            &mut NodesMatchingDirect(ref mut iter) => iter.next(),
+            &mut NodesMatchingSuffix(ref mut iter) => iter.next(),
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        use NodesMatchingUII::*;
+        match self {
+            &NodesMatchingDirect(ref iter) => iter.size_hint(),
+            &NodesMatchingSuffix(ref iter) => iter.size_hint(),
+        }
+    }
+}
+
+impl UserIdentifiedItem {
+    pub fn reconstructed_input(&self) -> String {
+        use UserIdentifiedItem::*;
+        match *self {
+            ItemViaNode(node_id) => node_id.to_string(),
+            ItemViaPath(ref parts) => parts.join("::"),
+        }
+    }
+
+    pub fn all_matching_node_ids<'a, 'hir>(&'a self,
+                                       map: &'a hir_map::Map<'hir>)
+                                       -> NodesMatchingUII<'a> {
+        use UserIdentifiedItem::*;
+        use NodesMatchingUII::*;
+        match *self {
+            ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
+            ItemViaPath(ref parts) => {
+                NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts)))
+            }
+        }
+    }
+
+    pub fn to_one_node_id(self,
+                      user_option: &str,
+                      sess: &Session,
+                      map: &hir_map::Map<'_>)
+                      -> ast::NodeId {
+        let fail_because = |is_wrong_because| -> ast::NodeId {
+            let message = format!("{} needs NodeId (int) or unique path suffix (b::c::d); got \
+                                   {}, which {}",
+                                  user_option,
+                                  self.reconstructed_input(),
+                                  is_wrong_because);
+            sess.fatal(&message)
+        };
+
+        let mut saw_node = ast::DUMMY_NODE_ID;
+        let mut seen = 0;
+        for node in self.all_matching_node_ids(map) {
+            saw_node = node;
+            seen += 1;
+            if seen > 1 {
+                fail_because("does not resolve uniquely");
+            }
+        }
+        if seen == 0 {
+            fail_because("does not resolve to any item");
+        }
+
+        assert!(seen == 1);
+        return saw_node;
+    }
+}
+
 /// Command-line arguments passed to the compiler have to be incorporated with
 /// the dependency tracking system for incremental compilation. This module
 /// provides some utilities to make this more convenient.
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 13b76b79b3d..9792223ea15 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -21,13 +21,12 @@ use errors::{DiagnosticBuilder, DiagnosticId, Applicability};
 use errors::emitter::{Emitter, EmitterWriter};
 use errors::emitter::HumanReadableErrorType;
 use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
-use syntax::ast::{self, NodeId};
 use syntax::edition::Edition;
 use syntax::expand::allocator::AllocatorKind;
 use syntax::feature_gate::{self, AttributeType};
 use syntax::json::JsonEmitter;
 use syntax::source_map;
-use syntax::sess::ParseSess;
+use syntax::sess::{ParseSess, ProcessCfgMod};
 use syntax::symbol::Symbol;
 use syntax_pos::{MultiSpan, Span};
 use crate::util::profiling::{SelfProfiler, SelfProfilerRef};
@@ -38,10 +37,11 @@ use rustc_data_structures::jobserver;
 use ::jobserver::Client;
 
 use std;
-use std::cell::{self, Cell, RefCell};
+use std::cell::{self, RefCell};
 use std::env;
 use std::fmt;
 use std::io::Write;
+use std::num::NonZeroU32;
 use std::path::PathBuf;
 use std::time::Duration;
 use std::sync::Arc;
@@ -125,9 +125,7 @@ pub struct Session {
     pub perf_stats: PerfStats,
 
     /// Data about code being compiled, gathered during compilation.
-    pub code_stats: Lock<CodeStats>,
-
-    next_node_id: OneThread<Cell<ast::NodeId>>,
+    pub code_stats: CodeStats,
 
     /// If `-zfuel=crate=n` is specified, `Some(crate)`.
     optimization_fuel_crate: Option<String>,
@@ -148,9 +146,6 @@ pub struct Session {
     /// Metadata about the allocators for the current crate being compiled.
     pub has_global_allocator: Once<bool>,
 
-    /// Metadata about the panic handlers for the current crate being compiled.
-    pub has_panic_handler: Once<bool>,
-
     /// Cap lint level specified by a driver specifically.
     pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 
@@ -189,7 +184,7 @@ enum DiagnosticBuilderMethod {
 pub enum DiagnosticMessageId {
     ErrorId(u16), // EXXXX error code as integer
     LintId(lint::LintId),
-    StabilityId(u32), // issue number
+    StabilityId(Option<NonZeroU32>), // issue number
 }
 
 impl From<&'static lint::Lint> for DiagnosticMessageId {
@@ -358,21 +353,6 @@ impl Session {
         self.diagnostic().span_note_without_error(sp, msg)
     }
 
-    pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
-        let id = self.next_node_id.get();
-
-        match id.as_usize().checked_add(count) {
-            Some(next) => {
-                self.next_node_id.set(ast::NodeId::from_usize(next));
-            }
-            None => bug!("input too large; ran out of node-IDs!"),
-        }
-
-        id
-    }
-    pub fn next_node_id(&self) -> NodeId {
-        self.reserve_node_ids(1)
-    }
     pub fn diagnostic(&self) -> &errors::Handler {
         &self.parse_sess.span_diagnostic
     }
@@ -955,6 +935,7 @@ pub fn build_session(
     sopts: config::Options,
     local_crate_source_file: Option<PathBuf>,
     registry: errors::registry::Registry,
+    process_cfg_mod: ProcessCfgMod,
 ) -> Session {
     let file_path_mapping = sopts.file_path_mapping();
 
@@ -965,6 +946,7 @@ pub fn build_session(
         Lrc::new(source_map::SourceMap::new(file_path_mapping)),
         DiagnosticOutput::Default,
         Default::default(),
+        process_cfg_mod,
     )
 }
 
@@ -1043,6 +1025,7 @@ pub fn build_session_with_source_map(
     source_map: Lrc<source_map::SourceMap>,
     diagnostics_output: DiagnosticOutput,
     lint_caps: FxHashMap<lint::LintId, lint::Level>,
+    process_cfg_mod: ProcessCfgMod,
 ) -> Session {
     // FIXME: This is not general enough to make the warning lint completely override
     // normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -1083,7 +1066,14 @@ pub fn build_session_with_source_map(
         },
     );
 
-    build_session_(sopts, local_crate_source_file, diagnostic_handler, source_map, lint_caps)
+    build_session_(
+        sopts,
+        local_crate_source_file,
+        diagnostic_handler,
+        source_map,
+        lint_caps,
+        process_cfg_mod,
+    )
 }
 
 fn build_session_(
@@ -1092,6 +1082,7 @@ fn build_session_(
     span_diagnostic: errors::Handler,
     source_map: Lrc<source_map::SourceMap>,
     driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
+    process_cfg_mod: ProcessCfgMod,
 ) -> Session {
     let self_profiler =
         if let SwitchWithOptPath::Enabled(ref d) = sopts.debugging_opts.self_profile {
@@ -1130,6 +1121,7 @@ fn build_session_(
     let parse_sess = ParseSess::with_span_handler(
         span_diagnostic,
         source_map,
+        process_cfg_mod,
     );
     let sysroot = match &sopts.maybe_sysroot {
         Some(sysroot) => sysroot.clone(),
@@ -1190,7 +1182,6 @@ fn build_session_(
         recursion_limit: Once::new(),
         type_length_limit: Once::new(),
         const_eval_stack_frame_limit: 100,
-        next_node_id: OneThread::new(Cell::new(NodeId::from_u32(1))),
         allocator_kind: Once::new(),
         injected_panic_runtime: Once::new(),
         imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
@@ -1211,7 +1202,6 @@ fn build_session_(
         print_fuel,
         jobserver: jobserver::client(),
         has_global_allocator: Once::new(),
-        has_panic_handler: Once::new(),
         driver_lint_caps,
         trait_methods_not_found: Lock::new(Default::default()),
         confused_type_with_std_module: Lock::new(Default::default()),
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 49a4d17d88d..1645f94535f 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -367,118 +367,52 @@ fn orphan_check_trait_ref<'tcx>(
              trait_ref);
     }
 
-    if tcx.features().re_rebalance_coherence {
-        // Given impl<P1..=Pn> Trait<T1..=Tn> for T0, an impl is valid only
-        // if at least one of the following is true:
-        //
-        // - Trait is a local trait
-        // (already checked in orphan_check prior to calling this function)
-        // - All of
-        //     - At least one of the types T0..=Tn must be a local type.
-        //      Let Ti be the first such type.
-        //     - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
-        //
-        fn uncover_fundamental_ty<'tcx>(
-            tcx: TyCtxt<'tcx>,
-            ty: Ty<'tcx>,
-            in_crate: InCrate,
-        ) -> Vec<Ty<'tcx>> {
-            if fundamental_ty(ty) && ty_is_non_local(tcx, ty, in_crate).is_some() {
-                ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).collect()
-            } else {
-                vec![ty]
-            }
+    // Given impl<P1..=Pn> Trait<T1..=Tn> for T0, an impl is valid only
+    // if at least one of the following is true:
+    //
+    // - Trait is a local trait
+    // (already checked in orphan_check prior to calling this function)
+    // - All of
+    //     - At least one of the types T0..=Tn must be a local type.
+    //      Let Ti be the first such type.
+    //     - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
+    //
+    fn uncover_fundamental_ty<'tcx>(
+        tcx: TyCtxt<'tcx>,
+        ty: Ty<'tcx>,
+        in_crate: InCrate,
+    ) -> Vec<Ty<'tcx>> {
+        if fundamental_ty(ty) && ty_is_non_local(tcx, ty, in_crate).is_some() {
+            ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).collect()
+        } else {
+            vec![ty]
         }
+    }
 
-        let mut non_local_spans = vec![];
-        for (i, input_ty) in trait_ref
-            .input_types()
-            .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
-            .enumerate()
-        {
-            debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
-            let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
-            if non_local_tys.is_none() {
-                debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
-                return Ok(());
-            } else if let ty::Param(_) = input_ty.kind {
-                debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
-                return Err(OrphanCheckErr::UncoveredTy(input_ty))
-            }
-            if let Some(non_local_tys) = non_local_tys {
-                for input_ty in non_local_tys {
-                    non_local_spans.push((input_ty, i == 0));
-                }
-            }
+    let mut non_local_spans = vec![];
+    for (i, input_ty) in trait_ref
+        .input_types()
+        .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
+        .enumerate()
+    {
+        debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
+        let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
+        if non_local_tys.is_none() {
+            debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
+            return Ok(());
+        } else if let ty::Param(_) = input_ty.kind {
+            debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
+            return Err(OrphanCheckErr::UncoveredTy(input_ty))
         }
-        // If we exit above loop, never found a local type.
-        debug!("orphan_check_trait_ref: no local type");
-        Err(OrphanCheckErr::NonLocalInputType(non_local_spans))
-    } else {
-        let mut non_local_spans = vec![];
-        // First, create an ordered iterator over all the type
-        // parameters to the trait, with the self type appearing
-        // first.  Find the first input type that either references a
-        // type parameter OR some local type.
-        for (i, input_ty) in trait_ref.input_types().enumerate() {
-            let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
-            if non_local_tys.is_none() {
-                debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);
-
-                // First local input type. Check that there are no
-                // uncovered type parameters.
-                let uncovered_tys = uncovered_tys(tcx, input_ty, in_crate);
-                for uncovered_ty in uncovered_tys {
-                    if let Some(param) = uncovered_ty.walk()
-                        .find(|t| is_possibly_remote_type(t, in_crate))
-                    {
-                        debug!("orphan_check_trait_ref: uncovered type `{:?}`", param);
-                        return Err(OrphanCheckErr::UncoveredTy(param));
-                    }
-                }
-
-                // OK, found local type, all prior types upheld invariant.
-                return Ok(());
-            }
-
-            // Otherwise, enforce invariant that there are no type
-            // parameters reachable.
-            if let Some(param) = input_ty.walk()
-                .find(|t| is_possibly_remote_type(t, in_crate))
-            {
-                debug!("orphan_check_trait_ref: uncovered type `{:?}`", param);
-                return Err(OrphanCheckErr::UncoveredTy(param));
-            }
-
-            if let Some(non_local_tys) = non_local_tys {
-                for input_ty in non_local_tys {
-                    non_local_spans.push((input_ty, i == 0));
-                }
+        if let Some(non_local_tys) = non_local_tys {
+            for input_ty in non_local_tys {
+                non_local_spans.push((input_ty, i == 0));
             }
         }
-        // If we exit above loop, never found a local type.
-        debug!("orphan_check_trait_ref: no local type");
-        Err(OrphanCheckErr::NonLocalInputType(non_local_spans))
-    }
-}
-
-fn uncovered_tys<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
-    if ty_is_non_local_constructor(tcx, ty, in_crate).is_none() {
-        vec![]
-    } else if fundamental_ty(ty) {
-        ty.walk_shallow()
-          .flat_map(|t| uncovered_tys(tcx, t, in_crate))
-          .collect()
-    } else {
-        vec![ty]
-    }
-}
-
-fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
-    match ty.kind {
-        ty::Projection(..) | ty::Param(..) => true,
-        _ => false,
     }
+    // If we exit above loop, never found a local type.
+    debug!("orphan_check_trait_ref: no local type");
+    Err(OrphanCheckErr::NonLocalInputType(non_local_spans))
 }
 
 fn ty_is_non_local<'t>(tcx: TyCtxt<'t>, ty: Ty<'t>, in_crate: InCrate) -> Option<Vec<Ty<'t>>> {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 1f7bce1c644..f77db962135 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -33,7 +33,7 @@ use crate::ty::subst::Subst;
 use crate::ty::SubtypePredicate;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::{sym, kw};
@@ -383,9 +383,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let hir = &self.tcx.hir();
         let node = hir.find(hir_id)?;
         if let hir::Node::Item(
-            hir::Item{kind: hir::ItemKind::Fn(_ ,fn_header ,_ , body_id), .. }) = &node {
+            hir::Item{kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node {
             self.describe_generator(*body_id).or_else(||
-                Some(if let hir::FnHeader{ asyncness: hir::IsAsync::Async, .. } = fn_header {
+                Some(if let hir::FnHeader{ asyncness: hir::IsAsync::Async, .. } = sig.header {
                     "an async function"
                 } else {
                     "a function"
@@ -1081,7 +1081,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 }
 
                 hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Fn(_, _, generics, _), ..
+                    kind: hir::ItemKind::Fn(_, generics, _), ..
                 }) |
                 hir::Node::TraitItem(hir::TraitItem {
                     generics,
@@ -1112,7 +1112,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     kind: hir::ItemKind::Impl(_, _, _, generics, ..), span, ..
                 }) |
                 hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Fn(_, _, generics, _), span, ..
+                    kind: hir::ItemKind::Fn(_, generics, _), span, ..
                 }) |
                 hir::Node::Item(hir::Item {
                     kind: hir::ItemKind::TyAlias(_, generics), span, ..
@@ -1130,7 +1130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let restrict_msg = "consider further restricting this bound";
                     let param_name = self_ty.to_string();
                     for param in generics.params.iter().filter(|p| {
-                        &param_name == std::convert::AsRef::<str>::as_ref(&p.name.ident().as_str())
+                        p.name.ident().as_str() == param_name
                     }) {
                         if param_name.starts_with("impl ") {
                             // `impl Trait` in argument:
@@ -1231,7 +1231,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     fn suggest_fn_call(
         &self,
         obligation: &PredicateObligation<'tcx>,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
         points_at_arg: bool,
     ) {
@@ -1385,8 +1385,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
             if let ty::Ref(region, t_type, mutability) = trait_ref.skip_binder().self_ty().kind {
                 let trait_type = match mutability {
-                    hir::Mutability::MutMutable => self.tcx.mk_imm_ref(region, t_type),
-                    hir::Mutability::MutImmutable => self.tcx.mk_mut_ref(region, t_type),
+                    hir::Mutability::Mutable => self.tcx.mk_imm_ref(region, t_type),
+                    hir::Mutability::Immutable => self.tcx.mk_mut_ref(region, t_type),
                 };
 
                 let substs = self.tcx.mk_substs_trait(&trait_type, &[]);
@@ -1403,7 +1403,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let sp = self.tcx.sess.source_map()
                         .span_take_while(span, |c| c.is_whitespace() || *c == '&');
                     if points_at_arg &&
-                        mutability == hir::Mutability::MutImmutable &&
+                        mutability == hir::Mutability::Immutable &&
                         refs_number > 0
                     {
                         err.span_suggestion(
@@ -1436,12 +1436,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let parent_node = hir.get_parent_node(obligation.cause.body_id);
         let node = hir.find(parent_node);
         if let Some(hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Fn(decl, _, _, body_id),
+            kind: hir::ItemKind::Fn(sig, _, body_id),
             ..
         })) = node {
             let body = hir.body(*body_id);
             if let hir::ExprKind::Block(blk, _) = &body.value.kind {
-                if decl.output.span().overlaps(span) && blk.expr.is_none() &&
+                if sig.decl.output.span().overlaps(span) && blk.expr.is_none() &&
                     "()" == &trait_ref.self_ty().to_string()
                 {
                     // FIXME(estebank): When encountering a method with a trait
@@ -1493,20 +1493,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
             Node::Item(&hir::Item {
                 span,
-                kind: hir::ItemKind::Fn(ref decl, ..),
+                kind: hir::ItemKind::Fn(ref sig, ..),
                 ..
             }) |
             Node::ImplItem(&hir::ImplItem {
                 span,
-                kind: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _),
+                kind: hir::ImplItemKind::Method(ref sig, _),
                 ..
             }) |
             Node::TraitItem(&hir::TraitItem {
                 span,
-                kind: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _),
+                kind: hir::TraitItemKind::Method(ref sig, _),
                 ..
             }) => {
-                (self.tcx.sess.source_map().def_span(span), decl.inputs.iter()
+                (self.tcx.sess.source_map().def_span(span), sig.decl.inputs.iter()
                         .map(|arg| match arg.clone().kind {
                     hir::TyKind::Tup(ref tys) => ArgKind::Tuple(
                         Some(arg.span),
@@ -1553,7 +1553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 _ => format!("{} {}argument{}",
                              arg_length,
                              if distinct && arg_length > 1 { "distinct " } else { "" },
-                             pluralise!(arg_length))
+                             pluralize!(arg_length))
             }
         };
 
@@ -2040,11 +2040,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             .and_then(|parent_did| self.tcx.hir().get_if_local(parent_did));
         debug!("note_obligation_cause_for_async_await: parent_node={:?}", parent_node);
         if let Some(hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Fn(_, header, _, _),
+            kind: hir::ItemKind::Fn(sig, _, _),
             ..
         })) = parent_node {
-            debug!("note_obligation_cause_for_async_await: header={:?}", header);
-            if header.asyncness != hir::IsAsync::Async {
+            debug!("note_obligation_cause_for_async_await: header={:?}", sig.header);
+            if sig.header.asyncness != hir::IsAsync::Async {
                 return false;
             }
         }
@@ -2287,11 +2287,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     );
                 }
             }
-            ObligationCauseCode::AssocTypeBound(impl_span, orig) => {
-                err.span_label(orig, "associated type defined here");
-                if let Some(sp) = impl_span {
+            ObligationCauseCode::AssocTypeBound(ref data) => {
+                err.span_label(data.original, "associated type defined here");
+                if let Some(sp) = data.impl_span {
                     err.span_label(sp, "in this `impl` item");
                 }
+                for sp in &data.bounds {
+                    err.span_label(*sp, "restricted in this bound");
+                }
             }
         }
     }
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index b8275299562..a29d8c66d81 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -276,7 +276,14 @@ pub enum ObligationCauseCode<'tcx> {
     /// #[feature(trivial_bounds)] is not enabled
     TrivialBound,
 
-    AssocTypeBound(/*impl*/ Option<Span>, /*original*/ Span),
+    AssocTypeBound(Box<AssocTypeBoundData>),
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct AssocTypeBoundData {
+    pub impl_span: Option<Span>,
+    pub original: Span,
+    pub bounds: Vec<Span>,
 }
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index b39c00a56e3..b64e44b6a5a 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -180,7 +180,7 @@ impl<'tcx> OnUnimplementedDirective {
                     c.ident().map_or(false, |ident| {
                         options.contains(&(
                             ident.name,
-                            c.value_str().map(|s| s.as_str().to_string())
+                            c.value_str().map(|s| s.to_string())
                         ))
                     })
                 }) {
diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs
index e84c91daf29..eaf5971e459 100644
--- a/src/librustc/traits/query/dropck_outlives.rs
+++ b/src/librustc/traits/query/dropck_outlives.rs
@@ -5,7 +5,6 @@ use std::iter::FromIterator;
 use syntax::source_map::Span;
 use crate::ty::subst::GenericArg;
 use crate::ty::{self, Ty, TyCtxt};
-use crate::ty::query::Providers;
 
 impl<'cx, 'tcx> At<'cx, 'tcx> {
     /// Given a type `ty` of some value being dropped, computes a set
@@ -34,7 +33,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
         // Quick check: there are a number of cases that we know do not require
         // any destructor.
         let tcx = self.infcx.tcx;
-        if tcx.trivial_dropck_outlives(ty) {
+        if trivial_dropck_outlives(tcx, ty) {
             return InferOk {
                 value: vec![],
                 obligations: vec![],
@@ -208,15 +207,15 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
         | ty::Error => true,
 
         // [T; N] and [T] have same properties as T.
-        ty::Array(ty, _) | ty::Slice(ty) => tcx.trivial_dropck_outlives(ty),
+        ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty),
 
         // (T1..Tn) and closures have same properties as T1..Tn --
         // check if *any* of those are trivial.
-        ty::Tuple(ref tys) => tys.iter().all(|t| tcx.trivial_dropck_outlives(t.expect_ty())),
+        ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())),
         ty::Closure(def_id, ref substs) => substs
             .as_closure()
             .upvar_tys(def_id, tcx)
-            .all(|t| tcx.trivial_dropck_outlives(t)),
+            .all(|t| trivial_dropck_outlives(tcx, t)),
 
         ty::Adt(def, _) => {
             if Some(def.did) == tcx.lang_items().manually_drop() {
@@ -244,10 +243,3 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
         ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
     }
 }
-
-crate fn provide(p: &mut Providers<'_>) {
-    *p = Providers {
-        trivial_dropck_outlives,
-        ..*p
-    };
-}
diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs
index 86a32d68fc0..81c3857cbf8 100644
--- a/src/librustc/traits/query/type_op/outlives.rs
+++ b/src/librustc/traits/query/type_op/outlives.rs
@@ -1,5 +1,5 @@
 use crate::infer::canonical::{Canonicalized, CanonicalizedQueryResponse};
-use crate::traits::query::dropck_outlives::DropckOutlivesResult;
+use crate::traits::query::dropck_outlives::{DropckOutlivesResult, trivial_dropck_outlives};
 use crate::traits::query::Fallible;
 use crate::ty::{ParamEnvAnd, Ty, TyCtxt};
 
@@ -21,7 +21,7 @@ impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
         tcx: TyCtxt<'tcx>,
         key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse> {
-        if tcx.trivial_dropck_outlives(key.value.dropped_ty) {
+        if trivial_dropck_outlives(tcx, key.value.dropped_ty) {
             Some(DropckOutlivesResult::default())
         } else {
             None
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index d8a27f1e040..04b2597af22 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2195,11 +2195,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     if self.tcx().lang_items().unpin_trait() == Some(def_id) =>
                 {
                     match movability {
-                        hir::GeneratorMovability::Static => {
+                        hir::Movability::Static => {
                             // Immovable generators are never `Unpin`, so
                             // suppress the normal auto-impl candidate for it.
                         }
-                        hir::GeneratorMovability::Movable => {
+                        hir::Movability::Movable => {
                             // Movable generators are always `Unpin`, so add an
                             // unconditional builtin candidate.
                             candidates.vec.push(BuiltinCandidate {
@@ -2652,7 +2652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Char
             | ty::RawPtr(..)
             | ty::Never
-            | ty::Ref(_, _, hir::MutImmutable) => {
+            | ty::Ref(_, _, hir::Mutability::Immutable) => {
                 // Implementations provided in libcore
                 None
             }
@@ -2663,7 +2663,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
             | ty::Foreign(..)
-            | ty::Ref(_, _, hir::MutMutable) => None,
+            | ty::Ref(_, _, hir::Mutability::Mutable) => None,
 
             ty::Array(element_ty, _) => {
                 // (*) binder moved here
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 109e884f8bd..59f2bb37548 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -549,7 +549,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::MethodReceiver => Some(super::MethodReceiver),
             super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
             super::TrivialBound => Some(super::TrivialBound),
-            super::AssocTypeBound(impl_sp, sp) => Some(super::AssocTypeBound(impl_sp, sp)),
+            super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())),
         }
     }
 }
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index 9ba99768215..f5ab1eb38c3 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -20,6 +20,9 @@ pub enum PointerCast {
     /// Go from a mut raw pointer to a const raw pointer.
     MutToConstPointer,
 
+    /// Go from `*const [T; N]` to `*const T`
+    ArrayToPointer,
+
     /// Unsize a pointer/reference value, e.g., `&[T; n]` to
     /// `&[T]`. Note that the source could be a thin or fat pointer.
     /// This will do things like convert thin pointers to fat
@@ -106,8 +109,8 @@ pub struct OverloadedDeref<'tcx> {
 impl<'tcx> OverloadedDeref<'tcx> {
     pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) {
         let trait_def_id = match self.mutbl {
-            hir::MutImmutable => tcx.lang_items().deref_trait(),
-            hir::MutMutable => tcx.lang_items().deref_mut_trait()
+            hir::Mutability::Immutable => tcx.lang_items().deref_trait(),
+            hir::Mutability::Mutable => tcx.lang_items().deref_mut_trait()
         };
         let method_def_id = tcx.associated_items(trait_def_id.unwrap())
             .find(|m| m.kind == ty::AssocKind::Method).unwrap().def_id;
@@ -142,8 +145,8 @@ pub enum AutoBorrowMutability {
 impl From<AutoBorrowMutability> for hir::Mutability {
     fn from(m: AutoBorrowMutability) -> Self {
         match m {
-            AutoBorrowMutability::Mutable { .. } => hir::MutMutable,
-            AutoBorrowMutability::Immutable => hir::MutImmutable,
+            AutoBorrowMutability::Mutable { .. } => hir::Mutability::Mutable,
+            AutoBorrowMutability::Immutable => hir::Mutability::Immutable,
         }
     }
 }
diff --git a/src/librustc/ty/binding.rs b/src/librustc/ty/binding.rs
index 5570144489c..905d7abb782 100644
--- a/src/librustc/ty/binding.rs
+++ b/src/librustc/ty/binding.rs
@@ -13,10 +13,10 @@ CloneTypeFoldableAndLiftImpls! { BindingMode, }
 impl BindingMode {
     pub fn convert(ba: BindingAnnotation) -> BindingMode {
         match ba {
-            Unannotated => BindingMode::BindByValue(Mutability::MutImmutable),
-            Mutable => BindingMode::BindByValue(Mutability::MutMutable),
-            Ref => BindingMode::BindByReference(Mutability::MutImmutable),
-            RefMut => BindingMode::BindByReference(Mutability::MutMutable),
+            Unannotated => BindingMode::BindByValue(Mutability::Immutable),
+            Mutable => BindingMode::BindByValue(Mutability::Mutable),
+            Ref => BindingMode::BindByReference(Mutability::Immutable),
+            RefMut => BindingMode::BindByReference(Mutability::Mutable),
         }
     }
 }
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index d5e7ac19263..b3ef3217ec6 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -76,7 +76,10 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E,
 
     // The shorthand encoding uses the same usize as the
     // discriminant, with an offset so they can't conflict.
+    #[cfg(bootstrap)]
     let discriminant = unsafe { intrinsics::discriminant_value(variant) };
+    #[cfg(not(bootstrap))]
+    let discriminant = intrinsics::discriminant_value(variant);
     assert!(discriminant < SHORTHAND_OFFSET as u64);
     let shorthand = start + SHORTHAND_OFFSET;
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 3d28beefb34..04e0f6f4b56 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2410,22 +2410,22 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutMutable})
+        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::Mutability::Mutable})
     }
 
     #[inline]
     pub fn mk_imm_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
+        self.mk_ref(r, TypeAndMut {ty: ty, mutbl: hir::Mutability::Immutable})
     }
 
     #[inline]
     pub fn mk_mut_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutMutable})
+        self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::Mutability::Mutable})
     }
 
     #[inline]
     pub fn mk_imm_ptr(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::MutImmutable})
+        self.mk_ptr(TypeAndMut {ty: ty, mutbl: hir::Mutability::Immutable})
     }
 
     #[inline]
@@ -2516,7 +2516,7 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn mk_generator(self,
                         id: DefId,
                         generator_substs: SubstsRef<'tcx>,
-                        movability: hir::GeneratorMovability)
+                        movability: hir::Movability)
                         -> Ty<'tcx> {
         self.mk_ty(Generator(id, generator_substs, movability))
     }
@@ -3045,4 +3045,9 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         assert_eq!(cnum, LOCAL_CRATE);
         attr::contains_name(tcx.hir().krate_attrs(), sym::compiler_builtins)
     };
+    providers.has_panic_handler = |tcx, cnum| {
+        assert_eq!(cnum, LOCAL_CRATE);
+        // We want to check if the panic handler was defined in this crate
+        tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
+    };
 }
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 77613b548cf..c61d559af53 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -4,7 +4,7 @@ use std::borrow::Cow;
 use std::fmt;
 use rustc_target::spec::abi;
 use syntax::ast;
-use syntax::errors::pluralise;
+use syntax::errors::pluralize;
 use errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
 
@@ -100,17 +100,17 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
                 write!(f, "expected a tuple with {} element{}, \
                            found one with {} element{}",
                        values.expected,
-                       pluralise!(values.expected),
+                       pluralize!(values.expected),
                        values.found,
-                       pluralise!(values.found))
+                       pluralize!(values.found))
             }
             FixedArraySize(values) => {
                 write!(f, "expected an array with a fixed size of {} element{}, \
                            found one with {} element{}",
                        values.expected,
-                       pluralise!(values.expected),
+                       pluralize!(values.expected),
                        values.found,
-                       pluralise!(values.found))
+                       pluralize!(values.found))
             }
             ArgCount => {
                 write!(f, "incorrect number of function parameters")
@@ -165,7 +165,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             ProjectionBoundsLength(ref values) => {
                 write!(f, "expected {} associated type binding{}, found {}",
                        values.expected,
-                       pluralise!(values.expected),
+                       pluralize!(values.expected),
                        values.found)
             },
             ExistentialMismatch(ref values) => {
@@ -196,7 +196,7 @@ impl<'tcx> ty::TyS<'tcx> {
                 let n = tcx.lift(&n).unwrap();
                 match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                     Some(n) => {
-                        format!("array of {} element{}", n, pluralise!(n)).into()
+                        format!("array of {} element{}", n, pluralize!(n)).into()
                     }
                     None => "array".into(),
                 }
@@ -211,7 +211,7 @@ impl<'tcx> ty::TyS<'tcx> {
                    region.to_string() != "'_"     //... or a complex type
                 {
                     format!("{}reference", match mutbl {
-                        hir::Mutability::MutMutable => "mutable ",
+                        hir::Mutability::Mutable => "mutable ",
                         _ => ""
                     }).into()
                 } else {
@@ -241,7 +241,7 @@ impl<'tcx> ty::TyS<'tcx> {
             ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
             ty::Projection(_) => "associated type".into(),
             ty::UnnormalizedProjection(_) => "non-normalized associated type".into(),
-            ty::Param(_) => "type parameter".into(),
+            ty::Param(p) => format!("type parameter `{}`", p).into(),
             ty::Opaque(..) => "opaque type".into(),
             ty::Error => "type error".into(),
         }
@@ -254,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
         db: &mut DiagnosticBuilder<'_>,
         err: &TypeError<'tcx>,
         sp: Span,
+        body_owner_def_id: DefId,
     ) {
         use self::TypeError::*;
 
@@ -288,7 +289,16 @@ impl<'tcx> TyCtxt<'tcx> {
                             );
                         }
                     },
-                    (ty::Param(_), ty::Param(_)) => {
+                    (ty::Param(expected), ty::Param(found)) => {
+                        let generics = self.generics_of(body_owner_def_id);
+                        let e_span = self.def_span(generics.type_param(expected, self).def_id);
+                        if !sp.contains(e_span) {
+                            db.span_label(e_span, "expected type parameter");
+                        }
+                        let f_span = self.def_span(generics.type_param(found, self).def_id);
+                        if !sp.contains(f_span) {
+                            db.span_label(f_span, "found type parameter");
+                        }
                         db.note("a type parameter was expected, but a different one was found; \
                                  you might be missing a type parameter or trait bound");
                         db.note("for more information, visit \
@@ -301,7 +311,12 @@ impl<'tcx> TyCtxt<'tcx> {
                     (ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
                         db.note("you might be missing a type parameter or trait bound");
                     }
-                    (ty::Param(_), _) | (_, ty::Param(_)) => {
+                    (ty::Param(p), _) | (_, ty::Param(p)) => {
+                        let generics = self.generics_of(body_owner_def_id);
+                        let p_span = self.def_span(generics.type_param(p, self).def_id);
+                        if !sp.contains(p_span) {
+                            db.span_label(p_span, "this type parameter");
+                        }
                         db.help("type parameters must be constrained to match other types");
                         if self.sess.teach(&db.get_code().unwrap()) {
                             db.help("given a type parameter `T` and a method `foo`:
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index 63cc60d80aa..227fbf967c0 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -76,19 +76,19 @@ impl<'tcx> DefIdForest {
                 break;
             }
 
-            for id in ret.root_ids.drain() {
+            for id in ret.root_ids.drain(..) {
                 if next_forest.contains(tcx, id) {
                     next_ret.push(id);
                 } else {
                     old_ret.push(id);
                 }
             }
-            ret.root_ids.extend(old_ret.drain());
+            ret.root_ids.extend(old_ret.drain(..));
 
             next_ret.extend(next_forest.root_ids.into_iter().filter(|&id| ret.contains(tcx, id)));
 
             mem::swap(&mut next_ret, &mut ret.root_ids);
-            next_ret.drain();
+            next_ret.drain(..);
         }
         ret
     }
@@ -101,7 +101,7 @@ impl<'tcx> DefIdForest {
         let mut ret = DefIdForest::empty();
         let mut next_ret = SmallVec::new();
         for next_forest in iter {
-            next_ret.extend(ret.root_ids.drain().filter(|&id| !next_forest.contains(tcx, id)));
+            next_ret.extend(ret.root_ids.drain(..).filter(|&id| !next_forest.contains(tcx, id)));
 
             for id in next_forest.root_ids {
                 if !next_ret.contains(&id) {
@@ -110,7 +110,7 @@ impl<'tcx> DefIdForest {
             }
 
             mem::swap(&mut next_ret, &mut ret.root_ids);
-            next_ret.drain();
+            next_ret.drain(..);
         }
         ret
     }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 95040135eb7..972452601dd 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -132,8 +132,8 @@ impl PrimitiveExt for Primitive {
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             Int(i, signed) => i.to_ty(tcx, signed),
-            Float(FloatTy::F32) => tcx.types.f32,
-            Float(FloatTy::F64) => tcx.types.f64,
+            F32 => tcx.types.f32,
+            F64 => tcx.types.f64,
             Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
         }
     }
@@ -144,7 +144,7 @@ impl PrimitiveExt for Primitive {
         match *self {
             Int(i, signed) => i.to_ty(tcx, signed),
             Pointer => tcx.types.usize,
-            Float(..) => bug!("floats do not have an int type"),
+            F32 | F64 => bug!("floats do not have an int type"),
         }
     }
 }
@@ -538,7 +538,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             ty::Uint(ity) => {
                 scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false))
             }
-            ty::Float(fty) => scalar(Float(fty)),
+            ty::Float(fty) => scalar(match fty {
+                ast::FloatTy::F32 => F32,
+                ast::FloatTy::F64 => F64,
+            }),
             ty::FnPtr(_) => {
                 let mut ptr = scalar_unit(Pointer);
                 ptr.valid_range = 1..=*ptr.valid_range.end();
@@ -1611,13 +1614,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         // (delay format until we actually need it)
         let record = |kind, packed, opt_discr_size, variants| {
             let type_desc = format!("{:?}", layout.ty);
-            self.tcx.sess.code_stats.borrow_mut().record_type_size(kind,
-                                                                   type_desc,
-                                                                   layout.align.abi,
-                                                                   layout.size,
-                                                                   packed,
-                                                                   opt_discr_size,
-                                                                   variants);
+            self.tcx.sess.code_stats.record_type_size(kind,
+                                                      type_desc,
+                                                      layout.align.abi,
+                                                      layout.size,
+                                                      packed,
+                                                      opt_discr_size,
+                                                      variants);
         };
 
         let adt_def = match layout.ty.kind {
@@ -2218,12 +2221,12 @@ where
                 let tcx = cx.tcx();
                 let is_freeze = ty.is_freeze(tcx, cx.param_env(), DUMMY_SP);
                 let kind = match mt {
-                    hir::MutImmutable => if is_freeze {
+                    hir::Mutability::Immutable => if is_freeze {
                         PointerKind::Frozen
                     } else {
                         PointerKind::Shared
                     },
-                    hir::MutMutable => {
+                    hir::Mutability::Mutable => {
                         // Previously we would only emit noalias annotations for LLVM >= 6 or in
                         // panic=abort mode. That was deemed right, as prior versions had many bugs
                         // in conjunction with unwinding, but later versions didn’t seem to have
@@ -2454,7 +2457,8 @@ impl_stable_hash_for!(enum crate::ty::layout::Integer {
 
 impl_stable_hash_for!(enum crate::ty::layout::Primitive {
     Int(integer, signed),
-    Float(fty),
+    F32,
+    F64,
     Pointer
 });
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 60028f2488a..e4ed1cd198e 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2693,8 +2693,8 @@ impl<'tcx> TyS<'tcx> {
 impl BorrowKind {
     pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
         match m {
-            hir::MutMutable => MutBorrow,
-            hir::MutImmutable => ImmBorrow,
+            hir::Mutability::Mutable => MutBorrow,
+            hir::Mutability::Immutable => ImmBorrow,
         }
     }
 
@@ -2704,13 +2704,13 @@ impl BorrowKind {
     /// question.
     pub fn to_mutbl_lossy(self) -> hir::Mutability {
         match self {
-            MutBorrow => hir::MutMutable,
-            ImmBorrow => hir::MutImmutable,
+            MutBorrow => hir::Mutability::Mutable,
+            ImmBorrow => hir::Mutability::Immutable,
 
             // We have no type corresponding to a unique imm borrow, so
             // use `&mut`. It gives all the capabilities of an `&uniq`
             // and hence is a safe "over approximation".
-            UniqueImmBorrow => hir::MutMutable,
+            UniqueImmBorrow => hir::Mutability::Mutable,
         }
     }
 
@@ -3407,7 +3407,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     layout::provide(providers);
     util::provide(providers);
     constness::provide(providers);
-    crate::traits::query::dropck_outlives::provide(providers);
     *providers = ty::query::Providers {
         asyncness,
         associated_item,
diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs
index e72916de6a9..0389218b61d 100644
--- a/src/librustc/ty/print/obsolete.rs
+++ b/src/librustc/ty/print/obsolete.rs
@@ -12,7 +12,6 @@ use rustc::ty::{self, Const, Instance, Ty, TyCtxt};
 use rustc::{bug, hir};
 use std::fmt::Write;
 use std::iter;
-use syntax::ast;
 
 /// Same as `unique_type_name()` but with the result pushed onto the given
 /// `output` parameter.
@@ -39,20 +38,9 @@ impl DefPathBasedNames<'tcx> {
             ty::Char => output.push_str("char"),
             ty::Str => output.push_str("str"),
             ty::Never => output.push_str("!"),
-            ty::Int(ast::IntTy::Isize) => output.push_str("isize"),
-            ty::Int(ast::IntTy::I8) => output.push_str("i8"),
-            ty::Int(ast::IntTy::I16) => output.push_str("i16"),
-            ty::Int(ast::IntTy::I32) => output.push_str("i32"),
-            ty::Int(ast::IntTy::I64) => output.push_str("i64"),
-            ty::Int(ast::IntTy::I128) => output.push_str("i128"),
-            ty::Uint(ast::UintTy::Usize) => output.push_str("usize"),
-            ty::Uint(ast::UintTy::U8) => output.push_str("u8"),
-            ty::Uint(ast::UintTy::U16) => output.push_str("u16"),
-            ty::Uint(ast::UintTy::U32) => output.push_str("u32"),
-            ty::Uint(ast::UintTy::U64) => output.push_str("u64"),
-            ty::Uint(ast::UintTy::U128) => output.push_str("u128"),
-            ty::Float(ast::FloatTy::F32) => output.push_str("f32"),
-            ty::Float(ast::FloatTy::F64) => output.push_str("f64"),
+            ty::Int(ty) => output.push_str(ty.name_str()),
+            ty::Uint(ty) => output.push_str(ty.name_str()),
+            ty::Float(ty) => output.push_str(ty.name_str()),
             ty::Adt(adt_def, substs) => {
                 self.push_def_path(adt_def.did, output);
                 self.push_generic_params(substs, iter::empty(), output, debug);
@@ -72,17 +60,15 @@ impl DefPathBasedNames<'tcx> {
             ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => {
                 output.push('*');
                 match mutbl {
-                    hir::MutImmutable => output.push_str("const "),
-                    hir::MutMutable => output.push_str("mut "),
+                    hir::Mutability::Immutable => output.push_str("const "),
+                    hir::Mutability::Mutable => output.push_str("mut "),
                 }
 
                 self.push_type_name(inner_type, output, debug);
             }
             ty::Ref(_, inner_type, mutbl) => {
                 output.push('&');
-                if mutbl == hir::MutMutable {
-                    output.push_str("mut ");
-                }
+                output.push_str(mutbl.prefix_str());
 
                 self.push_type_name(inner_type, output, debug);
             }
@@ -114,9 +100,7 @@ impl DefPathBasedNames<'tcx> {
             ty::Foreign(did) => self.push_def_path(did, output),
             ty::FnDef(..) | ty::FnPtr(_) => {
                 let sig = t.fn_sig(self.tcx);
-                if sig.unsafety() == hir::Unsafety::Unsafe {
-                    output.push_str("unsafe ");
-                }
+                output.push_str(sig.unsafety().prefix_str());
 
                 let abi = sig.abi();
                 if abi != ::rustc_target::spec::abi::Abi::Rust {
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 8a98a5d8361..fdd3a1faaa9 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -466,13 +466,13 @@ pub trait PrettyPrinter<'tcx>:
         match ty.kind {
             ty::Bool => p!(write("bool")),
             ty::Char => p!(write("char")),
-            ty::Int(t) => p!(write("{}", t.ty_to_string())),
-            ty::Uint(t) => p!(write("{}", t.ty_to_string())),
-            ty::Float(t) => p!(write("{}", t.ty_to_string())),
+            ty::Int(t) => p!(write("{}", t.name_str())),
+            ty::Uint(t) => p!(write("{}", t.name_str())),
+            ty::Float(t) => p!(write("{}", t.name_str())),
             ty::RawPtr(ref tm) => {
                 p!(write("*{} ", match tm.mutbl {
-                    hir::MutMutable => "mut",
-                    hir::MutImmutable => "const",
+                    hir::Mutability::Mutable => "mut",
+                    hir::Mutability::Immutable => "const",
                 }));
                 p!(print(tm.ty))
             }
@@ -607,10 +607,9 @@ pub trait PrettyPrinter<'tcx>:
             ty::Generator(did, substs, movability) => {
                 let upvar_tys = substs.as_generator().upvar_tys(did, self.tcx());
                 let witness = substs.as_generator().witness(did, self.tcx());
-                if movability == hir::GeneratorMovability::Movable {
-                    p!(write("[generator"));
-                } else {
-                    p!(write("[static generator"));
+                match movability {
+                    hir::Movability::Movable => p!(write("[generator")),
+                    hir::Movability::Static  => p!(write("[static generator")),
                 }
 
                 // FIXME(eddyb) should use `def_span`.
@@ -895,10 +894,11 @@ pub trait PrettyPrinter<'tcx>:
                 let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
                 let max = truncate(u128::max_value(), bit_size);
 
+                let ui_str = ui.name_str();
                 if data == max {
-                    p!(write("std::{}::MAX", ui))
+                    p!(write("std::{}::MAX", ui_str))
                 } else {
-                    p!(write("{}{}", data, ui))
+                    p!(write("{}{}", data, ui_str))
                 };
             },
             (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Int(i)) => {
@@ -911,10 +911,11 @@ pub trait PrettyPrinter<'tcx>:
                 let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty))
                     .unwrap()
                     .size;
+                let i_str = i.name_str();
                 match data {
-                    d if d == min => p!(write("std::{}::MIN", i)),
-                    d if d == max => p!(write("std::{}::MAX", i)),
-                    _ => p!(write("{}{}", sign_extend(data, size) as i128, i))
+                    d if d == min => p!(write("std::{}::MIN", i_str)),
+                    d if d == max => p!(write("std::{}::MAX", i_str)),
+                    _ => p!(write("{}{}", sign_extend(data, size) as i128, i_str))
                 }
             },
             (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) =>
@@ -1666,8 +1667,7 @@ define_print_and_forward_display! {
     }
 
     ty::TypeAndMut<'tcx> {
-        p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
-            print(self.ty))
+        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
     }
 
     ty::ExistentialTraitRef<'tcx> {
@@ -1693,9 +1693,7 @@ define_print_and_forward_display! {
     }
 
     ty::FnSig<'tcx> {
-        if self.unsafety == hir::Unsafety::Unsafe {
-            p!(write("unsafe "));
-        }
+        p!(write("{}", self.unsafety.prefix_str()));
 
         if self.abi != Abi::Rust {
             p!(write("extern {} ", self.abi));
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 9b15ad560b5..0615004125b 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -42,7 +42,6 @@ use crate::util::common::ErrorReported;
 use crate::util::profiling::ProfileCategory::*;
 
 use rustc_data_structures::svh::Svh;
-use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet};
 use rustc_data_structures::stable_hasher::StableVec;
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 21a7cf00b28..4031eb62194 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -264,7 +264,7 @@ impl<'sess> OnDiskCache<'sess> {
             let sorted_cnums = sorted_cnums_including_local_crate(tcx);
             let prev_cnums: Vec<_> = sorted_cnums.iter()
                 .map(|&cnum| {
-                    let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
+                    let crate_name = tcx.original_crate_name(cnum).to_string();
                     let crate_disambiguator = tcx.crate_disambiguator(cnum);
                     (cnum.as_u32(), crate_name, crate_disambiguator)
                 })
@@ -796,11 +796,6 @@ where
         }
 
         let span_data = span.data();
-
-        if span_data.hi < span_data.lo {
-            return TAG_INVALID_SPAN.encode(self);
-        }
-
         let (file_lo, line_lo, col_lo) = match self.source_map
                                                    .byte_pos_to_line_and_col(span_data.lo) {
             Some(pos) => pos,
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 1da65f4b51d..9b5cdc489a8 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -121,8 +121,8 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
         } else {
             let mutbl = a.mutbl;
             let variance = match mutbl {
-                ast::Mutability::MutImmutable => ty::Covariant,
-                ast::Mutability::MutMutable => ty::Invariant,
+                ast::Mutability::Immutable => ty::Covariant,
+                ast::Mutability::Mutable => ty::Invariant,
             };
             let ty = relation.relate_with_variance(variance, &a.ty, &b.ty)?;
             Ok(ty::TypeAndMut { ty, mutbl })
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 3a9994ac64c..51cf7550c30 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -162,7 +162,7 @@ pub enum TyKind<'tcx> {
 
     /// The anonymous type of a generator. Used to represent the type of
     /// `|a| yield a`.
-    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 
     /// A type representin the types stored inside a generator.
     /// This should only appear in GeneratorInteriors.
@@ -1839,8 +1839,8 @@ impl<'tcx> TyS<'tcx> {
     #[inline]
     pub fn is_mutable_ptr(&self) -> bool {
         match self.kind {
-            RawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) |
-            Ref(_, _, hir::Mutability::MutMutable) => true,
+            RawPtr(TypeAndMut { mutbl: hir::Mutability::Mutable, .. }) |
+            Ref(_, _, hir::Mutability::Mutable) => true,
             _ => false
         }
     }
@@ -2030,7 +2030,7 @@ impl<'tcx> TyS<'tcx> {
             Adt(def, _) if def.is_box() => {
                 Some(TypeAndMut {
                     ty: self.boxed_ty(),
-                    mutbl: hir::MutImmutable,
+                    mutbl: hir::Mutability::Immutable,
                 })
             },
             Ref(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }),
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 5555dace45b..d46320abff2 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -184,7 +184,7 @@ impl<'tcx> ty::ParamEnv<'tcx> {
                 // Now libcore provides that impl.
                 ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Float(_) |
                 ty::Char | ty::RawPtr(..) | ty::Never |
-                ty::Ref(_, _, hir::MutImmutable) => return Ok(()),
+                ty::Ref(_, _, hir::Mutability::Immutable) => return Ok(()),
 
                 ty::Adt(adt, substs) => (adt, substs),
 
@@ -680,7 +680,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     /// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
     pub fn is_mutable_static(&self, def_id: DefId) -> bool {
-        self.static_mutability(def_id) == Some(hir::MutMutable)
+        self.static_mutability(def_id) == Some(hir::Mutability::Mutable)
     }
 
     /// Expands the given impl trait type, stopping if the type is recursive.
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index 4ea01bf9647..f9e7a8030a6 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -2,9 +2,10 @@ use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::infer::InferCtxt;
 use crate::ty::subst::SubstsRef;
-use crate::traits;
+use crate::traits::{self, AssocTypeBoundData};
 use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use std::iter::once;
+use syntax::symbol::{kw, Ident};
 use syntax_pos::Span;
 use crate::middle::lang_items;
 use crate::mir::interpret::ConstValue;
@@ -176,6 +177,23 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
             pred: &ty::Predicate<'_>,
             trait_assoc_items: ty::AssocItemsIterator<'_>,
         | {
+            let trait_item = tcx.hir().as_local_hir_id(trait_ref.def_id).and_then(|trait_id| {
+                tcx.hir().find(trait_id)
+            });
+            let (trait_name, trait_generics) = match trait_item {
+                Some(hir::Node::Item(hir::Item {
+                    ident,
+                    kind: hir::ItemKind::Trait(.., generics, _, _),
+                    ..
+                })) |
+                Some(hir::Node::Item(hir::Item {
+                    ident,
+                    kind: hir::ItemKind::TraitAlias(generics, _),
+                    ..
+                })) => (Some(ident), Some(generics)),
+                _ => (None, None),
+            };
+
             let item_span = item.map(|i| tcx.sess.source_map().def_span(i.span));
             match pred {
                 ty::Predicate::Projection(proj) => {
@@ -226,10 +244,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                             item.ident == trait_assoc_item.ident
                         }).next() {
                             cause.span = impl_item.span;
-                            cause.code = traits::AssocTypeBound(
-                                item_span,
-                                trait_assoc_item.ident.span,
-                            );
+                            cause.code = traits::AssocTypeBound(Box::new(AssocTypeBoundData {
+                                impl_span: item_span,
+                                original: trait_assoc_item.ident.span,
+                                bounds: vec![],
+                            }));
                         }
                     }
                 }
@@ -251,14 +270,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                     //   LL |     type Assoc = bool;
                     //      |     ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
                     //
-                    // FIXME: if the obligation comes from the where clause in the `trait`, we
-                    // should point at it:
+                    // If the obligation comes from the where clause in the `trait`, we point at it:
                     //
                     //   error[E0277]: the trait bound `bool: Bar` is not satisfied
                     //     --> $DIR/point-at-type-on-obligation-failure-2.rs:8:5
                     //      |
                     //      | trait Foo where <Self as Foo>>::Assoc: Bar {
-                    //      |                 -------------------------- obligation set here
+                    //      |                 -------------------------- restricted in this bound
                     //   LL |     type Assoc;
                     //      |          ----- associated type defined here
                     //   ...
@@ -278,11 +296,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                                 .next()
                                 .map(|impl_item| (impl_item, trait_assoc_item)))
                         {
+                            let bounds = trait_generics.map(|generics| get_generic_bound_spans(
+                                &generics,
+                                trait_name,
+                                trait_assoc_item.ident,
+                            )).unwrap_or_else(Vec::new);
                             cause.span = impl_item.span;
-                            cause.code = traits::AssocTypeBound(
-                                item_span,
-                                trait_assoc_item.ident.span,
-                            );
+                            cause.code = traits::AssocTypeBound(Box::new(AssocTypeBoundData {
+                                impl_span: item_span,
+                                original: trait_assoc_item.ident.span,
+                                bounds,
+                            }));
                         }
                     }
                 }
@@ -666,3 +690,56 @@ pub fn object_region_bounds<'tcx>(
 
     tcx.required_region_bounds(open_ty, predicates)
 }
+
+/// Find the span of a generic bound affecting an associated type.
+fn get_generic_bound_spans(
+    generics: &hir::Generics,
+    trait_name: Option<&Ident>,
+    assoc_item_name: Ident,
+) -> Vec<Span> {
+    let mut bounds = vec![];
+    for clause in generics.where_clause.predicates.iter() {
+        if let hir::WherePredicate::BoundPredicate(pred) = clause {
+            match &pred.bounded_ty.kind {
+                hir::TyKind::Path(hir::QPath::Resolved(Some(ty), path)) => {
+                    let mut s = path.segments.iter();
+                    if let (a, Some(b), None) = (s.next(), s.next(), s.next()) {
+                        if a.map(|s| &s.ident) == trait_name
+                            && b.ident == assoc_item_name
+                            && is_self_path(&ty.kind)
+                        {
+                            // `<Self as Foo>::Bar`
+                            bounds.push(pred.span);
+                        }
+                    }
+                }
+                hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => {
+                    if segment.ident == assoc_item_name {
+                        if is_self_path(&ty.kind) {
+                            // `Self::Bar`
+                            bounds.push(pred.span);
+                        }
+                    }
+                }
+                _ => {}
+            }
+        }
+    }
+    bounds
+}
+
+fn is_self_path(kind: &hir::TyKind) -> bool {
+    match kind {
+        hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
+            let mut s = path.segments.iter();
+            if let (Some(segment), None) = (s.next(), s.next()) {
+                if segment.ident.name == kw::SelfUpper {
+                    // `type(Self)`
+                    return true;
+                }
+            }
+        }
+        _ => {}
+    }
+    false
+}
diff --git a/src/librustc_apfloat/Cargo.toml b/src/librustc_apfloat/Cargo.toml
index 4fc15f99e48..726965e1e71 100644
--- a/src/librustc_apfloat/Cargo.toml
+++ b/src/librustc_apfloat/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 bitflags = "1.2.1"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index 6a36a4a50cb..6f4e7d0f0ca 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -314,7 +314,7 @@ pub fn from_fn_attrs(
             codegen_fn_attrs.target_features
                 .iter()
                 .map(|f| {
-                    let feature = &*f.as_str();
+                    let feature = &f.as_str();
                     format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
                 })
         )
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 52f3a1cbb5c..e5a5d05ba5e 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -161,6 +161,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
     let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
     let features = features.join(",");
     let features = CString::new(features).unwrap();
+    let abi = SmallCStr::new(&sess.target.target.options.llvm_abiname);
     let is_pie_binary = !find_features && is_pie_binary(sess);
     let trap_unreachable = sess.target.target.options.trap_unreachable;
     let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
@@ -170,7 +171,7 @@ pub fn target_machine_factory(sess: &Session, optlvl: config::OptLevel, find_fea
     Arc::new(move || {
         let tm = unsafe {
             llvm::LLVMRustCreateTargetMachine(
-                triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
+                triple.as_ptr(), cpu.as_ptr(), features.as_ptr(), abi.as_ptr(),
                 code_model,
                 reloc_model,
                 opt_level,
@@ -239,9 +240,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
     }
 }
 
-unsafe extern "C" fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>,
-                                       msg: &str,
-                                       cookie: c_uint) {
+fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>, msg: &str, cookie: c_uint) {
     cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
 }
 
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 2da93877172..4a40349cb73 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -203,6 +203,10 @@ pub unsafe fn create_module(
     let llvm_target = SmallCStr::new(&sess.target.target.llvm_target);
     llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
 
+    if get_reloc_model(sess) == llvm::RelocMode::PIC {
+        llvm::LLVMRustSetModulePICLevel(llmod);
+    }
+
     if is_pie_binary(sess) {
         llvm::LLVMRustSetModulePIELevel(llmod);
     }
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index f0148a21ae6..f1bf4511131 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -843,13 +843,13 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
         ty::Bool => ("bool", DW_ATE_boolean),
         ty::Char => ("char", DW_ATE_unsigned_char),
         ty::Int(int_ty) => {
-            (int_ty.ty_to_string(), DW_ATE_signed)
+            (int_ty.name_str(), DW_ATE_signed)
         },
         ty::Uint(uint_ty) => {
-            (uint_ty.ty_to_string(), DW_ATE_unsigned)
+            (uint_ty.name_str(), DW_ATE_unsigned)
         },
         ty::Float(float_ty) => {
-            (float_ty.ty_to_string(), DW_ATE_float)
+            (float_ty.name_str(), DW_ATE_float)
         },
         _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
     };
@@ -1904,8 +1904,8 @@ fn prepare_enum_metadata(
 
             let discr_type = match discr.value {
                 layout::Int(t, _) => t,
-                layout::Float(layout::FloatTy::F32) => Integer::I32,
-                layout::Float(layout::FloatTy::F64) => Integer::I64,
+                layout::F32 => Integer::I32,
+                layout::F64 => Integer::I64,
                 layout::Pointer => cx.data_layout().ptr_sized_integer(),
             }.to_ty(cx.tcx, false);
 
diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs
index 628d1372b57..482bcf2aa58 100644
--- a/src/librustc_codegen_llvm/debuginfo/namespace.rs
+++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs
@@ -34,11 +34,11 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
     });
 
     let namespace_name = match def_key.disambiguated_data.data {
-        DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(),
-        data => data.as_symbol().as_str()
+        DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate),
+        data => data.as_symbol()
     };
 
-    let namespace_name = SmallCStr::new(&namespace_name);
+    let namespace_name = SmallCStr::new(&namespace_name.as_str());
 
     let scope = unsafe {
         llvm::LLVMRustDIBuilderCreateNameSpace(
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 1bce34abe55..e1ce7f622e2 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -18,8 +18,8 @@ use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive};
 use rustc::mir::interpret::GlobalId;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc::hir;
-use syntax::ast::{self, FloatTy};
 use rustc_target::abi::HasDataLayout;
+use syntax::ast;
 
 use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::traits::*;
@@ -163,12 +163,12 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                                     emit_va_arg(self, args[0], ret_ty)
                                 }
                             }
-                            Primitive::Float(FloatTy::F64) |
+                            Primitive::F64 |
                             Primitive::Pointer => {
                                 emit_va_arg(self, args[0], ret_ty)
                             }
                             // `va_arg` should never be used with the return type f32.
-                            Primitive::Float(FloatTy::F32) => {
+                            Primitive::F32 => {
                                 bug!("the va_arg intrinsic does not work with `f32`")
                             }
                         }
@@ -1335,7 +1335,7 @@ fn generic_simd_intrinsic(
             },
             ty::Float(f) => {
                 return_error!("unsupported element type `{}` of floating-point vector `{}`",
-                              f, in_ty);
+                              f.name_str(), in_ty);
             },
             _ => {
                 return_error!("`{}` is not a floating-point type", in_ty);
@@ -1573,7 +1573,7 @@ fn generic_simd_intrinsic(
         // The second argument must be a simd vector with an element type that's a pointer
         // to the element type of the first argument
         let (pointer_count, underlying_ty) = match arg_tys[1].simd_type(tcx).kind {
-            ty::RawPtr(p) if p.ty == in_elem && p.mutbl == hir::MutMutable
+            ty::RawPtr(p) if p.ty == in_elem && p.mutbl == hir::Mutability::Mutable
                 => (ptr_count(arg_tys[1].simd_type(tcx)),
                     non_ptr(arg_tys[1].simd_type(tcx))),
             _ => {
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 72b0a7d640a..548e8c732a7 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1684,6 +1684,7 @@ extern "C" {
     pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
                                        CPU: *const c_char,
                                        Features: *const c_char,
+                                       Abi: *const c_char,
                                        Model: CodeModel,
                                        Reloc: RelocMode,
                                        Level: CodeGenOptLevel,
@@ -1806,6 +1807,7 @@ extern "C" {
 
     pub fn LLVMRustSetComdat(M: &'a Module, V: &'a Value, Name: *const c_char);
     pub fn LLVMRustUnsetComdat(V: &Value);
+    pub fn LLVMRustSetModulePICLevel(M: &Module);
     pub fn LLVMRustSetModulePIELevel(M: &Module);
     pub fn LLVMRustModuleBufferCreate(M: &Module) -> &'static mut ModuleBuffer;
     pub fn LLVMRustModuleBufferPtr(p: &ModuleBuffer) -> *const u8;
diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs
index 57815933af0..e49462674b3 100644
--- a/src/librustc_codegen_llvm/llvm/mod.rs
+++ b/src/librustc_codegen_llvm/llvm/mod.rs
@@ -87,6 +87,7 @@ pub struct RustString {
 }
 
 /// Appending to a Rust string -- used by RawRustStringOstream.
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString,
                                                  ptr: *const c_char,
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index dc68872ede1..c21e62e7562 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -3,7 +3,7 @@ use crate::common::*;
 use crate::type_::Type;
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::layout::{self, Align, LayoutOf, FnAbiExt, PointeeInfo, Size, TyLayout};
-use rustc_target::abi::{FloatTy, TyLayoutMethods};
+use rustc_target::abi::TyLayoutMethods;
 use rustc::ty::print::obsolete::DefPathBasedNames;
 use rustc_codegen_ssa::traits::*;
 
@@ -300,8 +300,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
                                scalar: &layout::Scalar, offset: Size) -> &'a Type {
         match scalar.value {
             layout::Int(i, _) => cx.type_from_integer( i),
-            layout::Float(FloatTy::F32) => cx.type_f32(),
-            layout::Float(FloatTy::F64) => cx.type_f64(),
+            layout::F32 => cx.type_f32(),
+            layout::F64 => cx.type_f64(),
             layout::Pointer => {
                 // If we know the alignment, pick something better than i8.
                 let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs
index 2d84d67e3c8..b8501f0e12a 100644
--- a/src/librustc_codegen_ssa/back/command.rs
+++ b/src/librustc_codegen_ssa/back/command.rs
@@ -53,7 +53,7 @@ impl Command {
     }
 
     pub fn sym_arg(&mut self, arg: Symbol) -> &mut Command {
-        self.arg(&arg.as_str());
+        self.arg(&*arg.as_str());
         self
     }
 
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 85a90459f5e..35b62603b07 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -129,9 +129,9 @@ fn reachable_non_generics_provider(
                 //
                 // In general though we won't link right if these
                 // symbols are stripped, and LTO currently strips them.
-                if &*name == "rust_eh_personality" ||
-                   &*name == "rust_eh_register_frames" ||
-                   &*name == "rust_eh_unregister_frames" {
+                if name == "rust_eh_personality" ||
+                   name == "rust_eh_register_frames" ||
+                   name == "rust_eh_unregister_frames" {
                     SymbolExportLevel::C
                 } else {
                     SymbolExportLevel::Rust
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index ee4ec7fb41e..c3f2a5161ae 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -552,8 +552,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     } else if let Some(kind) = *tcx.sess.allocator_kind.get() {
         let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
                                                        &["crate"],
-                                                       Some("allocator")).as_str()
-                                                                         .to_string();
+                                                       Some("allocator")).to_string();
         let mut modules = backend.new_metadata(tcx, &llmod_id);
         time(tcx.sess, "write allocator module", || {
             backend.codegen_allocator(tcx, &mut modules, kind)
@@ -576,8 +575,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         // Codegen the encoded metadata.
         let metadata_cgu_name = cgu_name_builder.build_cgu_name(LOCAL_CRATE,
                                                                 &["crate"],
-                                                                Some("metadata")).as_str()
-                                                                                 .to_string();
+                                                                Some("metadata")).to_string();
         let mut metadata_llvm_module = backend.new_metadata(tcx, &metadata_cgu_name);
         time(tcx.sess, "write compressed metadata", || {
             backend.write_compressed_metadata(tcx, &ongoing_codegen.metadata,
diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs
index 166a74fe487..8ff08e832dc 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs
@@ -37,9 +37,9 @@ pub fn push_debuginfo_type_name<'tcx>(
         ty::Char => output.push_str("char"),
         ty::Str => output.push_str("str"),
         ty::Never => output.push_str("!"),
-        ty::Int(int_ty) => output.push_str(int_ty.ty_to_string()),
-        ty::Uint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
-        ty::Float(float_ty) => output.push_str(float_ty.ty_to_string()),
+        ty::Int(int_ty) => output.push_str(int_ty.name_str()),
+        ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
+        ty::Float(float_ty) => output.push_str(float_ty.name_str()),
         ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
         ty::Adt(def, substs) => {
             push_item_name(tcx, def.did, qualified, output);
@@ -62,8 +62,8 @@ pub fn push_debuginfo_type_name<'tcx>(
                 output.push('*');
             }
             match mutbl {
-                hir::MutImmutable => output.push_str("const "),
-                hir::MutMutable => output.push_str("mut "),
+                hir::Mutability::Immutable => output.push_str("const "),
+                hir::Mutability::Mutable => output.push_str("mut "),
             }
 
             push_debuginfo_type_name(tcx, inner_type, true, output, visited);
@@ -76,9 +76,7 @@ pub fn push_debuginfo_type_name<'tcx>(
             if !cpp_like_names {
                 output.push('&');
             }
-            if mutbl == hir::MutMutable {
-                output.push_str("mut ");
-            }
+            output.push_str(mutbl.prefix_str());
 
             push_debuginfo_type_name(tcx, inner_type, true, output, visited);
 
@@ -140,9 +138,7 @@ pub fn push_debuginfo_type_name<'tcx>(
 
 
             let sig = t.fn_sig(tcx);
-            if sig.unsafety() == hir::Unsafety::Unsafe {
-                output.push_str("unsafe ");
-            }
+            output.push_str(sig.unsafety().prefix_str());
 
             let abi = sig.abi();
             if abi != rustc_target::spec::abi::Abi::Rust {
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index dd75883f97d..81e7ef64e97 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -59,7 +59,8 @@ pub struct ModuleCodegen<M> {
     pub kind: ModuleKind,
 }
 
-pub const METADATA_FILENAME: &str = "rust.metadata.bin";
+// FIXME(eddyb) maybe include the crate name in this?
+pub const METADATA_FILENAME: &str = "lib.rmeta";
 pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z";
 
 
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 07e904300a6..13cd202158b 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -995,7 +995,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         bx: &mut Bx,
         span: Span,
     ) -> OperandRef<'tcx, Bx::Value> {
-        let caller = bx.tcx().sess.source_map().lookup_char_pos(span.lo());
+        let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
+        let caller = bx.tcx().sess.source_map().lookup_char_pos(topmost.lo());
         let const_loc = bx.tcx().const_caller_location((
             Symbol::intern(&caller.file.name.to_string()),
             caller.line as u32,
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 1608f222bc6..981fdf22984 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -269,6 +269,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         }
                     }
                     mir::CastKind::Pointer(PointerCast::MutToConstPointer)
+                    | mir::CastKind::Pointer(PointerCast::ArrayToPointer)
                     | mir::CastKind::Misc => {
                         assert!(bx.cx().is_backend_immediate(cast));
                         let ll_t_out = bx.cx().immediate_backend_type(cast);
diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs
index 601a33a66bb..66e1b6d949e 100644
--- a/src/librustc_codegen_utils/symbol_names/legacy.rs
+++ b/src/librustc_codegen_utils/symbol_names/legacy.rs
@@ -121,9 +121,10 @@ fn get_symbol_hash<'tcx>(
         substs.hash_stable(&mut hcx, &mut hasher);
 
         if let Some(instantiating_crate) = instantiating_crate {
-            (&tcx.original_crate_name(instantiating_crate).as_str()[..])
+            tcx.original_crate_name(instantiating_crate).as_str()
+                .hash_stable(&mut hcx, &mut hasher);
+            tcx.crate_disambiguator(instantiating_crate)
                 .hash_stable(&mut hcx, &mut hasher);
-            (&tcx.crate_disambiguator(instantiating_crate)).hash_stable(&mut hcx, &mut hasher);
         }
 
         // We want to avoid accidental collision between different types of instances.
diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs
index 55b148fceb2..1dfcc21f390 100644
--- a/src/librustc_codegen_utils/symbol_names/v0.rs
+++ b/src/librustc_codegen_utils/symbol_names/v0.rs
@@ -373,8 +373,8 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
 
             ty::Ref(r, ty, mutbl) => {
                 self.push(match mutbl {
-                    hir::MutImmutable => "R",
-                    hir::MutMutable => "Q",
+                    hir::Mutability::Immutable => "R",
+                    hir::Mutability::Mutable => "Q",
                 });
                 if *r != ty::ReErased {
                     self = r.print(self)?;
@@ -384,8 +384,8 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
 
             ty::RawPtr(mt) => {
                 self.push(match mt.mutbl {
-                    hir::MutImmutable => "P",
-                    hir::MutMutable => "O",
+                    hir::Mutability::Immutable => "P",
+                    hir::Mutability::Mutable => "O",
                 });
                 self = mt.ty.print(self)?;
             }
@@ -601,8 +601,7 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
             | DefPathData::Misc
             | DefPathData::Impl
             | DefPathData::MacroNs(_)
-            | DefPathData::LifetimeNs(_)
-            | DefPathData::GlobalMetaData(_) => {
+            | DefPathData::LifetimeNs(_) => {
                 bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data)
             }
         };
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 065c8436ae0..e79b3a81b96 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -23,7 +23,7 @@ stable_deref_trait = "1.0.0"
 rayon = { version = "0.3.0", package = "rustc-rayon" }
 rayon-core = { version = "0.3.0", package = "rustc-rayon-core" }
 rustc-hash = "1.0.1"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_index = { path = "../librustc_index", package = "rustc_index" }
 
 [dependencies.parking_lot]
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index a9e4e6db1c7..f1565a2bd0a 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -21,11 +21,13 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_metadata = { path = "../librustc_metadata" }
 rustc_mir = { path = "../librustc_mir" }
+rustc_parse = { path = "../librustc_parse" }
 rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot
 rustc_plugin_impl = { path = "../librustc_plugin" }
 rustc_save_analysis = { path = "../librustc_save_analysis" }
 rustc_codegen_utils = { path = "../librustc_codegen_utils" }
 rustc_interface = { path = "../librustc_interface" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
+rustc_resolve = { path = "../librustc_resolve" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_driver/args.rs b/src/librustc_driver/args.rs
index 0906d358bad..339a10f9140 100644
--- a/src/librustc_driver/args.rs
+++ b/src/librustc_driver/args.rs
@@ -3,22 +3,12 @@ use std::fmt;
 use std::fs;
 use std::io;
 use std::str;
-use std::sync::atomic::{AtomicBool, Ordering};
-
-static USED_ARGSFILE_FEATURE: AtomicBool = AtomicBool::new(false);
-
-pub fn used_unstable_argsfile() -> bool {
-    USED_ARGSFILE_FEATURE.load(Ordering::Relaxed)
-}
 
 pub fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
     if arg.starts_with("@") {
         let path = &arg[1..];
         let file = match fs::read_to_string(path) {
-            Ok(file) => {
-                USED_ARGSFILE_FEATURE.store(true, Ordering::Relaxed);
-                file
-            }
+            Ok(file) => file,
             Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
                 return Err(Error::Utf8Error(Some(path.to_string())));
             }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 6e8bc11162f..10bc6599e75 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -25,8 +25,6 @@ extern crate lazy_static;
 
 pub extern crate rustc_plugin_impl as plugin;
 
-use pretty::{PpMode, UserIdentifiedItem};
-
 //use rustc_resolve as resolve;
 use rustc_save_analysis as save;
 use rustc_save_analysis::DumpHandler;
@@ -42,6 +40,7 @@ use rustc::ty::TyCtxt;
 use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
 use rustc_metadata::locator;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
+use errors::PResult;
 use rustc_interface::interface;
 use rustc_interface::util::get_codegen_sysroot;
 use rustc_data_structures::sync::SeqCst;
@@ -64,7 +63,6 @@ use std::time::Instant;
 use syntax::ast;
 use syntax::source_map::FileLoader;
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
-use syntax::parse::{self, PResult};
 use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, FileName};
 
@@ -284,33 +282,29 @@ pub fn run_compiler(
             return sess.compile_status();
         }
 
-        let pretty_info = parse_pretty(sess, &matches);
-
         compiler.parse()?;
 
-        if let Some((ppm, opt_uii)) = pretty_info {
+        if let Some((ppm, opt_uii)) = &sess.opts.pretty {
             if ppm.needs_ast_map(&opt_uii) {
-                pretty::visit_crate(sess, &mut compiler.parse()?.peek_mut(), ppm);
                 compiler.global_ctxt()?.peek_mut().enter(|tcx| {
                     let expanded_crate = compiler.expansion()?.take().0;
                     pretty::print_after_hir_lowering(
                         tcx,
                         compiler.input(),
                         &expanded_crate,
-                        ppm,
+                        *ppm,
                         opt_uii.clone(),
                         compiler.output_file().as_ref().map(|p| &**p),
                     );
                     Ok(())
                 })?;
             } else {
-                let mut krate = compiler.parse()?.take();
-                pretty::visit_crate(sess, &mut krate, ppm);
+                let krate = compiler.parse()?.take();
                 pretty::print_after_parsing(
                     sess,
                     &compiler.input(),
                     &krate,
-                    ppm,
+                    *ppm,
                     compiler.output_file().as_ref().map(|p| &**p),
                 );
             }
@@ -399,7 +393,7 @@ pub fn run_compiler(
         mem::drop(compiler.global_ctxt()?.take());
 
         if sess.opts.debugging_opts.print_type_sizes {
-            sess.code_stats.borrow().print_type_sizes();
+            sess.code_stats.print_type_sizes();
         }
 
         compiler.link()?;
@@ -469,28 +463,6 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option
     }
 }
 
-fn parse_pretty(sess: &Session,
-                matches: &getopts::Matches)
-                -> Option<(PpMode, Option<UserIdentifiedItem>)> {
-    let pretty = if sess.opts.debugging_opts.unstable_options {
-        matches.opt_default("pretty", "normal").map(|a| {
-            // stable pretty-print variants only
-            pretty::parse_pretty(sess, &a, false)
-        })
-    } else {
-        None
-    };
-
-    if pretty.is_none() {
-        sess.opts.debugging_opts.unpretty.as_ref().map(|a| {
-            // extended with unstable pretty-print variants
-            pretty::parse_pretty(sess, &a, true)
-        })
-    } else {
-        pretty
-    }
-}
-
 // Whether to stop or continue compilation.
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum Compilation {
@@ -1043,12 +1015,6 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
     //   (unstable option being used on stable)
     nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
 
-    // Late check to see if @file was used without unstable options enabled
-    if crate::args::used_unstable_argsfile() && !nightly_options::is_unstable_enabled(&matches) {
-        early_error(ErrorOutputType::default(),
-            "@path is unstable - use -Z unstable-options to enable its use");
-    }
-
     if matches.opt_present("h") || matches.opt_present("help") {
         // Only show unstable options in --help if we accept unstable options.
         usage(matches.opt_present("verbose"), nightly_options::is_unstable_enabled(&matches));
@@ -1095,14 +1061,16 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
 }
 
 fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<ast::Attribute>> {
-    match *input {
-        Input::File(ref ifile) => {
-            parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess)
+    match input {
+        Input::File(ifile) => {
+            rustc_parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess)
         }
-        Input::Str { ref name, ref input } => {
-            parse::parse_crate_attrs_from_source_str(name.clone(),
-                                                     input.clone(),
-                                                     &sess.parse_sess)
+        Input::Str { name, input } => {
+            rustc_parse::parse_crate_attrs_from_source_str(
+                name.clone(),
+                input.clone(),
+                &sess.parse_sess,
+            )
         }
     }
 }
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 0de5b700b4f..23253dc4dad 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -5,117 +5,27 @@ use rustc::hir::map as hir_map;
 use rustc::hir::print as pprust_hir;
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::session::Session;
-use rustc::session::config::Input;
+use rustc::session::config::{PpMode, PpSourceMode, UserIdentifiedItem, Input};
 use rustc::ty::{self, TyCtxt};
 use rustc::util::common::ErrorReported;
-use rustc_interface::util::ReplaceBodyWithLoop;
 use rustc_mir::util::{write_mir_pretty, write_mir_graphviz};
 
 use syntax::ast;
-use syntax::mut_visit::MutVisitor;
 use syntax::print::{pprust};
 use syntax_pos::FileName;
 
 use std::cell::Cell;
 use std::fs::File;
 use std::io::Write;
-use std::option;
 use std::path::Path;
-use std::str::FromStr;
 
 pub use self::UserIdentifiedItem::*;
 pub use self::PpSourceMode::*;
 pub use self::PpMode::*;
-use self::NodesMatchingUII::*;
 use crate::abort_on_err;
 
 use crate::source_name;
 
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum PpSourceMode {
-    PpmNormal,
-    PpmEveryBodyLoops,
-    PpmExpanded,
-    PpmIdentified,
-    PpmExpandedIdentified,
-    PpmExpandedHygiene,
-    PpmTyped,
-}
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum PpMode {
-    PpmSource(PpSourceMode),
-    PpmHir(PpSourceMode),
-    PpmHirTree(PpSourceMode),
-    PpmMir,
-    PpmMirCFG,
-}
-
-impl PpMode {
-    pub fn needs_ast_map(&self, opt_uii: &Option<UserIdentifiedItem>) -> bool {
-        match *self {
-            PpmSource(PpmNormal) |
-            PpmSource(PpmEveryBodyLoops) |
-            PpmSource(PpmIdentified) => opt_uii.is_some(),
-
-            PpmSource(PpmExpanded) |
-            PpmSource(PpmExpandedIdentified) |
-            PpmSource(PpmExpandedHygiene) |
-            PpmHir(_) |
-            PpmHirTree(_) |
-            PpmMir |
-            PpmMirCFG => true,
-            PpmSource(PpmTyped) => panic!("invalid state"),
-        }
-    }
-
-    pub fn needs_analysis(&self) -> bool {
-        match *self {
-            PpmMir | PpmMirCFG => true,
-            _ => false,
-        }
-    }
-}
-
-pub fn parse_pretty(sess: &Session,
-                    name: &str,
-                    extended: bool)
-                    -> (PpMode, Option<UserIdentifiedItem>) {
-    let mut split = name.splitn(2, '=');
-    let first = split.next().unwrap();
-    let opt_second = split.next();
-    let first = match (first, extended) {
-        ("normal", _) => PpmSource(PpmNormal),
-        ("identified", _) => PpmSource(PpmIdentified),
-        ("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
-        ("expanded", _) => PpmSource(PpmExpanded),
-        ("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
-        ("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
-        ("hir", true) => PpmHir(PpmNormal),
-        ("hir,identified", true) => PpmHir(PpmIdentified),
-        ("hir,typed", true) => PpmHir(PpmTyped),
-        ("hir-tree", true) => PpmHirTree(PpmNormal),
-        ("mir", true) => PpmMir,
-        ("mir-cfg", true) => PpmMirCFG,
-        _ => {
-            if extended {
-                sess.fatal(&format!("argument to `unpretty` must be one of `normal`, \
-                                     `expanded`, `identified`, `expanded,identified`, \
-                                     `expanded,hygiene`, `everybody_loops`, \
-                                     `hir`, `hir,identified`, `hir,typed`, `hir-tree`, \
-                                     `mir` or `mir-cfg`; got {}",
-                                    name));
-            } else {
-                sess.fatal(&format!("argument to `pretty` must be one of `normal`, `expanded`, \
-                                     `identified`, or `expanded,identified`; got {}",
-                                    name));
-            }
-        }
-    };
-    let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
-    (first, opt_second)
-}
-
 
 
 // This slightly awkward construction is to allow for each PpMode to
@@ -131,76 +41,74 @@ pub fn parse_pretty(sess: &Session,
 // (The `use_once_payload` is working around the current lack of once
 // functions in the compiler.)
 
-impl PpSourceMode {
-    /// Constructs a `PrinterSupport` object and passes it to `f`.
-    fn call_with_pp_support<'tcx, A, F>(
-        &self,
-        sess: &'tcx Session,
-        tcx: Option<TyCtxt<'tcx>>,
-        f: F,
-    ) -> A
-    where
-        F: FnOnce(&dyn PrinterSupport) -> A,
-    {
-        match *self {
-            PpmNormal | PpmEveryBodyLoops | PpmExpanded => {
-                let annotation = NoAnn {
-                    sess,
-                    tcx,
-                };
-                f(&annotation)
-            }
+/// Constructs a `PrinterSupport` object and passes it to `f`.
+fn call_with_pp_support<'tcx, A, F>(
+    ppmode: &PpSourceMode,
+    sess: &'tcx Session,
+    tcx: Option<TyCtxt<'tcx>>,
+    f: F,
+) -> A
+where
+    F: FnOnce(&dyn PrinterSupport) -> A,
+{
+    match *ppmode {
+        PpmNormal | PpmEveryBodyLoops | PpmExpanded => {
+            let annotation = NoAnn {
+                sess,
+                tcx,
+            };
+            f(&annotation)
+        }
 
-            PpmIdentified | PpmExpandedIdentified => {
-                let annotation = IdentifiedAnnotation {
-                    sess,
-                    tcx,
-                };
-                f(&annotation)
-            }
-            PpmExpandedHygiene => {
-                let annotation = HygieneAnnotation {
-                    sess,
-                };
-                f(&annotation)
-            }
-            _ => panic!("Should use call_with_pp_support_hir"),
+        PpmIdentified | PpmExpandedIdentified => {
+            let annotation = IdentifiedAnnotation {
+                sess,
+                tcx,
+            };
+            f(&annotation)
+        }
+        PpmExpandedHygiene => {
+            let annotation = HygieneAnnotation {
+                sess,
+            };
+            f(&annotation)
+        }
+        _ => panic!("Should use call_with_pp_support_hir"),
+    }
+}
+fn call_with_pp_support_hir<A, F>(ppmode: &PpSourceMode, tcx: TyCtxt<'_>, f: F) -> A
+where
+    F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A,
+{
+    match *ppmode {
+        PpmNormal => {
+            let annotation = NoAnn {
+                sess: tcx.sess,
+                tcx: Some(tcx),
+            };
+            f(&annotation, tcx.hir().forest.krate())
         }
-    }
-    fn call_with_pp_support_hir<A, F>(&self, tcx: TyCtxt<'_>, f: F) -> A
-    where
-        F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A,
-    {
-        match *self {
-            PpmNormal => {
-                let annotation = NoAnn {
-                    sess: tcx.sess,
-                    tcx: Some(tcx),
-                };
-                f(&annotation, tcx.hir().forest.krate())
-            }
 
-            PpmIdentified => {
-                let annotation = IdentifiedAnnotation {
-                    sess: tcx.sess,
-                    tcx: Some(tcx),
-                };
+        PpmIdentified => {
+            let annotation = IdentifiedAnnotation {
+                sess: tcx.sess,
+                tcx: Some(tcx),
+            };
+            f(&annotation, tcx.hir().forest.krate())
+        }
+        PpmTyped => {
+            abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess);
+
+            let empty_tables = ty::TypeckTables::empty(None);
+            let annotation = TypedAnnotation {
+                tcx,
+                tables: Cell::new(&empty_tables)
+            };
+            tcx.dep_graph.with_ignore(|| {
                 f(&annotation, tcx.hir().forest.krate())
-            }
-            PpmTyped => {
-                abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess);
-
-                let empty_tables = ty::TypeckTables::empty(None);
-                let annotation = TypedAnnotation {
-                    tcx,
-                    tables: Cell::new(&empty_tables)
-                };
-                tcx.dep_graph.with_ignore(|| {
-                    f(&annotation, tcx.hir().forest.krate())
-                })
-            }
-            _ => panic!("Should use call_with_pp_support"),
+            })
         }
+        _ => panic!("Should use call_with_pp_support"),
     }
 }
 
@@ -482,102 +390,6 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
     }
 }
 
-#[derive(Clone, Debug)]
-pub enum UserIdentifiedItem {
-    ItemViaNode(ast::NodeId),
-    ItemViaPath(Vec<String>),
-}
-
-impl FromStr for UserIdentifiedItem {
-    type Err = ();
-    fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
-        Ok(s.parse()
-            .map(ast::NodeId::from_u32)
-            .map(ItemViaNode)
-            .unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect())))
-    }
-}
-
-enum NodesMatchingUII<'a> {
-    NodesMatchingDirect(option::IntoIter<ast::NodeId>),
-    NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
-}
-
-impl<'a> Iterator for NodesMatchingUII<'a> {
-    type Item = ast::NodeId;
-
-    fn next(&mut self) -> Option<ast::NodeId> {
-        match self {
-            &mut NodesMatchingDirect(ref mut iter) => iter.next(),
-            &mut NodesMatchingSuffix(ref mut iter) => iter.next(),
-        }
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        match self {
-            &NodesMatchingDirect(ref iter) => iter.size_hint(),
-            &NodesMatchingSuffix(ref iter) => iter.size_hint(),
-        }
-    }
-}
-
-impl UserIdentifiedItem {
-    fn reconstructed_input(&self) -> String {
-        match *self {
-            ItemViaNode(node_id) => node_id.to_string(),
-            ItemViaPath(ref parts) => parts.join("::"),
-        }
-    }
-
-    fn all_matching_node_ids<'a, 'hir>(&'a self,
-                                       map: &'a hir_map::Map<'hir>)
-                                       -> NodesMatchingUII<'a> {
-        match *self {
-            ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
-            ItemViaPath(ref parts) => {
-                NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts)))
-            }
-        }
-    }
-
-    fn to_one_node_id(self,
-                      user_option: &str,
-                      sess: &Session,
-                      map: &hir_map::Map<'_>)
-                      -> ast::NodeId {
-        let fail_because = |is_wrong_because| -> ast::NodeId {
-            let message = format!("{} needs NodeId (int) or unique path suffix (b::c::d); got \
-                                   {}, which {}",
-                                  user_option,
-                                  self.reconstructed_input(),
-                                  is_wrong_because);
-            sess.fatal(&message)
-        };
-
-        let mut saw_node = ast::DUMMY_NODE_ID;
-        let mut seen = 0;
-        for node in self.all_matching_node_ids(map) {
-            saw_node = node;
-            seen += 1;
-            if seen > 1 {
-                fail_because("does not resolve uniquely");
-            }
-        }
-        if seen == 0 {
-            fail_because("does not resolve to any item");
-        }
-
-        assert!(seen == 1);
-        return saw_node;
-    }
-}
-
-pub fn visit_crate(sess: &Session, krate: &mut ast::Crate, ppm: PpMode) {
-    if let PpmSource(PpmEveryBodyLoops) = ppm {
-        ReplaceBodyWithLoop::new(sess).visit_crate(krate);
-    }
-}
-
 fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
     let src_name = source_name(input);
     let src = String::clone(&sess.source_map()
@@ -613,7 +425,7 @@ pub fn print_after_parsing(sess: &Session,
     if let PpmSource(s) = ppm {
         // Silently ignores an identified node.
         let out = &mut out;
-        s.call_with_pp_support(sess, None, move |annotation| {
+        call_with_pp_support(&s, sess, None, move |annotation| {
             debug!("pretty printing source code {:?}", s);
             let sess = annotation.sess();
             *out = pprust::print_crate(sess.source_map(),
@@ -658,7 +470,7 @@ pub fn print_after_hir_lowering<'tcx>(
                 // Silently ignores an identified node.
                 let out = &mut out;
                 let src = src.clone();
-                s.call_with_pp_support(tcx.sess, Some(tcx), move |annotation| {
+                call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
                     *out = pprust::print_crate(sess.source_map(),
@@ -674,7 +486,7 @@ pub fn print_after_hir_lowering<'tcx>(
             (PpmHir(s), None) => {
                 let out = &mut out;
                 let src = src.clone();
-                s.call_with_pp_support_hir(tcx, move |annotation, krate| {
+                call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
                     *out = pprust_hir::print_crate(sess.source_map(),
@@ -688,7 +500,7 @@ pub fn print_after_hir_lowering<'tcx>(
 
             (PpmHirTree(s), None) => {
                 let out = &mut out;
-                s.call_with_pp_support_hir(tcx, move |_annotation, krate| {
+                call_with_pp_support_hir(&s, tcx, move |_annotation, krate| {
                     debug!("pretty printing source code {:?}", s);
                     *out = format!("{:#?}", krate);
                 });
@@ -697,7 +509,7 @@ pub fn print_after_hir_lowering<'tcx>(
             (PpmHir(s), Some(uii)) => {
                 let out = &mut out;
                 let src = src.clone();
-                s.call_with_pp_support_hir(tcx, move |annotation, _| {
+                call_with_pp_support_hir(&s, tcx, move |annotation, _| {
                     debug!("pretty printing source code {:?}", s);
                     let sess = annotation.sess();
                     let hir_map = annotation.hir_map().expect("-Z unpretty missing HIR map");
@@ -722,7 +534,7 @@ pub fn print_after_hir_lowering<'tcx>(
 
             (PpmHirTree(s), Some(uii)) => {
                 let out = &mut out;
-                s.call_with_pp_support_hir(tcx, move |_annotation, _krate| {
+                call_with_pp_support_hir(&s, tcx, move |_annotation, _krate| {
                     debug!("pretty printing source code {:?}", s);
                     for node_id in uii.all_matching_node_ids(tcx.hir()) {
                         let hir_id = tcx.hir().node_to_hir_id(node_id);
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index b153f0f0e82..291920f17f6 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -12,7 +12,7 @@ use Destination::*;
 use syntax_pos::{SourceFile, Span, MultiSpan};
 
 use crate::{
-    Level, CodeSuggestion, Diagnostic, SubDiagnostic, pluralise,
+    Level, CodeSuggestion, Diagnostic, SubDiagnostic, pluralize,
     SuggestionStyle, SourceMapper, SourceMapperDyn, DiagnosticId,
 };
 use crate::Level::Error;
@@ -424,6 +424,14 @@ impl Emitter for EmitterWriter {
     }
 }
 
+/// An emitter that does nothing when emitting a diagnostic.
+pub struct SilentEmitter;
+
+impl Emitter for SilentEmitter {
+    fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> { None }
+    fn emit_diagnostic(&mut self, _: &Diagnostic) {}
+}
+
 /// maximum number of lines we will print for each error; arbitrary.
 pub const MAX_HIGHLIGHT_LINES: usize = 6;
 /// maximum number of suggestions to be shown
@@ -1573,7 +1581,7 @@ impl EmitterWriter {
         }
         if suggestions.len() > MAX_SUGGESTIONS {
             let others = suggestions.len() - MAX_SUGGESTIONS;
-            let msg = format!("and {} other candidate{}", others, pluralise!(others));
+            let msg = format!("and {} other candidate{}", others, pluralize!(others));
             buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
         } else if notice_capitalization {
             let msg = "notice the capitalization difference";
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 9743cf0d805..8ee28875c62 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -15,7 +15,6 @@ use Level::*;
 
 use emitter::{Emitter, EmitterWriter, is_case_difference};
 use registry::Registry;
-
 use rustc_data_structures::sync::{self, Lrc, Lock};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::stable_hasher::StableHasher;
@@ -48,6 +47,13 @@ use syntax_pos::{
     SpanSnippetError,
 };
 
+pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
+
+// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
+// (See also the comment on `DiagnosticBuilderInner`.)
+#[cfg(target_arch = "x86_64")]
+rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
+
 /// Indicates the confidence in the correctness of a suggestion.
 ///
 /// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
@@ -1027,7 +1033,7 @@ impl Level {
 }
 
 #[macro_export]
-macro_rules! pluralise {
+macro_rules! pluralize {
     ($x:expr) => {
         if $x != 1 { "s" } else { "" }
     };
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index ca035d0cdcb..483b515f2ba 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -31,10 +31,6 @@ use syntax::symbol::{Symbol, sym};
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
                  ATTR_EXPECTED_CGU_REUSE};
 
-const MODULE: Symbol = sym::module;
-const CFG: Symbol = sym::cfg;
-const KIND: Symbol = sym::kind;
-
 pub fn assert_module_sources(tcx: TyCtxt<'_>) {
     tcx.dep_graph.with_ignore(|| {
         if tcx.sess.opts.incremental.is_none() {
@@ -71,7 +67,7 @@ impl AssertModuleSource<'tcx> {
         } else if attr.check_name(ATTR_PARTITION_CODEGENED) {
             (CguReuse::No, ComparisonKind::Exact)
         } else if attr.check_name(ATTR_EXPECTED_CGU_REUSE) {
-            match &self.field(attr, KIND).as_str()[..] {
+            match &*self.field(attr, sym::kind).as_str() {
                 "no" => (CguReuse::No, ComparisonKind::Exact),
                 "pre-lto" => (CguReuse::PreLto, ComparisonKind::Exact),
                 "post-lto" => (CguReuse::PostLto, ComparisonKind::Exact),
@@ -98,8 +94,8 @@ impl AssertModuleSource<'tcx> {
             return;
         }
 
-        let user_path = self.field(attr, MODULE).as_str().to_string();
-        let crate_name = self.tcx.crate_name(LOCAL_CRATE).as_str().to_string();
+        let user_path = self.field(attr, sym::module).to_string();
+        let crate_name = self.tcx.crate_name(LOCAL_CRATE).to_string();
 
         if !user_path.starts_with(&crate_name) {
             let msg = format!("Found malformed codegen unit name `{}`. \
@@ -125,7 +121,7 @@ impl AssertModuleSource<'tcx> {
                                                        cgu_path_components,
                                                        cgu_special_suffix);
 
-        debug!("mapping '{}' to cgu name '{}'", self.field(attr, MODULE), cgu_name);
+        debug!("mapping '{}' to cgu name '{}'", self.field(attr, sym::module), cgu_name);
 
         if !self.available_cgus.contains(&cgu_name) {
             self.tcx.sess.span_err(attr.span,
@@ -135,7 +131,7 @@ impl AssertModuleSource<'tcx> {
                     cgu_name,
                     self.available_cgus
                         .iter()
-                        .map(|cgu| cgu.as_str().to_string())
+                        .map(|cgu| cgu.to_string())
                         .collect::<Vec<_>>()
                         .join(", ")));
         }
@@ -169,7 +165,7 @@ impl AssertModuleSource<'tcx> {
     /// cfg flag called `foo`.
     fn check_config(&self, attr: &ast::Attribute) -> bool {
         let config = &self.tcx.sess.parse_sess.config;
-        let value = self.field(attr, CFG);
+        let value = self.field(attr, sym::cfg);
         debug!("check_config(config={:?}, value={:?})", config, value);
         if config.iter().any(|&(name, _)| name == value) {
             debug!("check_config: matched");
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index abe0ffb0e02..ea156a94ea1 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -303,7 +303,7 @@ impl DirtyCleanVisitor<'tcx> {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
             if item.check_name(LABEL) {
                 let value = expect_associated_value(self.tcx, &item);
-                return Some(self.resolve_labels(&item, value.as_str().as_ref()));
+                return Some(self.resolve_labels(&item, &value.as_str()));
             }
         }
         None
@@ -314,7 +314,7 @@ impl DirtyCleanVisitor<'tcx> {
         for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
             if item.check_name(EXCEPT) {
                 let value = expect_associated_value(self.tcx, &item);
-                return self.resolve_labels(&item, value.as_str().as_ref());
+                return self.resolve_labels(&item, &value.as_str());
             }
         }
         // if no `label` or `except` is given, only the node's group are asserted
diff --git a/src/librustc_index/Cargo.toml b/src/librustc_index/Cargo.toml
index b1ebc95e488..1435297f27a 100644
--- a/src/librustc_index/Cargo.toml
+++ b/src/librustc_index/Cargo.toml
@@ -11,4 +11,4 @@ doctest = false
 
 [dependencies]
 rustc_serialize = { path = "../libserialize", package = "serialize" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index 0d8d765a572..de59882bbdf 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -12,10 +12,11 @@ doctest = false
 [dependencies]
 log = "0.4"
 rayon = { version = "0.3.0", package = "rustc-rayon" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_expand = { path = "../libsyntax_expand" }
+rustc_parse = { path = "../librustc_parse" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 rustc = { path = "../librustc" }
@@ -27,7 +28,6 @@ rustc_codegen_utils = { path = "../librustc_codegen_utils" }
 rustc_metadata = { path = "../librustc_metadata" }
 rustc_mir = { path = "../librustc_mir" }
 rustc_passes = { path = "../librustc_passes" }
-rustc_target = { path = "../librustc_target" }
 rustc_typeck = { path = "../librustc_typeck" }
 rustc_lint = { path = "../librustc_lint" }
 rustc_errors = { path = "../librustc_errors" }
@@ -36,3 +36,6 @@ rustc_privacy = { path = "../librustc_privacy" }
 rustc_resolve = { path = "../librustc_resolve" }
 tempfile = "3.0.5"
 once_cell = "1"
+
+[dev-dependencies]
+rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index e014e4ed0fd..02068b2ce38 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -11,16 +11,16 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::OnDrop;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+use rustc_parse::new_parser_from_source_str;
 use std::path::PathBuf;
 use std::result;
 use std::sync::{Arc, Mutex};
-use syntax::{self, parse};
 use syntax::ast::{self, MetaItemKind};
-use syntax::parse::token;
-use syntax::source_map::{FileName, FilePathMapping, FileLoader, SourceMap};
+use syntax::token;
+use syntax::source_map::{FileName, FileLoader, SourceMap};
 use syntax::sess::ParseSess;
+use syntax_expand::config::process_configure_mod;
 use syntax_pos::edition;
-use rustc_errors::{Diagnostic, emitter::Emitter, Handler, SourceMapperDyn};
 
 pub type Result<T> = result::Result<T, ErrorReported>;
 
@@ -63,20 +63,11 @@ impl Compiler {
 
 /// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
 pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
-    struct NullEmitter;
-    impl Emitter for NullEmitter {
-        fn emit_diagnostic(&mut self, _: &Diagnostic) {}
-        fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> { None }
-    }
-
     syntax::with_default_globals(move || {
         let cfg = cfgspecs.into_iter().map(|s| {
-
-            let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-            let handler = Handler::with_emitter(false, None, Box::new(NullEmitter));
-            let sess = ParseSess::with_span_handler(handler, cm);
+            let sess = ParseSess::with_silent_emitter(process_configure_mod);
             let filename = FileName::cfg_spec_source_code(&s);
-            let mut parser = parse::new_parser_from_source_str(&sess, filename, s.to_string());
+            let mut parser = new_parser_from_source_str(&sess, filename, s.to_string());
 
             macro_rules! error {($reason: expr) => {
                 early_error(ErrorOutputType::default(),
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 52332744d1a..453007c5642 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -16,15 +16,18 @@ use rustc::traits;
 use rustc::util::common::{time, ErrorReported};
 use rustc::session::Session;
 use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType};
+use rustc::session::config::{PpMode, PpSourceMode};
 use rustc::session::search_paths::PathKind;
 use rustc_codegen_ssa::back::link::emit_metadata;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_codegen_utils::link::filename_for_metadata;
 use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
 use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
+use rustc_errors::PResult;
 use rustc_incremental;
 use rustc_metadata::cstore;
 use rustc_mir as mir;
+use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
 use rustc_passes::{self, ast_validation, hir_stats, layout_test};
 use rustc_plugin as plugin;
 use rustc_plugin::registry::Registry;
@@ -36,7 +39,6 @@ use syntax::{self, ast, visit};
 use syntax::early_buffered_lints::BufferedEarlyLint;
 use syntax_expand::base::{NamedSyntaxExtension, ExtCtxt};
 use syntax::mut_visit::MutVisitor;
-use syntax::parse::{self, PResult};
 use syntax::util::node_count::NodeCounter;
 use syntax::symbol::Symbol;
 use syntax_pos::FileName;
@@ -59,12 +61,11 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
     let krate = time(sess, "parsing", || {
         let _prof_timer = sess.prof.generic_activity("parse_crate");
 
-        match *input {
-            Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess),
-            Input::Str {
-                ref input,
-                ref name,
-            } => parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess),
+        match input {
+            Input::File(file) => parse_crate_from_file(file, &sess.parse_sess),
+            Input::Str { input, name } => {
+                parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
+            }
         }
     })?;
 
@@ -180,7 +181,7 @@ pub fn register_plugins<'a>(
         )
     });
 
-    let (krate, features) = syntax::config::features(
+    let (krate, features) = syntax_expand::config::features(
         krate,
         &sess.parse_sess,
         sess.edition(),
@@ -393,8 +394,12 @@ fn configure_and_expand_inner<'a>(
 
     // If we're actually rustdoc then there's no need to actually compile
     // anything, so switch everything to just looping
-    if sess.opts.actually_rustdoc {
-        util::ReplaceBodyWithLoop::new(sess).visit_crate(&mut krate);
+    let mut should_loop = sess.opts.actually_rustdoc;
+    if let Some((PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops), _)) = sess.opts.pretty {
+        should_loop |= true;
+    }
+    if should_loop {
+        util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
     }
 
     let has_proc_macro_decls = time(sess, "AST validation", || {
@@ -483,7 +488,7 @@ pub fn lower_to_hir(
 ) -> Result<hir::map::Forest> {
     // Lower AST to HIR.
     let hir_forest = time(sess, "lowering AST -> HIR", || {
-        let nt_to_tokenstream = syntax::parse::nt_to_tokenstream;
+        let nt_to_tokenstream = rustc_parse::nt_to_tokenstream;
         let hir_crate = lower_crate(sess, &dep_graph, &krate, resolver, nt_to_tokenstream);
 
         if sess.opts.debugging_opts.hir_stats {
diff --git a/src/librustc_interface/tests.rs b/src/librustc_interface/tests.rs
index 7a57605da58..8c1dac21576 100644
--- a/src/librustc_interface/tests.rs
+++ b/src/librustc_interface/tests.rs
@@ -8,7 +8,7 @@ use rustc::session::config::{build_configuration, build_session_options, to_crat
 use rustc::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
 use rustc::session::config::{Externs, OutputType, OutputTypes, SymbolManglingVersion};
 use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes};
-use rustc::session::build_session;
+use rustc::session::{build_session, Session};
 use rustc::session::search_paths::SearchPath;
 use std::collections::{BTreeMap, BTreeSet};
 use std::iter::FromIterator;
@@ -17,16 +17,23 @@ use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel};
 use syntax::symbol::sym;
 use syntax::edition::{Edition, DEFAULT_EDITION};
 use syntax;
+use syntax_expand::config::process_configure_mod;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{ColorConfig, emitter::HumanReadableErrorType, registry};
 
-pub fn build_session_options_and_crate_config(
-    matches: &getopts::Matches,
-) -> (Options, FxHashSet<(String, Option<String>)>) {
-    (
-        build_session_options(matches),
-        parse_cfgspecs(matches.opt_strs("cfg")),
-    )
+type CfgSpecs = FxHashSet<(String, Option<String>)>;
+
+fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options, CfgSpecs) {
+    let sessopts = build_session_options(&matches);
+    let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
+    (sessopts, cfg)
+}
+
+fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
+    let registry = registry::Registry::new(&[]);
+    let (sessopts, cfg) = build_session_options_and_crate_config(matches);
+    let sess = build_session(sessopts, None, registry, process_configure_mod);
+    (sess, cfg)
 }
 
 fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
@@ -59,31 +66,19 @@ fn mk_map<K: Ord, V>(entries: Vec<(K, V)>) -> BTreeMap<K, V> {
 #[test]
 fn test_switch_implies_cfg_test() {
     syntax::with_default_globals(|| {
-        let matches = &match optgroups().parse(&["--test".to_string()]) {
-            Ok(m) => m,
-            Err(f) => panic!("test_switch_implies_cfg_test: {}", f),
-        };
-        let registry = registry::Registry::new(&[]);
-        let (sessopts, cfg) = build_session_options_and_crate_config(matches);
-        let sess = build_session(sessopts, None, registry);
+        let matches = optgroups().parse(&["--test".to_string()]).unwrap();
+        let (sess, cfg) = mk_session(matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
         assert!(cfg.contains(&(sym::test, None)));
     });
 }
 
-// When the user supplies --test and --cfg test, don't implicitly add
-// another --cfg test
+// When the user supplies --test and --cfg test, don't implicitly add another --cfg test
 #[test]
 fn test_switch_implies_cfg_test_unless_cfg_test() {
     syntax::with_default_globals(|| {
-        let matches = &match optgroups().parse(&["--test".to_string(),
-                                                 "--cfg=test".to_string()]) {
-            Ok(m) => m,
-            Err(f) => panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f),
-        };
-        let registry = registry::Registry::new(&[]);
-        let (sessopts, cfg) = build_session_options_and_crate_config(matches);
-        let sess = build_session(sessopts, None, registry);
+        let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
+        let (sess, cfg) = mk_session(matches);
         let cfg = build_configuration(&sess, to_crate_config(cfg));
         let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
         assert!(test_items.next().is_some());
@@ -95,9 +90,7 @@ fn test_switch_implies_cfg_test_unless_cfg_test() {
 fn test_can_print_warnings() {
     syntax::with_default_globals(|| {
         let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
-        let registry = registry::Registry::new(&[]);
-        let (sessopts, _) = build_session_options_and_crate_config(&matches);
-        let sess = build_session(sessopts, None, registry);
+        let (sess, _) = mk_session(matches);
         assert!(!sess.diagnostic().can_emit_warnings());
     });
 
@@ -105,17 +98,13 @@ fn test_can_print_warnings() {
         let matches = optgroups()
             .parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()])
             .unwrap();
-        let registry = registry::Registry::new(&[]);
-        let (sessopts, _) = build_session_options_and_crate_config(&matches);
-        let sess = build_session(sessopts, None, registry);
+        let (sess, _) = mk_session(matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 
     syntax::with_default_globals(|| {
         let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
-        let registry = registry::Registry::new(&[]);
-        let (sessopts, _) = build_session_options_and_crate_config(&matches);
-        let sess = build_session(sessopts, None, registry);
+        let (sess, _) = mk_session(matches);
         assert!(sess.diagnostic().can_emit_warnings());
     });
 }
@@ -704,6 +693,6 @@ fn test_edition_parsing() {
     let matches = optgroups()
         .parse(&["--edition=2018".to_string()])
         .unwrap();
-    let (sessopts, _) = build_session_options_and_crate_config(&matches);
+    let (sessopts, _) = build_session_options_and_crate_config(matches);
     assert!(sessopts.edition == Edition::Edition2018)
 }
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index d0c15073f16..115345955ae 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -18,7 +18,7 @@ use rustc_mir;
 use rustc_passes;
 use rustc_plugin;
 use rustc_privacy;
-use rustc_resolve;
+use rustc_resolve::{self, Resolver};
 use rustc_typeck;
 use std::env;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
@@ -36,6 +36,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::source_map::{FileLoader, RealFileLoader, SourceMap};
 use syntax::symbol::{Symbol, sym};
 use syntax::{self, ast, attr};
+use syntax_expand::config::process_configure_mod;
 use syntax_pos::edition::Edition;
 #[cfg(not(parallel_compiler))]
 use std::{thread, panic};
@@ -49,6 +50,7 @@ pub fn diagnostics_registry() -> Registry {
     // FIXME: need to figure out a way to get these back in here
     // all_errors.extend_from_slice(get_codegen_backend(sess).diagnostics());
     all_errors.extend_from_slice(&rustc_metadata::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_parse::error_codes::DIAGNOSTICS);
     all_errors.extend_from_slice(&rustc_passes::error_codes::DIAGNOSTICS);
     all_errors.extend_from_slice(&rustc_plugin::error_codes::DIAGNOSTICS);
     all_errors.extend_from_slice(&rustc_mir::error_codes::DIAGNOSTICS);
@@ -103,6 +105,7 @@ pub fn create_session(
         source_map.clone(),
         diagnostic_output,
         lint_caps,
+        process_configure_mod,
     );
 
     let codegen_backend = get_codegen_backend(&sess);
@@ -715,18 +718,18 @@ pub fn build_output_filenames(
 //    ambitious form of the closed RFC #1637. See also [#34511].
 //
 // [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401
-pub struct ReplaceBodyWithLoop<'a> {
+pub struct ReplaceBodyWithLoop<'a, 'b> {
     within_static_or_const: bool,
     nested_blocks: Option<Vec<ast::Block>>,
-    sess: &'a Session,
+    resolver: &'a mut Resolver<'b>,
 }
 
-impl<'a> ReplaceBodyWithLoop<'a> {
-    pub fn new(sess: &'a Session) -> ReplaceBodyWithLoop<'a> {
+impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
+    pub fn new(resolver: &'a mut Resolver<'b>) -> ReplaceBodyWithLoop<'a, 'b> {
         ReplaceBodyWithLoop {
             within_static_or_const: false,
             nested_blocks: None,
-            sess
+            resolver,
         }
     }
 
@@ -786,14 +789,18 @@ impl<'a> ReplaceBodyWithLoop<'a> {
             false
         }
     }
+
+    fn is_sig_const(sig: &ast::FnSig) -> bool {
+        sig.header.constness.node == ast::Constness::Const ||
+            ReplaceBodyWithLoop::should_ignore_fn(&sig.decl)
+    }
 }
 
-impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
+impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
     fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
         let is_const = match i {
             ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
-            ast::ItemKind::Fn(ref decl, ref header, _, _) =>
-                header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
+            ast::ItemKind::Fn(ref sig, _, _) => Self::is_sig_const(sig),
             _ => false,
         };
         self.run(is_const, |s| noop_visit_item_kind(i, s))
@@ -802,8 +809,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
     fn flat_map_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
         let is_const = match i.kind {
             ast::TraitItemKind::Const(..) => true,
-            ast::TraitItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) =>
-                header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
+            ast::TraitItemKind::Method(ref sig, _) => Self::is_sig_const(sig),
             _ => false,
         };
         self.run(is_const, |s| noop_flat_map_trait_item(i, s))
@@ -812,8 +818,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
     fn flat_map_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
         let is_const = match i.kind {
             ast::ImplItemKind::Const(..) => true,
-            ast::ImplItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) =>
-                header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
+            ast::ImplItemKind::Method(ref sig, _) => Self::is_sig_const(sig),
             _ => false,
         };
         self.run(is_const, |s| noop_flat_map_impl_item(i, s))
@@ -826,40 +831,40 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
     fn visit_block(&mut self, b: &mut P<ast::Block>) {
         fn stmt_to_block(rules: ast::BlockCheckMode,
                          s: Option<ast::Stmt>,
-                         sess: &Session) -> ast::Block {
+                         resolver: &mut Resolver<'_>) -> ast::Block {
             ast::Block {
                 stmts: s.into_iter().collect(),
                 rules,
-                id: sess.next_node_id(),
+                id: resolver.next_node_id(),
                 span: syntax_pos::DUMMY_SP,
             }
         }
 
-        fn block_to_stmt(b: ast::Block, sess: &Session) -> ast::Stmt {
+        fn block_to_stmt(b: ast::Block, resolver: &mut Resolver<'_>) -> ast::Stmt {
             let expr = P(ast::Expr {
-                id: sess.next_node_id(),
+                id: resolver.next_node_id(),
                 kind: ast::ExprKind::Block(P(b), None),
                 span: syntax_pos::DUMMY_SP,
                 attrs: ThinVec::new(),
             });
 
             ast::Stmt {
-                id: sess.next_node_id(),
+                id: resolver.next_node_id(),
                 kind: ast::StmtKind::Expr(expr),
                 span: syntax_pos::DUMMY_SP,
             }
         }
 
-        let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.sess);
+        let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver);
         let loop_expr = P(ast::Expr {
             kind: ast::ExprKind::Loop(P(empty_block), None),
-            id: self.sess.next_node_id(),
+            id: self.resolver.next_node_id(),
             span: syntax_pos::DUMMY_SP,
                 attrs: ThinVec::new(),
         });
 
         let loop_stmt = ast::Stmt {
-            id: self.sess.next_node_id(),
+            id: self.resolver.next_node_id(),
             span: syntax_pos::DUMMY_SP,
             kind: ast::StmtKind::Expr(loop_expr),
         };
@@ -877,7 +882,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
                     // we put a Some in there earlier with that replace(), so this is valid
                     let new_blocks = self.nested_blocks.take().unwrap();
                     self.nested_blocks = old_blocks;
-                    stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, &self.sess)));
+                    stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver)));
                 }
 
                 let mut new_block = ast::Block {
@@ -891,7 +896,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
                         old_blocks.push(new_block);
                     }
 
-                    stmt_to_block(b.rules, Some(loop_stmt), self.sess)
+                    stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver)
                 } else {
                     //push `loop {}` onto the end of our fresh block and yield that
                     new_block.stmts.push(loop_stmt);
diff --git a/src/librustc_lexer/src/cursor.rs b/src/librustc_lexer/src/cursor.rs
index 73d305c6d4f..ed0911379c4 100644
--- a/src/librustc_lexer/src/cursor.rs
+++ b/src/librustc_lexer/src/cursor.rs
@@ -41,10 +41,20 @@ impl<'a> Cursor<'a> {
     /// If requested position doesn't exist, `EOF_CHAR` is returned.
     /// However, getting `EOF_CHAR` doesn't always mean actual end of file,
     /// it should be checked with `is_eof` method.
-    pub(crate) fn nth_char(&self, n: usize) -> char {
+    fn nth_char(&self, n: usize) -> char {
         self.chars().nth(n).unwrap_or(EOF_CHAR)
     }
 
+    /// Peeks the next symbol from the input stream without consuming it.
+    pub(crate) fn first(&self) -> char {
+        self.nth_char(0)
+    }
+
+    /// Peeks the second symbol from the input stream without consuming it.
+    pub(crate) fn second(&self) -> char {
+        self.nth_char(1)
+    }
+
     /// Checks if there is nothing more to consume.
     pub(crate) fn is_eof(&self) -> bool {
         self.chars.as_str().is_empty()
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index d55ef46d750..3cecb4317b1 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -1,7 +1,7 @@
 //! Low-level Rust lexer.
 //!
 //! Tokens produced by this lexer are not yet ready for parsing the Rust syntax,
-//! for that see `libsyntax::parse::lexer`, which converts this basic token stream
+//! for that see `librustc_parse::lexer`, which converts this basic token stream
 //! into wide tokens used by actual parser.
 //!
 //! The purpose of this crate is to convert raw sources into a labeled sequence
@@ -18,6 +18,8 @@ mod cursor;
 pub mod unescape;
 
 use crate::cursor::{Cursor, EOF_CHAR};
+use self::TokenKind::*;
+use self::LiteralKind::*;
 
 /// Parsed token.
 /// It doesn't contain information about data that has been parsed,
@@ -116,7 +118,6 @@ pub enum TokenKind {
     /// Unknown token, not expected by the lexer, e.g. "№"
     Unknown,
 }
-use self::TokenKind::*;
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum LiteralKind {
@@ -137,7 +138,6 @@ pub enum LiteralKind {
     /// "br"abc"", "br#"abc"#", "br####"ab"###"c"####", "br#"a"
     RawByteStr { n_hashes: usize, started: bool, terminated: bool },
 }
-use self::LiteralKind::*;
 
 /// Base of numeric literal encoding according to its prefix.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -241,14 +241,13 @@ pub fn is_id_continue(c: char) -> bool {
         || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
 }
 
-
 impl Cursor<'_> {
     /// Parses a token from the input string.
     fn advance_token(&mut self) -> Token {
         let first_char = self.bump().unwrap();
         let token_kind = match first_char {
             // Slash, comment or block comment.
-            '/' => match self.nth_char(0) {
+            '/' => match self.first() {
                 '/' => self.line_comment(),
                 '*' => self.block_comment(),
                 _ => Slash,
@@ -257,8 +256,8 @@ impl Cursor<'_> {
             // Whitespace sequence.
             c if is_whitespace(c) => self.whitespace(),
 
-            // Raw string literal or identifier.
-            'r' => match (self.nth_char(0), self.nth_char(1)) {
+            // Raw identifier, raw string literal or identifier.
+            'r' => match (self.first(), self.second()) {
                 ('#', c1) if is_id_start(c1) => self.raw_ident(),
                 ('#', _) | ('"', _) => {
                     let (n_hashes, started, terminated) = self.raw_double_quoted_string();
@@ -273,7 +272,7 @@ impl Cursor<'_> {
             },
 
             // Byte literal, byte string literal, raw byte string literal or identifier.
-            'b' => match (self.nth_char(0), self.nth_char(1)) {
+            'b' => match (self.first(), self.second()) {
                 ('\'', _) => {
                     self.bump();
                     let terminated = self.single_quoted_string();
@@ -366,31 +365,23 @@ impl Cursor<'_> {
     }
 
     fn line_comment(&mut self) -> TokenKind {
-        debug_assert!(self.prev() == '/' && self.nth_char(0) == '/');
+        debug_assert!(self.prev() == '/' && self.first() == '/');
         self.bump();
-        loop {
-            match self.nth_char(0) {
-                '\n' => break,
-                EOF_CHAR if self.is_eof() => break,
-                _ => {
-                    self.bump();
-                }
-            }
-        }
+        self.eat_while(|c| c != '\n');
         LineComment
     }
 
     fn block_comment(&mut self) -> TokenKind {
-        debug_assert!(self.prev() == '/' && self.nth_char(0) == '*');
+        debug_assert!(self.prev() == '/' && self.first() == '*');
         self.bump();
         let mut depth = 1usize;
         while let Some(c) = self.bump() {
             match c {
-                '/' if self.nth_char(0) == '*' => {
+                '/' if self.first() == '*' => {
                     self.bump();
                     depth += 1;
                 }
-                '*' if self.nth_char(0) == '/' => {
+                '*' if self.first() == '/' => {
                     self.bump();
                     depth -= 1;
                     if depth == 0 {
@@ -409,31 +400,27 @@ impl Cursor<'_> {
 
     fn whitespace(&mut self) -> TokenKind {
         debug_assert!(is_whitespace(self.prev()));
-        while is_whitespace(self.nth_char(0)) {
-            self.bump();
-        }
+        self.eat_while(is_whitespace);
         Whitespace
     }
 
     fn raw_ident(&mut self) -> TokenKind {
         debug_assert!(
             self.prev() == 'r'
-                && self.nth_char(0) == '#'
-                && is_id_start(self.nth_char(1))
+                && self.first() == '#'
+                && is_id_start(self.second())
         );
+        // Eat "#" symbol.
         self.bump();
-        self.bump();
-        while is_id_continue(self.nth_char(0)) {
-            self.bump();
-        }
+        // Eat the identifier part of RawIdent.
+        self.eat_identifier();
         RawIdent
     }
 
     fn ident(&mut self) -> TokenKind {
         debug_assert!(is_id_start(self.prev()));
-        while is_id_continue(self.nth_char(0)) {
-            self.bump();
-        }
+        // Start is already eaten, eat the rest of identifier.
+        self.eat_while(is_id_continue);
         Ident
     }
 
@@ -442,7 +429,7 @@ impl Cursor<'_> {
         let mut base = Base::Decimal;
         if first_digit == '0' {
             // Attempt to parse encoding base.
-            let has_digits = match self.nth_char(0) {
+            let has_digits = match self.first() {
                 'b' => {
                     base = Base::Binary;
                     self.bump();
@@ -476,23 +463,23 @@ impl Cursor<'_> {
             self.eat_decimal_digits();
         };
 
-        match self.nth_char(0) {
+        match self.first() {
             // Don't be greedy if this is actually an
             // integer literal followed by field/method access or a range pattern
             // (`0..2` and `12.foo()`)
-            '.' if self.nth_char(1) != '.'
-                && !is_id_start(self.nth_char(1)) =>
+            '.' if self.second() != '.'
+                && !is_id_start(self.second()) =>
             {
                 // might have stuff after the ., and if it does, it needs to start
                 // with a number
                 self.bump();
                 let mut empty_exponent = false;
-                if self.nth_char(0).is_digit(10) {
+                if self.first().is_digit(10) {
                     self.eat_decimal_digits();
-                    match self.nth_char(0) {
+                    match self.first() {
                         'e' | 'E' => {
                             self.bump();
-                            empty_exponent = self.float_exponent().is_err()
+                            empty_exponent = !self.eat_float_exponent();
                         }
                         _ => (),
                     }
@@ -501,7 +488,7 @@ impl Cursor<'_> {
             }
             'e' | 'E' => {
                 self.bump();
-                let empty_exponent = self.float_exponent().is_err();
+                let empty_exponent = !self.eat_float_exponent();
                 Float { base, empty_exponent }
             }
             _ => Int { base, empty_int: false },
@@ -510,65 +497,76 @@ impl Cursor<'_> {
 
     fn lifetime_or_char(&mut self) -> TokenKind {
         debug_assert!(self.prev() == '\'');
-        let mut starts_with_number = false;
-
-        // Check if the first symbol after '\'' is a valid identifier
-        // character or a number (not a digit followed by '\'').
-        if (is_id_start(self.nth_char(0))
-            || self.nth_char(0).is_digit(10) && {
-                starts_with_number = true;
-                true
-            })
-            && self.nth_char(1) != '\''
-        {
-            self.bump();
 
-            // Skip the identifier.
-            while is_id_continue(self.nth_char(0)) {
-                self.bump();
-            }
+        let can_be_a_lifetime = if self.second() == '\'' {
+            // It's surely not a lifetime.
+            false
+        } else {
+            // If the first symbol is valid for identifier, it can be a lifetime.
+            // Also check if it's a number for a better error reporting (so '0 will
+            // be reported as invalid lifetime and not as unterminated char literal).
+            is_id_start(self.first()) || self.first().is_digit(10)
+        };
 
-            return if self.nth_char(0) == '\'' {
-                self.bump();
-                let kind = Char { terminated: true };
-                Literal { kind, suffix_start: self.len_consumed() }
-            } else {
-                Lifetime { starts_with_number }
-            };
+        if !can_be_a_lifetime {
+            let terminated = self.single_quoted_string();
+            let suffix_start = self.len_consumed();
+            if terminated {
+                self.eat_literal_suffix();
+            }
+            let kind = Char { terminated };
+            return Literal { kind, suffix_start };
         }
 
-        // This is not a lifetime (checked above), parse a char literal.
-        let terminated = self.single_quoted_string();
-        let suffix_start = self.len_consumed();
-        if terminated {
-            self.eat_literal_suffix();
+        // Either a lifetime or a character literal with
+        // length greater than 1.
+
+        let starts_with_number = self.first().is_digit(10);
+
+        // Skip the literal contents.
+        // First symbol can be a number (which isn't a valid identifier start),
+        // so skip it without any checks.
+        self.bump();
+        self.eat_while(is_id_continue);
+
+        // Check if after skipping literal contents we've met a closing
+        // single quote (which means that user attempted to create a
+        // string with single quotes).
+        if self.first() == '\'' {
+            self.bump();
+            let kind = Char { terminated: true };
+            return Literal { kind, suffix_start: self.len_consumed() };
         }
-        let kind = Char { terminated };
-        return Literal { kind, suffix_start };
+
+        return Lifetime { starts_with_number };
     }
 
     fn single_quoted_string(&mut self) -> bool {
         debug_assert!(self.prev() == '\'');
-        // Parse `'''` as a single char literal.
-        if self.nth_char(0) == '\'' && self.nth_char(1) == '\'' {
+        // Check if it's a one-symbol literal.
+        if self.second() == '\'' && self.first() != '\\' {
+            self.bump();
             self.bump();
+            return true;
         }
+
+        // Literal has more than one symbol.
+
         // Parse until either quotes are terminated or error is detected.
-        let mut first = true;
         loop {
-            match self.nth_char(0) {
-                // Probably beginning of the comment, which we don't want to include
-                // to the error report.
-                '/' if !first => break,
-                // Newline without following '\'' means unclosed quote, stop parsing.
-                '\n' if self.nth_char(1) != '\'' => break,
-                // End of file, stop parsing.
-                EOF_CHAR if self.is_eof() => break,
+            match self.first() {
                 // Quotes are terminated, finish parsing.
                 '\'' => {
                     self.bump();
                     return true;
                 }
+                // Probably beginning of the comment, which we don't want to include
+                // to the error report.
+                '/' => break,
+                // Newline without following '\'' means unclosed quote, stop parsing.
+                '\n' if self.second() != '\'' => break,
+                // End of file, stop parsing.
+                EOF_CHAR if self.is_eof() => break,
                 // Escaped slash is considered one character, so bump twice.
                 '\\' => {
                     self.bump();
@@ -579,8 +577,8 @@ impl Cursor<'_> {
                     self.bump();
                 }
             }
-            first = false;
         }
+        // String was not terminated.
         false
     }
 
@@ -588,62 +586,71 @@ impl Cursor<'_> {
     /// if string is terminated.
     fn double_quoted_string(&mut self) -> bool {
         debug_assert!(self.prev() == '"');
-        loop {
-            match self.nth_char(0) {
+        while let Some(c) = self.bump() {
+            match c {
                 '"' => {
-                    self.bump();
                     return true;
                 }
-                EOF_CHAR if self.is_eof() => return false,
-                '\\' if self.nth_char(1) == '\\' || self.nth_char(1) == '"' => {
+                '\\' if self.first() == '\\' || self.first() == '"' => {
+                    // Bump again to skip escaped character.
                     self.bump();
                 }
                 _ => (),
             }
-            self.bump();
         }
+        // End of file reached.
+        false
     }
 
     /// Eats the double-quoted string and returns a tuple of
     /// (amount of the '#' symbols, raw string started, raw string terminated)
     fn raw_double_quoted_string(&mut self) -> (usize, bool, bool) {
         debug_assert!(self.prev() == 'r');
+        let mut started: bool = false;
+        let mut finished: bool = false;
+
         // Count opening '#' symbols.
-        let n_hashes = {
-            let mut acc: usize = 0;
-            loop {
-                match self.bump() {
-                    Some('#') => acc += 1,
-                    Some('"') => break acc,
-                    None | Some(_) => return (acc, false, false),
-                }
+        let n_hashes = self.eat_while(|c| c == '#');
+
+        // Check that string is started.
+        match self.bump() {
+            Some('"') => started = true,
+            _ => return (n_hashes, started, finished),
+        }
+
+        // Skip the string contents and on each '#' character met, check if this is
+        // a raw string termination.
+        while !finished {
+            self.eat_while(|c| c != '"');
+
+            if self.is_eof() {
+                return (n_hashes, started, finished);
             }
-        };
 
-        // Skip the string itself and check that amount of closing '#'
-        // symbols is equal to the amount of opening ones.
-        loop {
-            match self.bump() {
-                Some('"') => {
-                    let mut acc = n_hashes;
-                    while self.nth_char(0) == '#' && acc > 0 {
-                        self.bump();
-                        acc -= 1;
-                    }
-                    if acc == 0 {
-                        return (n_hashes, true, true);
-                    }
+            // Eat closing double quote.
+            self.bump();
+
+            // Check that amount of closing '#' symbols
+            // is equal to the amount of opening ones.
+            let mut hashes_left = n_hashes;
+            let is_closing_hash = |c| {
+                if c == '#' && hashes_left != 0 {
+                    hashes_left -= 1;
+                    true
+                } else {
+                    false
                 }
-                Some(_) => (),
-                None => return (n_hashes, true, false),
-            }
+            };
+            finished = self.eat_while(is_closing_hash) == n_hashes;
         }
+
+        (n_hashes, started, finished)
     }
 
     fn eat_decimal_digits(&mut self) -> bool {
         let mut has_digits = false;
         loop {
-            match self.nth_char(0) {
+            match self.first() {
                 '_' => {
                     self.bump();
                 }
@@ -660,7 +667,7 @@ impl Cursor<'_> {
     fn eat_hexadecimal_digits(&mut self) -> bool {
         let mut has_digits = false;
         loop {
-            match self.nth_char(0) {
+            match self.first() {
                 '_' => {
                     self.bump();
                 }
@@ -674,23 +681,43 @@ impl Cursor<'_> {
         has_digits
     }
 
-    fn float_exponent(&mut self) -> Result<(), ()> {
+    /// Eats the float exponent. Returns true if at least one digit was met,
+    /// and returns false otherwise.
+    fn eat_float_exponent(&mut self) -> bool {
         debug_assert!(self.prev() == 'e' || self.prev() == 'E');
-        if self.nth_char(0) == '-' || self.nth_char(0) == '+' {
+        if self.first() == '-' || self.first() == '+' {
             self.bump();
         }
-        if self.eat_decimal_digits() { Ok(()) } else { Err(()) }
+        self.eat_decimal_digits()
     }
 
-    // Eats the suffix if it's an identifier.
+    // Eats the suffix of the literal, e.g. "_u8".
     fn eat_literal_suffix(&mut self) {
-        if !is_id_start(self.nth_char(0)) {
+        self.eat_identifier();
+    }
+
+    // Eats the identifier.
+    fn eat_identifier(&mut self) {
+        if !is_id_start(self.first()) {
             return;
         }
         self.bump();
 
-        while is_id_continue(self.nth_char(0)) {
+        self.eat_while(is_id_continue);
+    }
+
+    /// Eats symbols while predicate returns true or until the end of file is reached.
+    /// Returns amount of eaten symbols.
+    fn eat_while<F>(&mut self, mut predicate: F) -> usize
+    where
+        F: FnMut(char) -> bool
+    {
+        let mut eaten: usize = 0;
+        while predicate(self.first()) && !self.is_eof() {
+            eaten += 1;
             self.bump();
         }
+
+        eaten
     }
 }
diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs
new file mode 100644
index 00000000000..e73414174fb
--- /dev/null
+++ b/src/librustc_lint/array_into_iter.rs
@@ -0,0 +1,91 @@
+use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
+use rustc::{
+    lint::FutureIncompatibleInfo,
+    hir,
+    ty::{
+        self,
+        adjustment::{Adjust, Adjustment},
+    },
+};
+use syntax::{
+    errors::Applicability,
+    symbol::sym,
+};
+
+
+declare_lint! {
+    pub ARRAY_INTO_ITER,
+    Warn,
+    "detects calling `into_iter` on arrays",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #66145 <https://github.com/rust-lang/rust/issues/66145>",
+        edition: None,
+    };
+}
+
+declare_lint_pass!(
+    /// Checks for instances of calling `into_iter` on arrays.
+    ArrayIntoIter => [ARRAY_INTO_ITER]
+);
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
+        // We only care about method call expressions.
+        if let hir::ExprKind::MethodCall(call, span, args) = &expr.kind {
+            if call.ident.name != sym::into_iter {
+                return;
+            }
+
+            // Check if the method call actually calls the libcore
+            // `IntoIterator::into_iter`.
+            let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap();
+            match cx.tcx.trait_of_item(def_id) {
+                Some(trait_id) if cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_id) => {},
+                _ => return,
+            };
+
+            // As this is a method call expression, we have at least one
+            // argument.
+            let receiver_arg = &args[0];
+
+            // Test if the original `self` type is an array type.
+            match cx.tables.expr_ty(receiver_arg).kind {
+                ty::Array(..) => {}
+                _ => return,
+            }
+
+            // Make sure that the first adjustment is an autoref coercion.
+            match cx.tables.expr_adjustments(receiver_arg).get(0) {
+                Some(Adjustment { kind: Adjust::Borrow(_), .. }) => {}
+                _ => return,
+            }
+
+            // Emit lint diagnostic.
+            let target = match cx.tables.expr_ty_adjusted(receiver_arg).kind {
+                ty::Ref(_, ty::TyS { kind: ty::Array(..), ..}, _) => "[T; N]",
+                ty::Ref(_, ty::TyS { kind: ty::Slice(..), ..}, _) => "[T]",
+
+                // We know the original first argument type is an array type,
+                // we know that the first adjustment was an autoref coercion
+                // and we know that `IntoIterator` is the trait involved. The
+                // array cannot be coerced to something other than a reference
+                // to an array or to a slice.
+                _ => bug!("array type coerced to something other than array or slice"),
+            };
+            let msg = format!(
+                "this method call currently resolves to `<&{} as IntoIterator>::into_iter` (due \
+                    to autoref coercions), but that might change in the future when \
+                    `IntoIterator` impls for arrays are added.",
+                target,
+            );
+            cx.struct_span_lint(ARRAY_INTO_ITER, *span, &msg)
+                .span_suggestion(
+                    call.ident.span,
+                    "use `.iter()` instead of `.into_iter()` to avoid ambiguity",
+                    "iter".into(),
+                    Applicability::MachineApplicable,
+                )
+                .emit();
+        }
+    }
+}
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index e3c3966c2f5..38624034022 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -706,7 +706,7 @@ impl EarlyLintPass for DeprecatedAttr {
             }
         }
         if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) {
-            let path_str = pprust::path_to_string(&attr.path);
+            let path_str = pprust::path_to_string(&attr.get_normal_item().path);
             let msg = format!("use of deprecated attribute `{}`: no longer used.", path_str);
             lint_deprecated_attr(cx, attr, &msg, None);
         }
@@ -736,7 +736,7 @@ impl UnusedDocComment {
         let mut sugared_span: Option<Span> = None;
 
         while let Some(attr) = attrs.next() {
-            if attr.is_sugared_doc {
+            if attr.is_doc_comment() {
                 sugared_span = Some(
                     sugared_span.map_or_else(
                         || attr.span,
@@ -745,7 +745,7 @@ impl UnusedDocComment {
                 );
             }
 
-            if attrs.peek().map(|next_attr| next_attr.is_sugared_doc).unwrap_or_default() {
+            if attrs.peek().map(|next_attr| next_attr.is_doc_comment()).unwrap_or_default() {
                 continue;
             }
 
@@ -926,8 +926,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
                    consider instead using an UnsafeCell";
         match get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (&ty1.kind, &ty2.kind)) {
             Some((&ty::Ref(_, _, from_mt), &ty::Ref(_, _, to_mt))) => {
-                if to_mt == hir::Mutability::MutMutable &&
-                   from_mt == hir::Mutability::MutImmutable {
+                if to_mt == hir::Mutability::Mutable &&
+                   from_mt == hir::Mutability::Immutable {
                     cx.span_lint(MUTABLE_TRANSMUTES, expr.span, msg);
                 }
             }
@@ -1476,14 +1476,12 @@ impl KeywordIdents {
         let mut lint = cx.struct_span_lint(
             KEYWORD_IDENTS,
             ident.span,
-            &format!("`{}` is a keyword in the {} edition",
-                     ident.as_str(),
-                     next_edition),
+            &format!("`{}` is a keyword in the {} edition", ident, next_edition),
         );
         lint.span_suggestion(
             ident.span,
             "you can use a raw identifier to stay compatible",
-            format!("r#{}", ident.as_str()),
+            format!("r#{}", ident),
             Applicability::MachineApplicable,
         );
         lint.emit()
@@ -1905,30 +1903,45 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
 
         /// 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.
+            // FIXME(#66075): use diagnostic items.  Somehow, that does not seem to work
+            // on intrinsics right now.
             const TRANSMUTE_PATH: &[Symbol] =
                 &[sym::core, sym::intrinsics, kw::Invalid, sym::transmute];
 
             if let hir::ExprKind::Call(ref path_expr, ref args) = expr.kind {
+                // Find calls to `mem::{uninitialized,zeroed}` methods.
                 if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
                     let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
 
-                    if cx.match_def_path(def_id, ZEROED_PATH) {
+                    if cx.tcx.is_diagnostic_item(sym::mem_zeroed, def_id) {
                         return Some(InitKind::Zeroed);
-                    }
-                    if cx.match_def_path(def_id, UININIT_PATH) {
+                    } else if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) {
                         return Some(InitKind::Uninit);
-                    }
-                    if cx.match_def_path(def_id, TRANSMUTE_PATH) {
+                    } else 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()`.
+                }
+            } else if let hir::ExprKind::MethodCall(_, _, ref args) = expr.kind {
+                // Find problematic calls to `MaybeUninit::assume_init`.
+                let def_id = cx.tables.type_dependent_def_id(expr.hir_id)?;
+                if cx.tcx.is_diagnostic_item(sym::assume_init, def_id) {
+                    // This is a call to *some* method named `assume_init`.
+                    // See if the `self` parameter is one of the dangerous constructors.
+                    if let hir::ExprKind::Call(ref path_expr, _) = args[0].kind {
+                        if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
+                            let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
+
+                            if cx.tcx.is_diagnostic_item(sym::maybe_uninit_zeroed, def_id) {
+                                return Some(InitKind::Zeroed);
+                            } else if cx.tcx.is_diagnostic_item(sym::maybe_uninit_uninit, def_id) {
+                                return Some(InitKind::Uninit);
+                            }
+                        }
+                    }
                 }
             }
 
@@ -1949,6 +1962,8 @@ 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)),
+                RawPtr(tm) if matches!(tm.ty.kind, Dynamic(..)) => // raw ptr to dyn Trait
+                    Some((format!("The vtable of a wide raw pointer must be non-null"), None)),
                 // Primitive types with other constraints.
                 Bool if init == InitKind::Uninit =>
                     Some((format!("Booleans must be `true` or `false`"), None)),
@@ -2032,7 +2047,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                 );
                 err.span_label(expr.span,
                     "this code causes undefined behavior when executed");
-                err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
+                err.span_label(expr.span, "help: use `MaybeUninit<T>` instead, \
+                    and only call `assume_init` after initialization is done");
                 if let Some(span) = span {
                     err.span_note(span, &msg);
                 } else {
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index b1beef04c59..a1e50018f8a 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -15,12 +15,14 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(nll)]
+#![feature(matches_macro)]
 
 #![recursion_limit="256"]
 
 #[macro_use]
 extern crate rustc;
 
+mod array_into_iter;
 mod error_codes;
 mod nonstandard_style;
 mod redundant_semicolon;
@@ -56,6 +58,7 @@ use types::*;
 use unused::*;
 use non_ascii_idents::*;
 use rustc::lint::internal::*;
+use array_into_iter::ArrayIntoIter;
 
 /// Useful for other parts of the compiler.
 pub use builtin::SoftLints;
@@ -130,6 +133,8 @@ macro_rules! late_lint_passes {
             // FIXME: Turn the computation of types which implement Debug into a query
             // and change this to a module lint pass
             MissingDebugImplementations: MissingDebugImplementations::default(),
+
+            ArrayIntoIter: ArrayIntoIter,
         ]);
     )
 }
@@ -334,6 +339,18 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
         "converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
     store.register_removed("incoherent_fundamental_impls",
         "converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
+    store.register_removed("legacy_constructor_visibility",
+        "converted into hard error, see https://github.com/rust-lang/rust/issues/39207");
+    store.register_removed("legacy_disrectory_ownership",
+        "converted into hard error, see https://github.com/rust-lang/rust/issues/37872");
+    store.register_removed("safe_extern_statics",
+        "converted into hard error, see https://github.com/rust-lang/rust/issues/36247");
+    store.register_removed("parenthesized_params_in_types_and_modules",
+        "converted into hard error, see https://github.com/rust-lang/rust/issues/42238");
+    store.register_removed("duplicate_macro_exports",
+        "converted into hard error, see https://github.com/rust-lang/rust/issues/35896");
+    store.register_removed("nested_impl_trait",
+        "converted into hard error, see https://github.com/rust-lang/rust/issues/59014");
 }
 
 fn register_internals(store: &mut lint::LintStore) {
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index aa6dfa50ddd..65e0940920b 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -4,7 +4,7 @@ use rustc::hir::{ExprKind, Node};
 use crate::hir::def_id::DefId;
 use rustc::hir::lowering::is_range_literal;
 use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
 use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton};
 use rustc::{lint, util};
 use rustc_index::vec::Idx;
@@ -68,7 +68,7 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
     max: u128,
     expr: &'tcx hir::Expr,
     parent_expr: &'tcx hir::Expr,
-    ty: impl std::fmt::Debug,
+    ty: &str,
 ) -> bool {
     // We only want to handle exclusive (`..`) ranges,
     // which are represented as `ExprKind::Struct`.
@@ -83,15 +83,15 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
             let mut err = cx.struct_span_lint(
                 OVERFLOWING_LITERALS,
                 parent_expr.span,
-                &format!("range endpoint is out of range for `{:?}`", ty),
+                &format!("range endpoint is out of range for `{}`", ty),
             );
             if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
                 use ast::{LitKind, LitIntType};
                 // We need to preserve the literal's suffix,
                 // as it may determine typing information.
                 let suffix = match lit.node {
-                    LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s),
-                    LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s),
+                    LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s.name_str()),
+                    LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s.name_str()),
                     LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(),
                     _ => bug!(),
                 };
@@ -161,11 +161,11 @@ fn report_bin_hex_error(
     let (t, actually) = match ty {
         attr::IntType::SignedInt(t) => {
             let actually = sign_extend(val, size) as i128;
-            (format!("{:?}", t), actually.to_string())
+            (t.name_str(), actually.to_string())
         }
         attr::IntType::UnsignedInt(t) => {
             let actually = truncate(val, size);
-            (format!("{:?}", t), actually.to_string())
+            (t.name_str(), actually.to_string())
         }
     };
     let mut err = cx.struct_span_lint(
@@ -204,7 +204,7 @@ fn report_bin_hex_error(
 //  - `uX` => `uY`
 //
 // No suggestion for: `isize`, `usize`.
-fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
+fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
     use syntax::ast::IntTy::*;
     use syntax::ast::UintTy::*;
     macro_rules! find_fit {
@@ -215,10 +215,10 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
                 match $ty {
                     $($type => {
                         $(if !negative && val <= uint_ty_range($utypes).1 {
-                            return Some(format!("{:?}", $utypes))
+                            return Some($utypes.name_str())
                         })*
                         $(if val <= int_ty_range($itypes).1 as u128 + _neg {
-                            return Some(format!("{:?}", $itypes))
+                            return Some($itypes.name_str())
                         })*
                         None
                     },)+
@@ -281,7 +281,7 @@ fn lint_int_literal<'a, 'tcx>(
         if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
             if let hir::ExprKind::Struct(..) = par_e.kind {
                 if is_range_literal(cx.sess(), par_e)
-                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t)
+                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
                 {
                     // The overflowing literal lint was overridden.
                     return;
@@ -292,7 +292,7 @@ fn lint_int_literal<'a, 'tcx>(
         cx.span_lint(
             OVERFLOWING_LITERALS,
             e.span,
-            &format!("literal out of range for `{:?}`", t),
+            &format!("literal out of range for `{}`", t.name_str()),
         );
     }
 }
@@ -338,6 +338,7 @@ fn lint_uint_literal<'a, 'tcx>(
                 }
                 hir::ExprKind::Struct(..)
                     if is_range_literal(cx.sess(), par_e) => {
+                        let t = t.name_str();
                         if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
                             // The overflowing literal lint was overridden.
                             return;
@@ -353,7 +354,7 @@ fn lint_uint_literal<'a, 'tcx>(
         cx.span_lint(
             OVERFLOWING_LITERALS,
             e.span,
-            &format!("literal out of range for `{:?}`", t),
+            &format!("literal out of range for `{}`", t.name_str()),
         );
     }
 }
@@ -379,8 +380,7 @@ fn lint_literal<'a, 'tcx>(
         }
         ty::Float(t) => {
             let is_infinite = match lit.node {
-                ast::LitKind::Float(v, _) |
-                ast::LitKind::FloatUnsuffixed(v) => {
+                ast::LitKind::Float(v, _) => {
                     match t {
                         ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
                         ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
@@ -389,9 +389,11 @@ fn lint_literal<'a, 'tcx>(
                 _ => bug!(),
             };
             if is_infinite == Ok(true) {
-                cx.span_lint(OVERFLOWING_LITERALS,
-                             e.span,
-                             &format!("literal out of range for `{:?}`", t));
+                cx.span_lint(
+                    OVERFLOWING_LITERALS,
+                    e.span,
+                    &format!("literal out of range for `{}`", t.name_str()),
+                );
             }
         }
         _ => {}
@@ -835,16 +837,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::Array(ty, _) => self.check_type_for_ffi(cache, ty),
 
             ty::FnPtr(sig) => {
-                match sig.abi() {
-                    Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
-                        return FfiUnsafe {
-                            ty,
-                            reason: "this function pointer has Rust-specific calling convention",
-                            help: Some("consider using an `extern fn(...) -> ...` \
-                                        function pointer instead"),
-                        }
-                    }
-                    _ => {}
+                if self.is_internal_abi(sig.abi()) {
+                    return FfiUnsafe {
+                        ty,
+                        reason: "this function pointer has Rust-specific calling convention",
+                        help: Some("consider using an `extern fn(...) -> ...` \
+                                    function pointer instead"),
+                    };
                 }
 
                 let sig = cx.erase_late_bound_regions(&sig);
@@ -871,7 +870,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
             ty::Foreign(..) => FfiSafe,
 
-            ty::Param(..) |
+            // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
+            //  so they are currently ignored for the purposes of this lint, see #65134.
+            ty::Param(..) | ty::Projection(..) => FfiSafe,
+
             ty::Infer(..) |
             ty::Bound(..) |
             ty::Error |
@@ -880,7 +882,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::GeneratorWitness(..) |
             ty::Placeholder(..) |
             ty::UnnormalizedProjection(..) |
-            ty::Projection(..) |
             ty::Opaque(..) |
             ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
         }
@@ -892,11 +893,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         sp: Span,
         note: &str,
         help: Option<&str>,
+        is_foreign_item: bool,
     ) {
         let mut diag = self.cx.struct_span_lint(
             IMPROPER_CTYPES,
             sp,
-            &format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
+            &format!(
+                "`extern` {} uses type `{}`, which is not FFI-safe",
+                if is_foreign_item { "block" } else { "fn" },
+                ty,
+            ),
         );
         diag.span_label(sp, "not FFI-safe");
         if let Some(help) = help {
@@ -911,9 +917,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         diag.emit();
     }
 
-    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
-        use crate::rustc::ty::TypeFoldable;
-
+    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>, is_foreign_item: bool) -> bool {
         struct ProhibitOpaqueTypes<'tcx> {
             ty: Option<Ty<'tcx>>,
         };
@@ -937,6 +941,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 sp,
                 "opaque types have no C equivalent",
                 None,
+                is_foreign_item,
             );
             true
         } else {
@@ -944,42 +949,46 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
     }
 
-    fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
+    fn check_type_for_ffi_and_report_errors(
+        &mut self,
+        sp: Span,
+        ty: Ty<'tcx>,
+        is_foreign_item: bool,
+    ) {
         // We have to check for opaque types before `normalize_erasing_regions`,
         // which will replace opaque types with their underlying concrete type.
-        if self.check_for_opaque_ty(sp, ty) {
+        if self.check_for_opaque_ty(sp, ty, is_foreign_item) {
             // We've already emitted an error due to an opaque type.
             return;
         }
 
-        // it is only OK to use this function because extern fns cannot have
-        // any generic types right now:
-        let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
-
+        let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
         match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
             FfiResult::FfiSafe => {}
             FfiResult::FfiPhantom(ty) => {
-                self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
+                self.emit_ffi_unsafe_type_lint(
+                    ty, sp, "composed only of `PhantomData`", None, is_foreign_item);
             }
             FfiResult::FfiUnsafe { ty, reason, help } => {
-                self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
+                self.emit_ffi_unsafe_type_lint(
+                    ty, sp, reason, help, is_foreign_item);
             }
         }
     }
 
-    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
+    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl, is_foreign_item: bool) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let sig = self.cx.tcx.fn_sig(def_id);
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
 
         for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
-            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
+            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, is_foreign_item);
         }
 
         if let hir::Return(ref ret_hir) = decl.output {
             let ret_ty = sig.output();
             if !ret_ty.is_unit() {
-                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
+                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, is_foreign_item);
             }
         }
     }
@@ -987,7 +996,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let ty = self.cx.tcx.type_of(def_id);
-        self.check_type_for_ffi_and_report_errors(span, ty);
+        self.check_type_for_ffi_and_report_errors(span, ty, true);
+    }
+
+    fn is_internal_abi(&self, abi: Abi) -> bool {
+        if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
+            true
+        } else {
+            false
+        }
     }
 }
 
@@ -995,12 +1012,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
     fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
         let mut vis = ImproperCTypesVisitor { cx };
         let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
-        if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
-            // Don't worry about types in internal ABIs.
-        } else {
+        if !vis.is_internal_abi(abi) {
             match it.kind {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
-                    vis.check_foreign_fn(it.hir_id, decl);
+                    vis.check_foreign_fn(it.hir_id, decl, true);
                 }
                 hir::ForeignItemKind::Static(ref ty, _) => {
                     vis.check_foreign_static(it.hir_id, ty.span);
@@ -1009,6 +1024,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
             }
         }
     }
+
+    fn check_fn(
+        &mut self,
+        cx: &LateContext<'a, 'tcx>,
+        kind: hir::intravisit::FnKind<'tcx>,
+        decl: &'tcx hir::FnDecl,
+        _: &'tcx hir::Body,
+        _: Span,
+        hir_id: hir::HirId,
+    ) {
+        use hir::intravisit::FnKind;
+
+        let abi = match kind {
+            FnKind::ItemFn(_, _, header, ..) => (header.abi),
+            FnKind::Method(_, sig, ..) => (sig.header.abi),
+            _ => return,
+        };
+
+        let mut vis = ImproperCTypesVisitor { cx };
+        if !vis.is_internal_abi(abi) {
+            vis.check_foreign_fn(hir_id, decl, false);
+        }
+    }
 }
 
 declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 3f85e6d772e..642b8e3279d 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -10,7 +10,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass};
 
 use syntax::ast;
 use syntax::attr;
-use syntax::errors::{Applicability, pluralise};
+use syntax::errors::{Applicability, pluralize};
 use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use syntax::print::pprust;
 use syntax::symbol::{kw, sym};
@@ -144,7 +144,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 return true;
             }
 
-            let plural_suffix = pluralise!(plural_len);
+            let plural_suffix = pluralize!(plural_len);
 
             match ty.kind {
                 ty::Adt(..) if ty.is_box() => {
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index 18192e35f8a..b1431563f21 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
 flate2 = "1.0"
 log = "0.4"
 memmap = "0.6"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
@@ -23,4 +23,5 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
 stable_deref_trait = "1.0.0"
 syntax = { path = "../libsyntax" }
 syntax_expand = { path = "../libsyntax_expand" }
+rustc_parse = { path = "../librustc_parse" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 07c49d91797..05e3ee3322e 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -2,7 +2,7 @@
 
 use crate::cstore::{self, CStore, MetadataBlob};
 use crate::locator::{self, CratePaths};
-use crate::schema::{CrateRoot, CrateDep};
+use crate::rmeta::{CrateRoot, CrateDep};
 use rustc_data_structures::sync::{Lock, Once, AtomicCell};
 
 use rustc::hir::def_id::CrateNum;
@@ -121,7 +121,7 @@ impl<'a> CrateLoader<'a> {
             // `source` stores paths which are normalized which may be different
             // from the strings on the command line.
             let source = &self.cstore.get_crate_data(cnum).source;
-            if let Some(entry) = self.sess.opts.externs.get(&*name.as_str()) {
+            if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
                 // Only use `--extern crate_name=path` here, not `--extern crate_name`.
                 let found = entry.locations.iter().filter_map(|l| l.as_ref()).any(|l| {
                     let l = fs::canonicalize(l).ok();
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index b7596d2018f..c6c8ee575a9 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -1,7 +1,7 @@
 // The crate store - a central repo for information collected about external
 // crates and libraries
 
-use crate::schema;
+use crate::rmeta;
 use rustc::dep_graph::DepNodeIndex;
 use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::map::definitions::DefPathTable;
@@ -17,7 +17,7 @@ use syntax_expand::base::SyntaxExtension;
 use syntax_pos;
 use proc_macro::bridge::client::ProcMacro;
 
-pub use crate::cstore_impl::{provide, provide_extern};
+pub use crate::rmeta::{provide, provide_extern};
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
@@ -49,7 +49,7 @@ crate struct CrateMetadata {
     /// lifetime is only used behind `Lazy`, and therefore acts like an
     /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
     /// is being used to decode those values.
-    crate root: schema::CrateRoot<'static>,
+    crate root: rmeta::CrateRoot<'static>,
     /// 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
@@ -59,7 +59,7 @@ crate struct CrateMetadata {
     /// Trait impl data.
     /// FIXME: Used only from queries and can use query cache,
     /// so pre-decoding can probably be avoided.
-    crate trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
+    crate trait_impls: FxHashMap<(u32, DefIndex), rmeta::Lazy<[DefIndex]>>,
     /// Proc macro descriptions for this crate, if it's a proc macro crate.
     crate raw_proc_macros: Option<&'static [ProcMacro]>,
     /// Source maps for code from the crate.
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 291ee23ff72..ac9d78e9a51 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -26,15 +26,11 @@ extern crate rustc_data_structures;
 
 pub mod error_codes;
 
-mod encoder;
-mod decoder;
 mod dependency_format;
-mod cstore_impl;
 mod foreign_modules;
 mod link_args;
 mod native_libs;
-mod schema;
-mod table;
+mod rmeta;
 
 pub mod creader;
 pub mod cstore;
diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs
index 4291f3a4ae3..b40d58a6819 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/src/librustc_metadata/link_args.rs
@@ -11,7 +11,7 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
     tcx.hir().krate().visit_all_item_likes(&mut collector);
 
     for attr in tcx.hir().krate().attrs.iter() {
-        if attr.path == sym::link_args {
+        if attr.has_name(sym::link_args) {
             if let Some(linkarg) = attr.value_str() {
                 collector.add_link_args(&linkarg.as_str());
             }
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 4a263250f9b..88d7595b063 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -214,7 +214,7 @@
 
 use crate::cstore::MetadataBlob;
 use crate::creader::Library;
-use crate::schema::{METADATA_HEADER, rustc_version};
+use crate::rmeta::{METADATA_HEADER, rustc_version};
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::svh::Svh;
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index a58db6a903b..c9de66a5c87 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -68,7 +68,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
                         Some(name) => name,
                         None => continue, // skip like historical compilers
                     };
-                    lib.kind = match &kind.as_str()[..] {
+                    lib.kind = match &*kind.as_str() {
                         "static" => cstore::NativeStatic,
                         "static-nobundle" => cstore::NativeStaticNobundle,
                         "dylib" => cstore::NativeUnknown,
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index c5954e1ea1d..7cebf2512d6 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -1,8 +1,8 @@
 // Decoding metadata from a single crate's metadata
 
 use crate::cstore::{self, CrateMetadata, MetadataBlob};
-use crate::schema::*;
-use crate::table::{FixedSizeEncoding, PerDefTable};
+use crate::rmeta::*;
+use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
 
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
@@ -40,6 +40,10 @@ use syntax_pos::symbol::{Symbol, sym};
 use log::debug;
 use proc_macro::bridge::client::ProcMacro;
 
+pub use cstore_impl::{provide, provide_extern};
+
+mod cstore_impl;
+
 crate struct DecodeContext<'a, 'tcx> {
     opaque: opaque::Decoder<'a>,
     cdata: Option<&'a CrateMetadata>,
@@ -464,7 +468,7 @@ impl<'tcx> EntryKind<'tcx> {
 }
 
 impl<'a, 'tcx> CrateMetadata {
-    crate fn is_proc_macro_crate(&self) -> bool {
+    fn is_proc_macro_crate(&self) -> bool {
         self.root.proc_macro_decls_static.is_some()
     }
 
@@ -507,7 +511,7 @@ impl<'a, 'tcx> CrateMetadata {
         &self.raw_proc_macros.unwrap()[pos]
     }
 
-    crate fn item_name(&self, item_index: DefIndex) -> Symbol {
+    fn item_name(&self, item_index: DefIndex) -> Symbol {
         if !self.is_proc_macro(item_index) {
             self.def_key(item_index)
                 .disambiguated_data
@@ -519,7 +523,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
+    fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
         if !self.is_proc_macro(index) {
             self.kind(index).def_kind()
         } else {
@@ -529,11 +533,11 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
+    fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
         self.root.per_def.span.get(self, index).unwrap().decode((self, sess))
     }
 
-    crate fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
+    fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
         let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
                 let helper_attrs =
@@ -563,7 +567,7 @@ impl<'a, 'tcx> CrateMetadata {
         )
     }
 
-    crate fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
+    fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
         match self.kind(item_id) {
             EntryKind::Trait(data) => {
                 let data = data.decode((self, sess));
@@ -633,7 +637,7 @@ impl<'a, 'tcx> CrateMetadata {
         )
     }
 
-    crate fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
+    fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
         let kind = self.kind(item_id);
         let did = self.local_def_id(item_id);
 
@@ -658,23 +662,25 @@ impl<'a, 'tcx> CrateMetadata {
         tcx.alloc_adt_def(did, adt_kind, variants, repr)
     }
 
-    crate fn get_predicates(
+    fn get_explicit_predicates(
         &self,
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
     ) -> ty::GenericPredicates<'tcx> {
-        self.root.per_def.predicates.get(self, item_id).unwrap().decode((self, tcx))
+        self.root.per_def.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx))
     }
 
-    crate fn get_predicates_defined_on(
+    fn get_inferred_outlives(
         &self,
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
-    ) -> ty::GenericPredicates<'tcx> {
-        self.root.per_def.predicates_defined_on.get(self, item_id).unwrap().decode((self, tcx))
+    ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
+        self.root.per_def.inferred_outlives.get(self, item_id).map(|predicates| {
+            predicates.decode((self, tcx))
+        }).unwrap_or_default()
     }
 
-    crate fn get_super_predicates(
+    fn get_super_predicates(
         &self,
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
@@ -682,28 +688,28 @@ impl<'a, 'tcx> CrateMetadata {
         self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
     }
 
-    crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
+    fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
         self.root.per_def.generics.get(self, item_id).unwrap().decode((self, sess))
     }
 
-    crate fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         self.root.per_def.ty.get(self, id).unwrap().decode((self, tcx))
     }
 
-    crate fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
+    fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
         match self.is_proc_macro(id) {
             true => self.root.proc_macro_stability.clone(),
             false => self.root.per_def.stability.get(self, id).map(|stab| stab.decode(self)),
         }
     }
 
-    crate fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
+    fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
         self.root.per_def.deprecation.get(self, id)
             .filter(|_| !self.is_proc_macro(id))
             .map(|depr| depr.decode(self))
     }
 
-    crate fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
+    fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
         match self.is_proc_macro(id) {
             true => ty::Visibility::Public,
             false => self.root.per_def.visibility.get(self, id).unwrap().decode(self),
@@ -717,31 +723,31 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
+    fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
         self.get_impl_data(id).parent_impl
     }
 
-    crate fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity {
+    fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity {
         self.get_impl_data(id).polarity
     }
 
-    crate fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
+    fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
         self.get_impl_data(id).defaultness
     }
 
-    crate fn get_coerce_unsized_info(
+    fn get_coerce_unsized_info(
         &self,
         id: DefIndex,
     ) -> Option<ty::adjustment::CoerceUnsizedInfo> {
         self.get_impl_data(id).coerce_unsized_info
     }
 
-    crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
+    fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
         self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
     }
 
     /// Iterates over all the stability attributes in the given crate.
-    crate fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
+    fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
         // FIXME: For a proc macro crate, not sure whether we should return the "host"
         // features or an empty Vec. Both don't cause ICEs.
         tcx.arena.alloc_from_iter(self.root
@@ -750,7 +756,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over the language items in the given crate.
-    crate fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
+    fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not export any lang-items to the target.
             &[]
@@ -763,7 +769,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over the diagnostic items in the given crate.
-    crate fn get_diagnostic_items(
+    fn get_diagnostic_items(
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx FxHashMap<Symbol, DefId> {
@@ -780,7 +786,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over each child of the given item.
-    crate fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
+    fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
         where F: FnMut(def::Export<hir::HirId>)
     {
         if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) {
@@ -919,12 +925,12 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn is_item_mir_available(&self, id: DefIndex) -> bool {
+    fn is_item_mir_available(&self, id: DefIndex) -> bool {
         !self.is_proc_macro(id) &&
             self.root.per_def.mir.get(self, id).is_some()
     }
 
-    crate fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
+    fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
         self.root.per_def.mir.get(self, id)
             .filter(|_| !self.is_proc_macro(id))
             .unwrap_or_else(|| {
@@ -933,7 +939,7 @@ impl<'a, 'tcx> CrateMetadata {
             .decode((self, tcx))
     }
 
-    crate fn get_promoted_mir(
+    fn get_promoted_mir(
         &self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
@@ -946,7 +952,7 @@ impl<'a, 'tcx> CrateMetadata {
             .decode((self, tcx))
     }
 
-    crate fn mir_const_qualif(&self, id: DefIndex) -> u8 {
+    fn mir_const_qualif(&self, id: DefIndex) -> u8 {
         match self.kind(id) {
             EntryKind::Const(qualif, _) |
             EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) |
@@ -957,7 +963,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
+    fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
         let def_key = self.def_key(id);
         let parent = self.local_def_id(def_key.parent.unwrap());
         let name = def_key.disambiguated_data.data.get_opt_name().unwrap();
@@ -990,12 +996,12 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
+    fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
         self.root.per_def.variances.get(self, id).unwrap_or(Lazy::empty())
             .decode(self).collect()
     }
 
-    crate fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
+    fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
         match self.kind(node_id) {
             EntryKind::Struct(data, _) |
             EntryKind::Union(data, _) |
@@ -1004,7 +1010,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
+    fn get_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
         match self.kind(node_id) {
             EntryKind::Struct(data, _) => {
                 data.decode(self).ctor.map(|index| self.local_def_id(index))
@@ -1016,7 +1022,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
+    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
@@ -1032,7 +1038,7 @@ impl<'a, 'tcx> CrateMetadata {
             .collect::<Vec<_>>())
     }
 
-    crate fn get_struct_field_names(
+    fn get_struct_field_names(
         &self,
         id: DefIndex,
         sess: &Session,
@@ -1058,7 +1064,7 @@ impl<'a, 'tcx> CrateMetadata {
         None
     }
 
-    crate fn get_inherent_implementations_for_type(
+    fn get_inherent_implementations_for_type(
         &self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
@@ -1070,7 +1076,7 @@ impl<'a, 'tcx> CrateMetadata {
         )
     }
 
-    crate fn get_implementations_for_trait(
+    fn get_implementations_for_trait(
         &self,
         tcx: TyCtxt<'tcx>,
         filter: Option<DefId>,
@@ -1101,7 +1107,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
+    fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
         let def_key = self.def_key(id);
         match def_key.disambiguated_data.data {
             DefPathData::TypeNs(..) | DefPathData::ValueNs(..) => (),
@@ -1118,7 +1124,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
 
-    crate fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
+    fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not have any *target* native libraries.
             vec![]
@@ -1127,7 +1133,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
+    fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not have any *target* foreign modules.
             &[]
@@ -1136,7 +1142,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_dylib_dependency_formats(
+    fn get_dylib_dependency_formats(
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx [(CrateNum, LinkagePreference)] {
@@ -1150,7 +1156,7 @@ impl<'a, 'tcx> CrateMetadata {
             }))
     }
 
-    crate fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
+    fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not depend on any target weak lang-items.
             &[]
@@ -1161,7 +1167,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
+    fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
         let param_names = match self.kind(id) {
             EntryKind::Fn(data) |
             EntryKind::ForeignFn(data) => data.decode(self).param_names,
@@ -1171,7 +1177,7 @@ impl<'a, 'tcx> CrateMetadata {
         param_names.decode(self).collect()
     }
 
-    crate fn exported_symbols(
+    fn exported_symbols(
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
@@ -1184,7 +1190,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_rendered_const(&self, id: DefIndex) -> String {
+    fn get_rendered_const(&self, id: DefIndex) -> String {
         match self.kind(id) {
             EntryKind::Const(_, data) |
             EntryKind::AssocConst(_, _, data) => data.decode(self).0,
@@ -1192,14 +1198,14 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_macro(&self, id: DefIndex) -> MacroDef {
+    fn get_macro(&self, id: DefIndex) -> MacroDef {
         match self.kind(id) {
             EntryKind::MacroDef(macro_def) => macro_def.decode(self),
             _ => bug!(),
         }
     }
 
-    crate fn is_const_fn_raw(&self, id: DefIndex) -> bool {
+    fn is_const_fn_raw(&self, id: DefIndex) -> bool {
         let constness = match self.kind(id) {
             EntryKind::Method(data) => data.decode(self).fn_data.constness,
             EntryKind::Fn(data) => data.decode(self).constness,
@@ -1209,7 +1215,7 @@ impl<'a, 'tcx> CrateMetadata {
         constness == hir::Constness::Const
     }
 
-    crate fn asyncness(&self, id: DefIndex) -> hir::IsAsync {
+    fn asyncness(&self, id: DefIndex) -> hir::IsAsync {
          match self.kind(id) {
             EntryKind::Fn(data) => data.decode(self).asyncness,
             EntryKind::Method(data) => data.decode(self).fn_data.asyncness,
@@ -1218,7 +1224,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn is_foreign_item(&self, id: DefIndex) -> bool {
+    fn is_foreign_item(&self, id: DefIndex) -> bool {
         match self.kind(id) {
             EntryKind::ForeignImmStatic |
             EntryKind::ForeignMutStatic |
@@ -1227,22 +1233,22 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn static_mutability(&self, id: DefIndex) -> Option<hir::Mutability> {
+    fn static_mutability(&self, id: DefIndex) -> Option<hir::Mutability> {
         match self.kind(id) {
             EntryKind::ImmStatic |
-            EntryKind::ForeignImmStatic => Some(hir::MutImmutable),
+            EntryKind::ForeignImmStatic => Some(hir::Mutability::Immutable),
             EntryKind::MutStatic |
-            EntryKind::ForeignMutStatic => Some(hir::MutMutable),
+            EntryKind::ForeignMutStatic => Some(hir::Mutability::Mutable),
             _ => None,
         }
     }
 
-    crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
+    fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
         self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx))
     }
 
     #[inline]
-    crate fn def_key(&self, index: DefIndex) -> DefKey {
+    fn def_key(&self, index: DefIndex) -> DefKey {
         let mut key = self.def_path_table.def_key(index);
         if self.is_proc_macro(index) {
             let name = self.raw_proc_macro(index).name();
@@ -1252,13 +1258,13 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     // Returns the path leading to the thing with this `id`.
-    crate fn def_path(&self, id: DefIndex) -> DefPath {
+    fn def_path(&self, id: DefIndex) -> DefPath {
         debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
         DefPath::make(self.cnum, id, |parent| self.def_key(parent))
     }
 
     #[inline]
-    crate fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
+    fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
         self.def_path_table.def_path_hash(index)
     }
 
@@ -1356,7 +1362,7 @@ impl<'a, 'tcx> CrateMetadata {
 
     /// Get the `DepNodeIndex` corresponding this crate. The result of this
     /// method is cached in the `dep_node_index` field.
-    pub(super) fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
+    fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
         let mut dep_node_index = self.dep_node_index.load();
 
         if unlikely!(dep_node_index == DepNodeIndex::INVALID) {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index c5f830c0d04..015866548cd 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -1,9 +1,8 @@
 use crate::cstore::{self, LoadedMacro};
-use crate::encoder;
 use crate::link_args;
 use crate::native_libs;
 use crate::foreign_modules;
-use crate::schema;
+use crate::rmeta::{self, encoder};
 
 use rustc::ty::query::QueryConfig;
 use rustc::middle::cstore::{CrateSource, CrateStore, DepKind, EncodedMetadata, NativeLibraryKind};
@@ -19,6 +18,8 @@ use rustc::hir::map::{DefKey, DefPath, DefPathHash};
 use rustc::hir::map::definitions::DefPathTable;
 use rustc::util::nodemap::DefIdMap;
 use rustc_data_structures::svh::Svh;
+use rustc_parse::source_file_to_stream;
+use rustc_parse::parser::emit_unclosed_delims;
 
 use smallvec::SmallVec;
 use std::any::Any;
@@ -28,12 +29,9 @@ use std::sync::Arc;
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map;
-use syntax::parse::source_file_to_stream;
-use syntax::parse::parser::emit_unclosed_delims;
 use syntax::source_map::Spanned;
 use syntax::symbol::Symbol;
 use syntax_pos::{Span, FileName};
-use rustc_index::bit_set::BitSet;
 
 macro_rules! provide {
     (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
@@ -95,8 +93,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     generics_of => {
         tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess))
     }
-    predicates_of => { cdata.get_predicates(def_id.index, tcx) }
-    predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
+    explicit_predicates_of => { cdata.get_explicit_predicates(def_id.index, tcx) }
+    inferred_outlives_of => { cdata.get_inferred_outlives(def_id.index, tcx) }
     super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
     trait_def => {
         tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess))
@@ -123,9 +121,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     }
     optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
     promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
-    mir_const_qualif => {
-        (cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0)))
-    }
+    mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
     fn_sig => { cdata.fn_sig(def_id.index, tcx) }
     inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
     is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
@@ -529,6 +525,6 @@ impl CrateStore for cstore::CStore {
 
     fn metadata_encoding_version(&self) -> &[u8]
     {
-        schema::METADATA_HEADER
+        rmeta::METADATA_HEADER
     }
 }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index f2b0cfa5305..26055d329bc 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1,5 +1,5 @@
-use crate::schema::*;
-use crate::table::{FixedSizeEncoding, PerDefTable};
+use crate::rmeta::*;
+use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
 
 use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
                             EncodedMetadata, ForeignModule};
@@ -76,8 +76,8 @@ struct PerDefTables<'tcx> {
     inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
     variances: PerDefTable<Lazy<[ty::Variance]>>,
     generics: PerDefTable<Lazy<ty::Generics>>,
-    predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
-    predicates_defined_on: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
+    explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
+    inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
     super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
 
     mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
@@ -524,8 +524,8 @@ impl<'tcx> EncodeContext<'tcx> {
             inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
             variances: self.per_def.variances.encode(&mut self.opaque),
             generics: self.per_def.generics.encode(&mut self.opaque),
-            predicates: self.per_def.predicates.encode(&mut self.opaque),
-            predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque),
+            explicit_predicates: self.per_def.explicit_predicates.encode(&mut self.opaque),
+            inferred_outlives: self.per_def.inferred_outlives.encode(&mut self.opaque),
             super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
 
             mir: self.per_def.mir.encode(&mut self.opaque),
@@ -542,7 +542,6 @@ impl<'tcx> EncodeContext<'tcx> {
         let attrs = tcx.hir().krate_attrs();
         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),
@@ -553,7 +552,7 @@ impl<'tcx> EncodeContext<'tcx> {
             panic_strategy: tcx.sess.panic_strategy(),
             edition: tcx.sess.edition(),
             has_global_allocator: has_global_allocator,
-            has_panic_handler: has_panic_handler,
+            has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
             has_default_lib_allocator: has_default_lib_allocator,
             plugin_registrar_fn: tcx.plugin_registrar_fn(LOCAL_CRATE).map(|id| id.index),
             proc_macro_decls_static: if is_proc_macro {
@@ -676,7 +675,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -719,7 +719,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -777,7 +778,8 @@ impl EncodeContext<'tcx> {
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
     }
 
     fn encode_struct_ctor(&mut self, adt_def_id: DefId, def_id: DefId) {
@@ -820,7 +822,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -830,15 +833,18 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.generics[def_id] <- self.tcx.generics_of(def_id));
     }
 
-    fn encode_predicates(&mut self, def_id: DefId) {
-        debug!("EncodeContext::encode_predicates({:?})", def_id);
-        record!(self.per_def.predicates[def_id] <- self.tcx.predicates_of(def_id));
+    fn encode_explicit_predicates(&mut self, def_id: DefId) {
+        debug!("EncodeContext::encode_explicit_predicates({:?})", def_id);
+        record!(self.per_def.explicit_predicates[def_id] <-
+            self.tcx.explicit_predicates_of(def_id));
     }
 
-    fn encode_predicates_defined_on(&mut self, def_id: DefId) {
-        debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
-        record!(self.per_def.predicates_defined_on[def_id] <-
-            self.tcx.predicates_defined_on(def_id))
+    fn encode_inferred_outlives(&mut self, def_id: DefId) {
+        debug!("EncodeContext::encode_inferred_outlives({:?})", def_id);
+        let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
+        if !inferred_outlives.is_empty() {
+            record!(self.per_def.inferred_outlives[def_id] <- inferred_outlives);
+        }
     }
 
     fn encode_super_predicates(&mut self, def_id: DefId) {
@@ -920,7 +926,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -948,7 +955,7 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.kind[def_id] <- match impl_item.kind {
             ty::AssocKind::Const => {
                 if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
-                    let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id).0;
+                    let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
 
                     EntryKind::AssocConst(container,
                         ConstQualif { mir },
@@ -987,7 +994,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         let mir = match ast_item.kind {
             hir::ImplItemKind::Const(..) => true,
             hir::ImplItemKind::Method(ref sig, _) => {
@@ -1078,19 +1086,19 @@ impl EncodeContext<'tcx> {
         debug!("EncodeContext::encode_info_for_item({:?})", def_id);
 
         record!(self.per_def.kind[def_id] <- match item.kind {
-            hir::ItemKind::Static(_, hir::MutMutable, _) => EntryKind::MutStatic,
-            hir::ItemKind::Static(_, hir::MutImmutable, _) => EntryKind::ImmStatic,
+            hir::ItemKind::Static(_, hir::Mutability::Mutable, _) => EntryKind::MutStatic,
+            hir::ItemKind::Static(_, hir::Mutability::Immutable, _) => EntryKind::ImmStatic,
             hir::ItemKind::Const(_, body_id) => {
-                let mir = self.tcx.at(item.span).mir_const_qualif(def_id).0;
+                let mir = self.tcx.at(item.span).mir_const_qualif(def_id);
                 EntryKind::Const(
                     ConstQualif { mir },
                     self.encode_rendered_const_for_body(body_id)
                 )
             }
-            hir::ItemKind::Fn(_, header, .., body) => {
+            hir::ItemKind::Fn(ref sig, .., body) => {
                 let data = FnData {
-                    asyncness: header.asyncness,
-                    constness: header.constness,
+                    asyncness: sig.header.asyncness,
+                    constness: sig.header.constness,
                     param_names: self.encode_fn_param_names_for_body(body),
                 };
 
@@ -1261,22 +1269,11 @@ impl EncodeContext<'tcx> {
             hir::ItemKind::Trait(..) |
             hir::ItemKind::TraitAlias(..) => {
                 self.encode_generics(def_id);
-                self.encode_predicates(def_id);
+                self.encode_explicit_predicates(def_id);
+                self.encode_inferred_outlives(def_id);
             }
             _ => {}
         }
-        // The only time that `predicates_defined_on` is used (on
-        // an external item) is for traits, during chalk lowering,
-        // so only encode it in that case as an efficiency
-        // hack. (No reason not to expand it in the future if
-        // necessary.)
-        match item.kind {
-            hir::ItemKind::Trait(..) |
-            hir::ItemKind::TraitAlias(..) => {
-                self.encode_predicates_defined_on(def_id);
-            }
-            _ => {} // not *wrong* for other kinds of items, but not needed
-        }
         match item.kind {
             hir::ItemKind::Trait(..) |
             hir::ItemKind::TraitAlias(..) => {
@@ -1287,14 +1284,14 @@ impl EncodeContext<'tcx> {
 
         let mir = match item.kind {
             hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
-            hir::ItemKind::Fn(_, header, ..) => {
+            hir::ItemKind::Fn(ref sig, ..) => {
                 let generics = tcx.generics_of(def_id);
                 let needs_inline =
                     (generics.requires_monomorphization(tcx) ||
                         tcx.codegen_fn_attrs(def_id).requests_inline()) &&
                         !self.metadata_output_only();
                 let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
-                needs_inline || header.constness == hir::Constness::Const || always_encode_mir
+                needs_inline || sig.header.constness == hir::Constness::Const || always_encode_mir
             }
             _ => false,
         };
@@ -1371,14 +1368,15 @@ impl EncodeContext<'tcx> {
         let id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
         let body_id = self.tcx.hir().body_owned_by(id);
         let const_data = self.encode_rendered_const_for_body(body_id);
-        let mir = self.tcx.mir_const_qualif(def_id).0;
+        let mir = self.tcx.mir_const_qualif(def_id);
 
         record!(self.per_def.kind[def_id] <- EntryKind::Const(ConstQualif { mir }, const_data));
         record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
         record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
         self.encode_item_type(def_id);
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -1573,8 +1571,10 @@ impl EncodeContext<'tcx> {
                 };
                 EntryKind::ForeignFn(self.lazy(data))
             }
-            hir::ForeignItemKind::Static(_, hir::MutMutable) => EntryKind::ForeignMutStatic,
-            hir::ForeignItemKind::Static(_, hir::MutImmutable) => EntryKind::ForeignImmStatic,
+            hir::ForeignItemKind::Static(_, hir::Mutability::Mutable) =>
+                EntryKind::ForeignMutStatic,
+            hir::ForeignItemKind::Static(_, hir::Mutability::Immutable) =>
+                EntryKind::ForeignImmStatic,
             hir::ForeignItemKind::Type => EntryKind::ForeignType,
         });
         record!(self.per_def.visibility[def_id] <-
@@ -1589,7 +1589,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
     }
 }
 
@@ -1782,7 +1783,7 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
 // will allow us to slice the metadata to the precise length that we just
 // generated regardless of trailing bytes that end up in it.
 
-crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
+pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
     let mut encoder = opaque::Encoder::new(vec![]);
     encoder.emit_raw_bytes(METADATA_HEADER);
 
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/rmeta/mod.rs
index 8bece251116..990a3d984b2 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -1,4 +1,5 @@
-use crate::table::PerDefTable;
+use decoder::Metadata;
+use table::PerDefTable;
 
 use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
@@ -13,7 +14,6 @@ use rustc::ty::{self, Ty, ReprOptions};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::svh::Svh;
-
 use rustc_serialize::Encodable;
 use syntax::{ast, attr};
 use syntax::edition::Edition;
@@ -23,6 +23,12 @@ use syntax_pos::{self, Span};
 use std::marker::PhantomData;
 use std::num::NonZeroUsize;
 
+pub use decoder::{provide, provide_extern};
+
+mod decoder;
+mod encoder;
+mod table;
+
 crate fn rustc_version() -> String {
     format!("rustc {}",
             option_env!("CFG_VERSION").unwrap_or("unknown version"))
@@ -31,18 +37,15 @@ crate fn rustc_version() -> String {
 /// Metadata encoding version.
 /// N.B., increment this if you change the format of metadata such that
 /// the rustc version can't be found to compare with `rustc_version()`.
-const METADATA_VERSION: u8 = 4;
+const METADATA_VERSION: u8 = 5;
 
 /// Metadata header which includes `METADATA_VERSION`.
-/// To get older versions of rustc to ignore this metadata,
-/// there are 4 zero bytes at the start, which are treated
-/// as a length of 0 by old compilers.
 ///
 /// This header is followed by the position of the `CrateRoot`,
 /// which is encoded as a 32-bit big-endian unsigned integer,
 /// and further followed by the rustc version string.
-crate const METADATA_HEADER: &[u8; 12] =
-    &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
+crate const METADATA_HEADER: &[u8; 8] =
+    &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
 
 /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
 /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
@@ -104,13 +107,13 @@ crate struct Lazy<T, Meta = <T as LazyMeta>::Meta>
     where T: ?Sized + LazyMeta<Meta = Meta>,
           Meta: 'static + Copy,
 {
-    pub position: NonZeroUsize,
-    pub meta: Meta,
+    position: NonZeroUsize,
+    meta: Meta,
     _marker: PhantomData<T>,
 }
 
 impl<T: ?Sized + LazyMeta> Lazy<T> {
-     crate fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
+     fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
         Lazy {
             position,
             meta,
@@ -120,13 +123,13 @@ impl<T: ?Sized + LazyMeta> Lazy<T> {
 }
 
 impl<T: Encodable> Lazy<T> {
-    crate fn from_position(position: NonZeroUsize) -> Lazy<T> {
+    fn from_position(position: NonZeroUsize) -> Lazy<T> {
         Lazy::from_position_and_meta(position, ())
     }
 }
 
 impl<T: Encodable> Lazy<[T]> {
-    crate fn empty() -> Lazy<[T]> {
+    fn empty() -> Lazy<[T]> {
         Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
     }
 }
@@ -143,7 +146,7 @@ impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedDecodable for Lazy<T>
 
 /// Encoding / decoding state for `Lazy`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-crate enum LazyState {
+enum LazyState {
     /// Outside of a metadata node.
     NoNode,
 
@@ -171,46 +174,46 @@ macro_rules! Lazy {
 crate struct CrateRoot<'tcx> {
     pub name: Symbol,
     pub triple: TargetTriple,
-    pub extra_filename: String,
+    extra_filename: String,
     pub hash: Svh,
     pub disambiguator: CrateDisambiguator,
     pub panic_strategy: PanicStrategy,
-    pub edition: Edition,
+    edition: Edition,
     pub has_global_allocator: bool,
-    pub has_panic_handler: bool,
+    has_panic_handler: bool,
     pub has_default_lib_allocator: bool,
-    pub plugin_registrar_fn: Option<DefIndex>,
-    pub proc_macro_decls_static: Option<DefIndex>,
-    pub proc_macro_stability: Option<attr::Stability>,
+    plugin_registrar_fn: Option<DefIndex>,
+    proc_macro_decls_static: Option<DefIndex>,
+    proc_macro_stability: Option<attr::Stability>,
 
     pub crate_deps: Lazy<[CrateDep]>,
-    pub dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
-    pub lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
-    pub lang_items: Lazy<[(DefIndex, usize)]>,
-    pub lang_items_missing: Lazy<[lang_items::LangItem]>,
-    pub diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
-    pub native_libraries: Lazy<[NativeLibrary]>,
-    pub foreign_modules: Lazy<[ForeignModule]>,
-    pub source_map: Lazy<[syntax_pos::SourceFile]>,
+    dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
+    lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
+    lang_items: Lazy<[(DefIndex, usize)]>,
+    lang_items_missing: Lazy<[lang_items::LangItem]>,
+    diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
+    native_libraries: Lazy<[NativeLibrary]>,
+    foreign_modules: Lazy<[ForeignModule]>,
+    source_map: Lazy<[syntax_pos::SourceFile]>,
     pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
     pub impls: Lazy<[TraitImpls]>,
-    pub exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
+    exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
     pub interpret_alloc_index: Lazy<[u32]>,
 
-    pub per_def: LazyPerDefTables<'tcx>,
+    per_def: LazyPerDefTables<'tcx>,
 
     /// The DefIndex's of any proc macros delcared by
     /// this crate
     pub proc_macro_data: Option<Lazy<[DefIndex]>>,
 
-    pub compiler_builtins: bool,
+    compiler_builtins: bool,
     pub needs_allocator: bool,
     pub needs_panic_runtime: bool,
-    pub no_builtins: bool,
+    no_builtins: bool,
     pub panic_runtime: bool,
     pub profiler_runtime: bool,
     pub sanitizer_runtime: bool,
-    pub symbol_mangling_version: SymbolManglingVersion,
+    symbol_mangling_version: SymbolManglingVersion,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -230,30 +233,33 @@ crate struct TraitImpls {
 
 #[derive(RustcEncodable, RustcDecodable)]
 crate struct LazyPerDefTables<'tcx> {
-    pub kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
-    pub visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
-    pub span: Lazy!(PerDefTable<Lazy<Span>>),
-    pub attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
-    pub children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
-    pub stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
-    pub deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
-
-    pub ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
-    pub fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
-    pub impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
-    pub inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
-    pub variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
-    pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
-    pub predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-    pub predicates_defined_on: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-    pub super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-
-    pub mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
-    pub promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
+    kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
+    visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
+    span: Lazy!(PerDefTable<Lazy<Span>>),
+    attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
+    children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
+    stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
+    deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
+    ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
+    fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
+    impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
+    inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
+    variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
+    generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
+    explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
+    // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
+    // doesn't handle shorthands in its own (de)serialization impls,
+    // as it's an `enum` for which we want to derive (de)serialization,
+    // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
+    // Also, as an optimization, a missing entry indicates an empty `&[]`.
+    inferred_outlives: Lazy!(PerDefTable<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
+    super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
+    mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
+    promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-crate enum EntryKind<'tcx> {
+enum EntryKind<'tcx> {
     Const(ConstQualif, Lazy<RenderedConst>),
     ImmStatic,
     MutStatic,
@@ -288,58 +294,58 @@ crate enum EntryKind<'tcx> {
 
 /// Additional data for EntryKind::Const and EntryKind::AssocConst
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
-crate struct ConstQualif {
-    pub mir: u8,
+struct ConstQualif {
+    mir: u8,
 }
 
 /// Contains a constant which has been rendered to a String.
 /// Used by rustdoc.
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct RenderedConst(pub String);
+struct RenderedConst(String);
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct ModData {
-    pub reexports: Lazy<[def::Export<hir::HirId>]>,
+struct ModData {
+    reexports: Lazy<[def::Export<hir::HirId>]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct MacroDef {
-    pub body: String,
-    pub legacy: bool,
+struct MacroDef {
+    body: String,
+    legacy: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct FnData {
-    pub asyncness: hir::IsAsync,
-    pub constness: hir::Constness,
-    pub param_names: Lazy<[ast::Name]>,
+struct FnData {
+    asyncness: hir::IsAsync,
+    constness: hir::Constness,
+    param_names: Lazy<[ast::Name]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct VariantData {
-    pub ctor_kind: CtorKind,
-    pub discr: ty::VariantDiscr,
+struct VariantData {
+    ctor_kind: CtorKind,
+    discr: ty::VariantDiscr,
     /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
-    pub ctor: Option<DefIndex>,
+    ctor: Option<DefIndex>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct TraitData {
-    pub unsafety: hir::Unsafety,
-    pub paren_sugar: bool,
-    pub has_auto_impl: bool,
-    pub is_marker: bool,
+struct TraitData {
+    unsafety: hir::Unsafety,
+    paren_sugar: bool,
+    has_auto_impl: bool,
+    is_marker: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct ImplData {
-    pub polarity: ty::ImplPolarity,
-    pub defaultness: hir::Defaultness,
-    pub parent_impl: Option<DefId>,
+struct ImplData {
+    polarity: ty::ImplPolarity,
+    defaultness: hir::Defaultness,
+    parent_impl: Option<DefId>,
 
     /// This is `Some` only for impls of `CoerceUnsized`.
     // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
-    pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
+    coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
 }
 
 
@@ -347,7 +353,7 @@ crate struct ImplData {
 /// is a trait or an impl and whether, in a trait, it has
 /// a default, or an in impl, whether it's marked "default".
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-crate enum AssocContainer {
+enum AssocContainer {
     TraitRequired,
     TraitWithDefault,
     ImplDefault,
@@ -355,7 +361,7 @@ crate enum AssocContainer {
 }
 
 impl AssocContainer {
-    crate fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
+    fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
         match *self {
             AssocContainer::TraitRequired |
             AssocContainer::TraitWithDefault => ty::TraitContainer(def_id),
@@ -365,7 +371,7 @@ impl AssocContainer {
         }
     }
 
-    crate fn defaultness(&self) -> hir::Defaultness {
+    fn defaultness(&self) -> hir::Defaultness {
         match *self {
             AssocContainer::TraitRequired => hir::Defaultness::Default {
                 has_value: false,
@@ -382,17 +388,17 @@ impl AssocContainer {
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct MethodData {
-    pub fn_data: FnData,
-    pub container: AssocContainer,
-    pub has_self: bool,
+struct MethodData {
+    fn_data: FnData,
+    container: AssocContainer,
+    has_self: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct GeneratorData<'tcx> {
-    pub layout: mir::GeneratorLayout<'tcx>,
+struct GeneratorData<'tcx> {
+    layout: mir::GeneratorLayout<'tcx>,
 }
 
 // Tags used for encoding Spans:
-crate const TAG_VALID_SPAN: u8 = 0;
-crate const TAG_INVALID_SPAN: u8 = 1;
+const TAG_VALID_SPAN: u8 = 0;
+const TAG_INVALID_SPAN: u8 = 1;
diff --git a/src/librustc_metadata/table.rs b/src/librustc_metadata/rmeta/table.rs
index e164c28c953..613d92c6d7b 100644
--- a/src/librustc_metadata/table.rs
+++ b/src/librustc_metadata/rmeta/table.rs
@@ -1,5 +1,4 @@
-use crate::decoder::Metadata;
-use crate::schema::*;
+use crate::rmeta::*;
 
 use rustc::hir::def_id::{DefId, DefIndex};
 use rustc_serialize::{Encodable, opaque::Encoder};
@@ -12,7 +11,7 @@ use log::debug;
 /// Used mainly for Lazy positions and lengths.
 /// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`,
 /// but this has no impact on safety.
-crate trait FixedSizeEncoding: Default {
+pub(super) trait FixedSizeEncoding: Default {
     const BYTE_LEN: usize;
 
     // FIXME(eddyb) convert to and from `[u8; Self::BYTE_LEN]` instead,
@@ -126,7 +125,7 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
 // FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used
 // when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
 // (not sure if that is possible given that the `Vec` is being resized now)
-crate struct Table<T> where Option<T>: FixedSizeEncoding {
+pub(super) struct Table<T> where Option<T>: FixedSizeEncoding {
     // FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`,
     // once that starts being allowed by the compiler (i.e. lazy normalization).
     bytes: Vec<u8>,
@@ -143,7 +142,7 @@ impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
 }
 
 impl<T> Table<T> where Option<T>: FixedSizeEncoding {
-    crate fn set(&mut self, i: usize, value: T) {
+    fn set(&mut self, i: usize, value: T) {
         // FIXME(eddyb) investigate more compact encodings for sparse tables.
         // On the PR @michaelwoerister mentioned:
         // > Space requirements could perhaps be optimized by using the HAMT `popcnt`
@@ -157,7 +156,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
         Some(value).write_to_bytes_at(&mut self.bytes, i);
     }
 
-    crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
+    fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
         let pos = buf.position();
         buf.emit_raw_bytes(&self.bytes);
         Lazy::from_position_and_meta(
@@ -178,7 +177,7 @@ impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
 impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
     /// Given the metadata, extract out the value at a particular index (if any).
     #[inline(never)]
-    crate fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
+    fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
         &self,
         metadata: M,
         i: usize,
@@ -194,7 +193,7 @@ impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
 /// Like a `Table` but using `DefIndex` instead of `usize` as keys.
 // FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
 // and by using `newtype_index!` to define `DefIndex`.
-crate struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
+pub(super) struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
 
 impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
     fn default() -> Self {
@@ -203,12 +202,12 @@ impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
 }
 
 impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
-    crate fn set(&mut self, def_id: DefId, value: T) {
+    pub(super) fn set(&mut self, def_id: DefId, value: T) {
         assert!(def_id.is_local());
         self.0.set(def_id.index.index(), value);
     }
 
-    crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
+    pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
         let lazy = self.0.encode(buf);
         Lazy::from_position_and_meta(lazy.position, lazy.meta)
     }
@@ -229,7 +228,7 @@ impl<T> Lazy<PerDefTable<T>> where Option<T>: FixedSizeEncoding {
 
     /// Given the metadata, extract out the value at a particular DefIndex (if any).
     #[inline(never)]
-    crate fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
+    pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
         &self,
         metadata: M,
         def_index: DefIndex,
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index f0cdcf2136b..8c62640353a 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -26,4 +26,4 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_apfloat = { path = "../librustc_apfloat" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 36db68a3372..ebc25138a06 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -2,9 +2,9 @@ use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::hir::{AsyncGeneratorKind, GeneratorKind};
 use rustc::mir::{
-    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
-    LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceRef, ProjectionElem, Rvalue,
-    Statement, StatementKind, TerminatorKind, VarBindingForm,
+    self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
+    FakeReadCause, Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceRef,
+    ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
 };
 use rustc::ty::{self, Ty};
 use rustc_data_structures::fx::FxHashSet;
@@ -380,42 +380,38 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let first_borrow_desc;
         let mut err = match (
             gen_borrow_kind,
-            "immutable",
-            "mutable",
             issued_borrow.kind,
-            "immutable",
-            "mutable",
         ) {
-            (BorrowKind::Shared, lft, _, BorrowKind::Mut { .. }, _, rgt) => {
+            (BorrowKind::Shared, BorrowKind::Mut { .. }) => {
                 first_borrow_desc = "mutable ";
                 self.cannot_reborrow_already_borrowed(
                     span,
                     &desc_place,
                     &msg_place,
-                    lft,
+                    "immutable",
                     issued_span,
                     "it",
-                    rgt,
+                    "mutable",
                     &msg_borrow,
                     None,
                 )
             }
-            (BorrowKind::Mut { .. }, _, lft, BorrowKind::Shared, rgt, _) => {
+            (BorrowKind::Mut { .. }, BorrowKind::Shared) => {
                 first_borrow_desc = "immutable ";
                 self.cannot_reborrow_already_borrowed(
                     span,
                     &desc_place,
                     &msg_place,
-                    lft,
+                    "mutable",
                     issued_span,
                     "it",
-                    rgt,
+                    "immutable",
                     &msg_borrow,
                     None,
                 )
             }
 
-            (BorrowKind::Mut { .. }, _, _, BorrowKind::Mut { .. }, _, _) => {
+            (BorrowKind::Mut { .. }, BorrowKind::Mut { .. }) => {
                 first_borrow_desc = "first ";
                 self.cannot_mutably_borrow_multiply(
                     span,
@@ -427,7 +423,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 )
             }
 
-            (BorrowKind::Unique, _, _, BorrowKind::Unique, _, _) => {
+            (BorrowKind::Unique, BorrowKind::Unique) => {
                 first_borrow_desc = "first ";
                 self.cannot_uniquely_borrow_by_two_closures(
                     span,
@@ -437,25 +433,45 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 )
             }
 
-            (BorrowKind::Mut { .. }, _, _, BorrowKind::Shallow, _, _)
-            | (BorrowKind::Unique, _, _, BorrowKind::Shallow, _, _) => {
-                let mut err = self.cannot_mutate_in_match_guard(
-                    span,
-                    issued_span,
-                    &desc_place,
-                    "mutably borrow",
-                );
-                borrow_spans.var_span_label(
-                    &mut err,
-                    format!(
-                        "borrow occurs due to use of `{}`{}", desc_place, borrow_spans.describe()
-                    ),
-                );
+            (BorrowKind::Mut { .. }, BorrowKind::Shallow)
+            | (BorrowKind::Unique, BorrowKind::Shallow) => {
+                if let Some(immutable_section_description) = self.classify_immutable_section(
+                    &issued_borrow.assigned_place,
+                ) {
+                    let mut err = self.cannot_mutate_in_immutable_section(
+                        span,
+                        issued_span,
+                        &desc_place,
+                        immutable_section_description,
+                        "mutably borrow",
+                    );
+                    borrow_spans.var_span_label(
+                        &mut err,
+                        format!(
+                            "borrow occurs due to use of `{}`{}",
+                            desc_place,
+                            borrow_spans.describe(),
+                        ),
+                    );
 
-                return err;
+                    return err;
+                } else {
+                    first_borrow_desc = "immutable ";
+                    self.cannot_reborrow_already_borrowed(
+                        span,
+                        &desc_place,
+                        &msg_place,
+                        "mutable",
+                        issued_span,
+                        "it",
+                        "immutable",
+                        &msg_borrow,
+                        None,
+                    )
+                }
             }
 
-            (BorrowKind::Unique, _, _, _, _, _) => {
+            (BorrowKind::Unique, _) => {
                 first_borrow_desc = "first ";
                 self.cannot_uniquely_borrow_by_one_closure(
                     span,
@@ -469,14 +485,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 )
             },
 
-            (BorrowKind::Shared, lft, _, BorrowKind::Unique, _, _) => {
+            (BorrowKind::Shared, BorrowKind::Unique) => {
                 first_borrow_desc = "first ";
                 self.cannot_reborrow_already_uniquely_borrowed(
                     span,
                     container_name,
                     &desc_place,
                     "",
-                    lft,
+                    "immutable",
                     issued_span,
                     "",
                     None,
@@ -484,14 +500,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 )
             }
 
-            (BorrowKind::Mut { .. }, _, lft, BorrowKind::Unique, _, _) => {
+            (BorrowKind::Mut { .. }, BorrowKind::Unique) => {
                 first_borrow_desc = "first ";
                 self.cannot_reborrow_already_uniquely_borrowed(
                     span,
                     container_name,
                     &desc_place,
                     "",
-                    lft,
+                    "mutable",
                     issued_span,
                     "",
                     None,
@@ -499,12 +515,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 )
             }
 
-            (BorrowKind::Shared, _, _, BorrowKind::Shared, _, _)
-            | (BorrowKind::Shared, _, _, BorrowKind::Shallow, _, _)
-            | (BorrowKind::Shallow, _, _, BorrowKind::Mut { .. }, _, _)
-            | (BorrowKind::Shallow, _, _, BorrowKind::Unique, _, _)
-            | (BorrowKind::Shallow, _, _, BorrowKind::Shared, _, _)
-            | (BorrowKind::Shallow, _, _, BorrowKind::Shallow, _, _) => unreachable!(),
+            (BorrowKind::Shared, BorrowKind::Shared)
+            | (BorrowKind::Shared, BorrowKind::Shallow)
+            | (BorrowKind::Shallow, BorrowKind::Mut { .. })
+            | (BorrowKind::Shallow, BorrowKind::Unique)
+            | (BorrowKind::Shallow, BorrowKind::Shared)
+            | (BorrowKind::Shallow, BorrowKind::Shallow) => unreachable!(),
         };
 
         if issued_spans == borrow_spans {
@@ -974,7 +990,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let mut err = self.cannot_borrow_across_destructor(borrow_span);
 
         let what_was_dropped = match self.describe_place(place.as_ref()) {
-            Some(name) => format!("`{}`", name.as_str()),
+            Some(name) => format!("`{}`", name),
             None => String::from("temporary value"),
         };
 
@@ -1429,20 +1445,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let loan_span = loan_spans.args_or_use();
 
         if loan.kind == BorrowKind::Shallow {
-            let mut err = self.cannot_mutate_in_match_guard(
-                span,
-                loan_span,
-                &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()),
-                "assign",
-            );
-            loan_spans.var_span_label(
-                &mut err,
-                format!("borrow occurs due to use{}", loan_spans.describe()),
-            );
+            if let Some(section) = self.classify_immutable_section(&loan.assigned_place) {
+                let mut err = self.cannot_mutate_in_immutable_section(
+                    span,
+                    loan_span,
+                    &self.describe_place(place.as_ref()).unwrap_or_else(|| "_".to_owned()),
+                    section,
+                    "assign",
+                );
+                loan_spans.var_span_label(
+                    &mut err,
+                    format!("borrow occurs due to use{}", loan_spans.describe()),
+                );
 
-            err.buffer(&mut self.errors_buffer);
+                err.buffer(&mut self.errors_buffer);
 
-            return;
+                return;
+            }
         }
 
         let mut err = self.cannot_assign_to_borrowed(
@@ -1593,6 +1612,35 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         }
     }
 
+    /// Describe the reason for the fake borrow that was assigned to `place`.
+    fn classify_immutable_section(&self, place: &Place<'tcx>) -> Option<&'static str> {
+        use rustc::mir::visit::Visitor;
+        struct FakeReadCauseFinder<'a, 'tcx> {
+            place: &'a Place<'tcx>,
+            cause: Option<FakeReadCause>,
+        }
+        impl<'tcx> Visitor<'tcx> for FakeReadCauseFinder<'_, 'tcx> {
+            fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
+                match statement {
+                    Statement {
+                        kind: StatementKind::FakeRead(cause, box ref place),
+                        ..
+                    } if *place == *self.place => {
+                        self.cause = Some(*cause);
+                    }
+                    _ => (),
+                }
+            }
+        }
+        let mut visitor = FakeReadCauseFinder { place, cause: None };
+        visitor.visit_body(&self.body);
+        match visitor.cause {
+            Some(FakeReadCause::ForMatchGuard) => Some("match guard"),
+            Some(FakeReadCause::ForIndex) => Some("indexing expression"),
+            _ => None,
+        }
+    }
+
     /// Annotate argument and return type of function and closure with (synthesized) lifetime for
     /// borrow of local value that does not live long enough.
     fn annotate_argument_and_return_for_borrow(
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index c3369e87215..f932a6bf155 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -137,7 +137,7 @@ fn do_mir_borrowck<'a, 'tcx>(
             };
             let bm = *tables.pat_binding_modes().get(var_hir_id)
                 .expect("missing binding mode");
-            if bm == ty::BindByValue(hir::MutMutable) {
+            if bm == ty::BindByValue(hir::Mutability::Mutable) {
                 upvar.mutability = Mutability::Mut;
             }
             upvar
@@ -235,7 +235,7 @@ fn do_mir_borrowck<'a, 'tcx>(
 
     let movable_generator = match tcx.hir().get(id) {
         Node::Expr(&hir::Expr {
-            kind: hir::ExprKind::Closure(.., Some(hir::GeneratorMovability::Static)),
+            kind: hir::ExprKind::Closure(.., Some(hir::Movability::Static)),
             ..
         }) => false,
         _ => true,
@@ -2118,10 +2118,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             ty::Ref(_, _, mutbl) => {
                                 match mutbl {
                                     // Shared borrowed data is never mutable
-                                    hir::MutImmutable => Err(place),
+                                    hir::Mutability::Immutable => Err(place),
                                     // Mutably borrowed data is mutable, but only if we have a
                                     // unique path to the `&mut`
-                                    hir::MutMutable => {
+                                    hir::Mutability::Mutable => {
                                         let mode = match self.is_upvar_field_projection(place) {
                                             Some(field)
                                                 if self.upvars[field.index()].by_ref =>
@@ -2141,10 +2141,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             ty::RawPtr(tnm) => {
                                 match tnm.mutbl {
                                     // `*const` raw pointers are not mutable
-                                    hir::MutImmutable => Err(place),
+                                    hir::Mutability::Immutable => Err(place),
                                     // `*mut` raw pointers are always mutable, regardless of
                                     // context. The users have to check by themselves.
-                                    hir::MutMutable => {
+                                    hir::Mutability::Mutable => {
                                         Ok(RootPlace {
                                             place_base: place.base,
                                             place_projection: place.projection,
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 68b33331a1f..11e89de810e 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -271,7 +271,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         // we have an explicit self. Do the same thing in this case and check
                         // for a `self: &mut Self` to suggest removing the `&mut`.
                         if let ty::Ref(
-                            _, _, hir::Mutability::MutMutable
+                            _, _, hir::Mutability::Mutable
                         ) = local_decl.ty.kind {
                             true
                         } else {
@@ -593,7 +593,7 @@ fn suggest_ampmut<'tcx>(
     }
 
     let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
-    assert_eq!(ty_mut.mutbl, hir::MutImmutable);
+    assert_eq!(ty_mut.mutbl, hir::Mutability::Immutable);
     (highlight_span,
      if local_decl.ty.is_region_ptr() {
          format!("&mut {}", ty_mut.ty)
@@ -629,7 +629,7 @@ fn annotate_struct_field(
             // we can expect a field that is an immutable reference to a type.
             if let hir::Node::Field(field) = node {
                 if let hir::TyKind::Rptr(lifetime, hir::MutTy {
-                    mutbl: hir::Mutability::MutImmutable,
+                    mutbl: hir::Mutability::Immutable,
                     ref ty
                 }) = field.ty.kind {
                     // Get the snippets in two parts - the named lifetime (if there is one) and
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 9f2f174553f..37fc0b09e5b 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -36,6 +36,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
 use rustc::traits::query::{Fallible, NoSolution};
 use rustc::traits::{self, ObligationCause, PredicateObligations};
 use rustc::ty::adjustment::{PointerCast};
+use rustc::ty::cast::CastTy;
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::subst::{Subst, SubstsRef, GenericArgKind, UserSubsts};
 use rustc::ty::{
@@ -2137,7 +2138,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         let ty_from = match op.ty(body, tcx).kind {
                             ty::RawPtr(ty::TypeAndMut {
                                 ty: ty_from,
-                                mutbl: hir::MutMutable,
+                                mutbl: hir::Mutability::Mutable,
                             }) => ty_from,
                             _ => {
                                 span_mirbug!(
@@ -2152,7 +2153,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         let ty_to = match ty.kind {
                             ty::RawPtr(ty::TypeAndMut {
                                 ty: ty_to,
-                                mutbl: hir::MutImmutable,
+                                mutbl: hir::Mutability::Immutable,
                             }) => ty_to,
                             _ => {
                                 span_mirbug!(
@@ -2177,72 +2178,125 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 ty_from,
                                 ty_to,
                                 terr
-                            )
+                            );
                         }
                     }
 
-                    CastKind::Misc => {
-                        if let ty::Ref(_, mut ty_from, _) = op.ty(body, tcx).kind {
-                            let (mut ty_to, mutability) = if let ty::RawPtr(ty::TypeAndMut {
-                                ty: ty_to,
-                                mutbl,
-                            }) = ty.kind {
-                                (ty_to, mutbl)
-                            } else {
+                    CastKind::Pointer(PointerCast::ArrayToPointer)  => {
+                        let ty_from = op.ty(body, tcx);
+
+                        let opt_ty_elem = match ty_from.kind {
+                            ty::RawPtr(
+                                ty::TypeAndMut { mutbl: hir::Mutability::Immutable, ty: array_ty }
+                            ) => {
+                                match array_ty.kind {
+                                    ty::Array(ty_elem, _) => Some(ty_elem),
+                                    _ => None,
+                                }
+                            }
+                            _ => None,
+                        };
+
+                        let ty_elem = match opt_ty_elem {
+                            Some(ty_elem) => ty_elem,
+                            None => {
                                 span_mirbug!(
                                     self,
                                     rvalue,
-                                    "invalid cast types {:?} -> {:?}",
-                                    op.ty(body, tcx),
+                                    "ArrayToPointer cast from unexpected type {:?}",
+                                    ty_from,
+                                );
+                                return;
+                            }
+                        };
+
+                        let ty_to = match ty.kind {
+                            ty::RawPtr(
+                                ty::TypeAndMut { mutbl: hir::Mutability::Immutable, ty: ty_to }
+                            ) => {
+                                ty_to
+                            }
+                            _ => {
+                                span_mirbug!(
+                                    self,
+                                    rvalue,
+                                    "ArrayToPointer cast to unexpected type {:?}",
                                     ty,
                                 );
                                 return;
-                            };
-
-                            // Handle the direct cast from `&[T; N]` to `*const T` by unwrapping
-                            // any array we find.
-                            while let ty::Array(ty_elem_from, _) = ty_from.kind {
-                                ty_from = ty_elem_from;
-                                if let ty::Array(ty_elem_to, _) = ty_to.kind {
-                                    ty_to = ty_elem_to;
-                                } else {
-                                    break;
-                                }
                             }
+                        };
 
-                            if let hir::MutMutable = mutability {
-                                if let Err(terr) = self.eq_types(
-                                    ty_from,
-                                    ty_to,
-                                    location.to_locations(),
-                                    ConstraintCategory::Cast,
-                                ) {
-                                    span_mirbug!(
-                                        self,
-                                        rvalue,
-                                        "equating {:?} with {:?} yields {:?}",
-                                        ty_from,
-                                        ty_to,
-                                        terr
-                                    )
-                                }
-                            } else {
-                                if let Err(terr) = self.sub_types(
-                                    ty_from,
-                                    ty_to,
-                                    location.to_locations(),
-                                    ConstraintCategory::Cast,
-                                ) {
-                                    span_mirbug!(
-                                        self,
-                                        rvalue,
-                                        "relating {:?} with {:?} yields {:?}",
-                                        ty_from,
-                                        ty_to,
-                                        terr
-                                    )
+                        if let Err(terr) = self.sub_types(
+                            ty_elem,
+                            ty_to,
+                            location.to_locations(),
+                            ConstraintCategory::Cast,
+                        ) {
+                            span_mirbug!(
+                                self,
+                                rvalue,
+                                "relating {:?} with {:?} yields {:?}",
+                                ty_elem,
+                                ty_to,
+                                terr
+                            )
+                        }
+                    }
+
+                    CastKind::Misc => {
+                        let ty_from = op.ty(body, tcx);
+                        let cast_ty_from = CastTy::from_ty(ty_from);
+                        let cast_ty_to = CastTy::from_ty(ty);
+                        match (cast_ty_from, cast_ty_to) {
+                            (Some(CastTy::RPtr(ref_tm)), Some(CastTy::Ptr(ptr_tm))) => {
+                                if let hir::Mutability::Mutable = ptr_tm.mutbl {
+                                    if let Err(terr) = self.eq_types(
+                                        ref_tm.ty,
+                                        ptr_tm.ty,
+                                        location.to_locations(),
+                                        ConstraintCategory::Cast,
+                                    ) {
+                                        span_mirbug!(
+                                            self,
+                                            rvalue,
+                                            "equating {:?} with {:?} yields {:?}",
+                                            ref_tm.ty,
+                                            ptr_tm.ty,
+                                            terr
+                                        )
+                                    }
+                                } else {
+                                    if let Err(terr) = self.sub_types(
+                                        ref_tm.ty,
+                                        ptr_tm.ty,
+                                        location.to_locations(),
+                                        ConstraintCategory::Cast,
+                                    ) {
+                                        span_mirbug!(
+                                            self,
+                                            rvalue,
+                                            "relating {:?} with {:?} yields {:?}",
+                                            ref_tm.ty,
+                                            ptr_tm.ty,
+                                            terr
+                                        )
+                                    }
                                 }
-                            }
+                            },
+                            (None, _)
+                            | (_, None)
+                            | (_, Some(CastTy::FnPtr))
+                            | (Some(CastTy::Float), Some(CastTy::Ptr(_)))
+                            | (Some(CastTy::Ptr(_)), Some(CastTy::Float))
+                            | (Some(CastTy::FnPtr), Some(CastTy::Float)) => span_mirbug!(
+                                self,
+                                rvalue,
+                                "Invalid cast {:?} -> {:?}",
+                                ty_from,
+                                ty,
+                            ),
+                            _ => (),
                         }
                     }
                 }
@@ -2450,13 +2504,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             });
 
                             match mutbl {
-                                hir::Mutability::MutImmutable => {
+                                hir::Mutability::Immutable => {
                                     // Immutable reference. We don't need the base
                                     // to be valid for the entire lifetime of
                                     // the borrow.
                                     break;
                                 }
-                                hir::Mutability::MutMutable => {
+                                hir::Mutability::Mutable => {
                                     // Mutable reference. We *do* need the base
                                     // to be valid, because after the base becomes
                                     // invalid, someone else can use our mutable deref.
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index b876fd83ec9..fbedac45ddf 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -90,7 +90,7 @@ pub enum DefiningTy<'tcx> {
     /// The MIR is a generator. The signature is that generators take
     /// no parameters and return the result of
     /// `ClosureSubsts::generator_return_ty`.
-    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 
     /// The MIR is a fn item with the given `DefId` and substs. The signature
     /// of the function can be bound then with the `fn_sig` query.
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index f437c717296..f0d2927ba45 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -57,7 +57,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
 
             if *elem == ProjectionElem::Deref {
                 let ty = Place::ty_from(&self.base, proj_base, body, tcx).ty;
-                if let ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) = ty.kind {
+                if let ty::RawPtr(..) | ty::Ref(_, _, hir::Mutability::Immutable) = ty.kind {
                     // For both derefs of raw pointers and `&T`
                     // references, the original path is `Copy` and
                     // therefore not significant.  In particular,
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 264e4807af0..87a431a7fb8 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -246,11 +246,13 @@ fn place_components_conflict<'tcx>(
                     debug!("borrow_conflicts_with_place: shallow access behind ptr");
                     return false;
                 }
-                (ProjectionElem::Deref, ty::Ref(_, _, hir::MutImmutable), _) => {
+                (ProjectionElem::Deref, ty::Ref(_, _, hir::Mutability::Immutable), _) => {
                     // Shouldn't be tracked
                     bug!("Tracking borrow behind shared reference.");
                 }
-                (ProjectionElem::Deref, ty::Ref(_, _, hir::MutMutable), AccessDepth::Drop) => {
+                (ProjectionElem::Deref,
+                 ty::Ref(_, _, hir::Mutability::Mutable),
+                 AccessDepth::Drop) => {
                     // Values behind a mutable reference are not access either by dropping a
                     // value, or by StorageDead
                     debug!("borrow_conflicts_with_place: drop access behind ptr");
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index 1be1fcef61b..57833cac9cb 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -149,7 +149,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                         ty::Ref(
                             _, /*rgn*/
                             _, /*ty*/
-                            hir::MutImmutable
+                            hir::Mutability::Immutable
                             ) => {
                             // don't continue traversing over derefs of raw pointers or shared
                             // borrows.
@@ -160,7 +160,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                         ty::Ref(
                             _, /*rgn*/
                             _, /*ty*/
-                            hir::MutMutable,
+                            hir::Mutability::Mutable,
                             ) => {
                             self.next = Some(PlaceRef {
                                 base: cursor.base,
diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs
index 8d2bef39bed..d3e013acc9e 100644
--- a/src/librustc_mir/build/expr/as_place.rs
+++ b/src/librustc_mir/build/expr/as_place.rs
@@ -4,9 +4,11 @@ use crate::build::expr::category::Category;
 use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
 use crate::build::{BlockAnd, BlockAndExtension, Builder};
 use crate::hair::*;
+use rustc::middle::region;
 use rustc::mir::interpret::{PanicInfo::BoundsCheck};
 use rustc::mir::*;
-use rustc::ty::{CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance};
+use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance};
+use syntax_pos::Span;
 
 use rustc_index::vec::Idx;
 
@@ -68,6 +70,17 @@ impl From<PlaceBase<'tcx>> for PlaceBuilder<'tcx> {
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Compile `expr`, yielding a place that we can move from etc.
+    ///
+    /// WARNING: Any user code might:
+    /// * Invalidate any slice bounds checks performed.
+    /// * Change the address that this `Place` refers to.
+    /// * Modify the memory that this place refers to.
+    /// * Invalidate the memory that this place refers to, this will be caught
+    ///   by borrow checking.
+    ///
+    /// Extra care is needed if any user code is allowed to run between calling
+    /// this method and using it, as is the case for `match` and index
+    /// expressions.
     pub fn as_place<M>(&mut self, mut block: BasicBlock, expr: M) -> BlockAnd<Place<'tcx>>
     where
         M: Mirror<'tcx, Output = Expr<'tcx>>,
@@ -83,7 +96,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         M: Mirror<'tcx, Output = Expr<'tcx>>,
     {
         let expr = self.hir.mirror(expr);
-        self.expr_as_place(block, expr, Mutability::Mut)
+        self.expr_as_place(block, expr, Mutability::Mut, None)
     }
 
     /// Compile `expr`, yielding a place that we can move from etc.
@@ -114,7 +127,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         M: Mirror<'tcx, Output = Expr<'tcx>>,
     {
         let expr = self.hir.mirror(expr);
-        self.expr_as_place(block, expr, Mutability::Not)
+        self.expr_as_place(block, expr, Mutability::Not, None)
     }
 
     fn expr_as_place(
@@ -122,6 +135,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         mut block: BasicBlock,
         expr: Expr<'tcx>,
         mutability: Mutability,
+        fake_borrow_temps: Option<&mut Vec<Local>>,
     ) -> BlockAnd<PlaceBuilder<'tcx>> {
         debug!(
             "expr_as_place(block={:?}, expr={:?}, mutability={:?})",
@@ -137,63 +151,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 lint_level,
                 value,
             } => this.in_scope((region_scope, source_info), lint_level, |this| {
-                if mutability == Mutability::Not {
-                    this.as_read_only_place_builder(block, value)
-                } else {
-                    this.as_place_builder(block, value)
-                }
+                let value = this.hir.mirror(value);
+                this.expr_as_place(block, value, mutability, fake_borrow_temps)
             }),
             ExprKind::Field { lhs, name } => {
-                let place_builder = unpack!(block = this.as_place_builder(block, lhs));
+                let lhs = this.hir.mirror(lhs);
+                let place_builder = unpack!(block = this.expr_as_place(
+                    block,
+                    lhs,
+                    mutability,
+                    fake_borrow_temps,
+                ));
                 block.and(place_builder.field(name, expr.ty))
             }
             ExprKind::Deref { arg } => {
-                let place_builder = unpack!(block = this.as_place_builder(block, arg));
+                let arg = this.hir.mirror(arg);
+                let place_builder = unpack!(block = this.expr_as_place(
+                    block,
+                    arg,
+                    mutability,
+                    fake_borrow_temps,
+                ));
                 block.and(place_builder.deref())
             }
             ExprKind::Index { lhs, index } => {
-                let (usize_ty, bool_ty) = (this.hir.usize_ty(), this.hir.bool_ty());
-
-                let place_builder = unpack!(block = this.as_place_builder(block, lhs));
-                // Making this a *fresh* temporary also means we do not have to worry about
-                // the index changing later: Nothing will ever change this temporary.
-                // The "retagging" transformation (for Stacked Borrows) relies on this.
-                let idx = unpack!(block = this.as_temp(
+                this.lower_index_expression(
                     block,
-                    expr.temp_lifetime,
+                    lhs,
                     index,
-                    Mutability::Not,
-                ));
-
-                let slice = place_builder.clone().into_place(this.hir.tcx());
-                // bounds check:
-                let (len, lt) = (
-                    this.temp(usize_ty.clone(), expr_span),
-                    this.temp(bool_ty, expr_span),
-                );
-                this.cfg.push_assign(
-                    block,
-                    source_info, // len = len(slice)
-                    &len,
-                    Rvalue::Len(slice),
-                );
-                this.cfg.push_assign(
-                    block,
-                    source_info, // lt = idx < len
-                    &lt,
-                    Rvalue::BinaryOp(
-                        BinOp::Lt,
-                        Operand::Copy(Place::from(idx)),
-                        Operand::Copy(len.clone()),
-                    ),
-                );
-
-                let msg = BoundsCheck {
-                    len: Operand::Move(len),
-                    index: Operand::Copy(Place::from(idx)),
-                };
-                let success = this.assert(block, Operand::Move(lt), true, msg, expr_span);
-                success.and(place_builder.index(idx))
+                    mutability,
+                    fake_borrow_temps,
+                    expr.temp_lifetime,
+                    expr_span,
+                    source_info,
+                )
             }
             ExprKind::SelfRef => block.and(PlaceBuilder::from(Local::new(1))),
             ExprKind::VarRef { id } => {
@@ -215,7 +206,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             )),
 
             ExprKind::PlaceTypeAscription { source, user_ty } => {
-                let place_builder = unpack!(block = this.as_place_builder(block, source));
+                let source = this.hir.mirror(source);
+                let place_builder = unpack!(block = this.expr_as_place(
+                    block,
+                    source,
+                    mutability,
+                    fake_borrow_temps,
+                ));
                 if let Some(user_ty) = user_ty {
                     let annotation_index = this.canonical_user_type_annotations.push(
                         CanonicalUserTypeAnnotation {
@@ -309,4 +306,208 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
         }
     }
+
+    /// Lower an index expression
+    ///
+    /// This has two complications;
+    ///
+    /// * We need to do a bounds check.
+    /// * We need to ensure that the bounds check can't be invalidated using an
+    ///   expression like `x[1][{x = y; 2}]`. We use fake borrows here to ensure
+    ///   that this is the case.
+    fn lower_index_expression(
+        &mut self,
+        mut block: BasicBlock,
+        base: ExprRef<'tcx>,
+        index: ExprRef<'tcx>,
+        mutability: Mutability,
+        fake_borrow_temps: Option<&mut Vec<Local>>,
+        temp_lifetime: Option<region::Scope>,
+        expr_span: Span,
+        source_info: SourceInfo
+    ) -> BlockAnd<PlaceBuilder<'tcx>> {
+        let lhs = self.hir.mirror(base);
+
+        let base_fake_borrow_temps = &mut Vec::new();
+        let is_outermost_index = fake_borrow_temps.is_none();
+        let fake_borrow_temps = fake_borrow_temps.unwrap_or(base_fake_borrow_temps);
+
+        let base_place = unpack!(block = self.expr_as_place(
+            block,
+            lhs,
+            mutability,
+            Some(fake_borrow_temps),
+        ));
+
+        // Making this a *fresh* temporary means we do not have to worry about
+        // the index changing later: Nothing will ever change this temporary.
+        // The "retagging" transformation (for Stacked Borrows) relies on this.
+        let idx = unpack!(block = self.as_temp(
+            block,
+            temp_lifetime,
+            index,
+            Mutability::Not,
+        ));
+
+        block = self.bounds_check(
+            block,
+            base_place.clone().into_place(self.hir.tcx()),
+            idx,
+            expr_span,
+            source_info,
+        );
+
+        if is_outermost_index {
+            self.read_fake_borrows(block, fake_borrow_temps, source_info)
+        } else {
+            self.add_fake_borrows_of_base(
+                &base_place,
+                block,
+                fake_borrow_temps,
+                expr_span,
+                source_info,
+            );
+        }
+
+        block.and(base_place.index(idx))
+    }
+
+    fn bounds_check(
+        &mut self,
+        block: BasicBlock,
+        slice: Place<'tcx>,
+        index: Local,
+        expr_span: Span,
+        source_info: SourceInfo,
+    ) -> BasicBlock {
+        let usize_ty = self.hir.usize_ty();
+        let bool_ty = self.hir.bool_ty();
+        // bounds check:
+        let len = self.temp(usize_ty, expr_span);
+        let lt = self.temp(bool_ty, expr_span);
+
+        // len = len(slice)
+        self.cfg.push_assign(
+            block,
+            source_info,
+            &len,
+            Rvalue::Len(slice),
+        );
+        // lt = idx < len
+        self.cfg.push_assign(
+            block,
+            source_info,
+            &lt,
+            Rvalue::BinaryOp(
+                BinOp::Lt,
+                Operand::Copy(Place::from(index)),
+                Operand::Copy(len.clone()),
+            ),
+        );
+        let msg = BoundsCheck {
+            len: Operand::Move(len),
+            index: Operand::Copy(Place::from(index)),
+        };
+        // assert!(lt, "...")
+        self.assert(block, Operand::Move(lt), true, msg, expr_span)
+    }
+
+    fn add_fake_borrows_of_base(
+        &mut self,
+        base_place: &PlaceBuilder<'tcx>,
+        block: BasicBlock,
+        fake_borrow_temps: &mut Vec<Local>,
+        expr_span: Span,
+        source_info: SourceInfo,
+    ) {
+        let tcx = self.hir.tcx();
+        let place_ty = Place::ty_from(
+            &base_place.base,
+            &base_place.projection,
+            &self.local_decls,
+            tcx,
+        );
+        if let ty::Slice(_) = place_ty.ty.kind {
+            // We need to create fake borrows to ensure that the bounds
+            // check that we just did stays valid. Since we can't assign to
+            // unsized values, we only need to ensure that none of the
+            // pointers in the base place are modified.
+            for (idx, elem) in base_place.projection.iter().enumerate().rev() {
+                match elem {
+                    ProjectionElem::Deref => {
+                        let fake_borrow_deref_ty = Place::ty_from(
+                            &base_place.base,
+                            &base_place.projection[..idx],
+                            &self.local_decls,
+                            tcx,
+                        ).ty;
+                        let fake_borrow_ty = tcx.mk_imm_ref(
+                            tcx.lifetimes.re_erased,
+                            fake_borrow_deref_ty,
+                        );
+                        let fake_borrow_temp = self.local_decls.push(
+                            LocalDecl::new_temp(fake_borrow_ty, expr_span)
+                        );
+                        let projection = tcx.intern_place_elems(&base_place.projection[..idx]);
+                        self.cfg.push_assign(
+                            block,
+                            source_info,
+                            &fake_borrow_temp.into(),
+                            Rvalue::Ref(
+                                tcx.lifetimes.re_erased,
+                                BorrowKind::Shallow,
+                                Place {
+                                    base: base_place.base.clone(),
+                                    projection,
+                                }
+                            ),
+                        );
+                        fake_borrow_temps.push(fake_borrow_temp);
+                    }
+                    ProjectionElem::Index(_) => {
+                        let index_ty = Place::ty_from(
+                            &base_place.base,
+                            &base_place.projection[..idx],
+                            &self.local_decls,
+                            tcx,
+                        );
+                        match index_ty.ty.kind {
+                            // The previous index expression has already
+                            // done any index expressions needed here.
+                            ty::Slice(_) => break,
+                            ty::Array(..) => (),
+                            _ => bug!("unexpected index base"),
+                        }
+                    }
+                    ProjectionElem::Field(..)
+                    | ProjectionElem::Downcast(..)
+                    | ProjectionElem::ConstantIndex { .. }
+                    | ProjectionElem::Subslice { .. } => (),
+                }
+            }
+        }
+    }
+
+    fn read_fake_borrows(
+        &mut self,
+        block: BasicBlock,
+        fake_borrow_temps: &mut Vec<Local>,
+        source_info: SourceInfo,
+    ) {
+        // All indexes have been evaluated now, read all of the
+        // fake borrows so that they are live across those index
+        // expressions.
+        for temp in fake_borrow_temps {
+            self.cfg.push(
+                block,
+                Statement {
+                    source_info,
+                    kind: StatementKind::FakeRead(
+                        FakeReadCause::ForIndex,
+                        Box::new(Place::from(*temp)),
+                    )
+                }
+            );
+        }
+    }
 }
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 4f1ac8e51dc..f9b77a4b5dd 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -1,6 +1,5 @@
 //! See docs in `build/expr/mod.rs`.
 
-use rustc_data_structures::fx::FxHashMap;
 use rustc_index::vec::Idx;
 
 use crate::build::expr::category::{Category, RvalueFunc};
@@ -9,11 +8,16 @@ use crate::hair::*;
 use rustc::middle::region;
 use rustc::mir::interpret::PanicInfo;
 use rustc::mir::*;
-use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts};
+use rustc::ty::{self, Ty, UpvarSubsts};
 use syntax_pos::Span;
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
-    /// See comment on `as_local_operand`
+    /// Returns an rvalue suitable for use until the end of the current
+    /// scope expression.
+    ///
+    /// The operand returned from this function will *not be valid* after
+    /// an ExprKind::Scope is passed, so please do *not* return it from
+    /// functions to avoid bad miscompiles.
     pub fn as_local_rvalue<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Rvalue<'tcx>>
     where
         M: Mirror<'tcx, Output = Expr<'tcx>>,
@@ -23,7 +27,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Compile `expr`, yielding an rvalue.
-    pub fn as_rvalue<M>(
+    fn as_rvalue<M>(
         &mut self,
         block: BasicBlock,
         scope: Option<region::Scope>,
@@ -66,16 +70,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let value_operand = unpack!(block = this.as_operand(block, scope, value));
                 block.and(Rvalue::Repeat(value_operand, count))
             }
-            ExprKind::Borrow {
-                borrow_kind,
-                arg,
-            } => {
-                let arg_place = match borrow_kind {
-                    BorrowKind::Shared => unpack!(block = this.as_read_only_place(block, arg)),
-                    _ => unpack!(block = this.as_place(block, arg)),
-                };
-                block.and(Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place))
-            }
             ExprKind::Binary { op, lhs, rhs } => {
                 let lhs = unpack!(block = this.as_operand(block, scope, lhs));
                 let rhs = unpack!(block = this.as_operand(block, scope, rhs));
@@ -256,77 +250,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 };
                 block.and(Rvalue::Aggregate(result, operands))
             }
-            ExprKind::Adt {
-                adt_def,
-                variant_index,
-                substs,
-                user_ty,
-                fields,
-                base,
-            } => {
-                // see (*) above
-                let is_union = adt_def.is_union();
-                let active_field_index = if is_union {
-                    Some(fields[0].name.index())
-                } else {
-                    None
-                };
-
-                // first process the set of fields that were provided
-                // (evaluating them in order given by user)
-                let fields_map: FxHashMap<_, _> = fields
-                    .into_iter()
-                    .map(|f| {
-                        (
-                            f.name,
-                            unpack!(block = this.as_operand(block, scope, f.expr)),
-                        )
-                    }).collect();
-
-                let field_names = this.hir.all_fields(adt_def, variant_index);
-
-                let fields = if let Some(FruInfo { base, field_types }) = base {
-                    let base = unpack!(block = this.as_place(block, base));
-
-                    // MIR does not natively support FRU, so for each
-                    // base-supplied field, generate an operand that
-                    // reads it from the base.
-                    field_names
-                        .into_iter()
-                        .zip(field_types.into_iter())
-                        .map(|(n, ty)| match fields_map.get(&n) {
-                            Some(v) => v.clone(),
-                            None => this.consume_by_copy_or_move(this.hir.tcx().mk_place_field(
-                                base.clone(),
-                                n,
-                                ty,
-                            )),
-                        })
-                        .collect()
-                } else {
-                    field_names
-                        .iter()
-                        .filter_map(|n| fields_map.get(n).cloned())
-                        .collect()
-                };
-
-                let inferred_ty = expr.ty;
-                let user_ty = user_ty.map(|ty| {
-                    this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
-                        span: source_info.span,
-                        user_ty: ty,
-                        inferred_ty,
-                    })
-                });
-                let adt = box AggregateKind::Adt(
-                    adt_def,
-                    variant_index,
-                    substs,
-                    user_ty,
-                    active_field_index,
-                );
-                block.and(Rvalue::Aggregate(adt, fields))
-            }
             ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
                 block = unpack!(this.stmt_expr(block, expr, None));
                 block.and(this.unit_rvalue())
@@ -351,6 +274,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Match { .. }
             | ExprKind::NeverToAny { .. }
             | ExprKind::Use { .. }
+            | ExprKind::Borrow { .. }
+            | ExprKind::Adt { .. }
             | ExprKind::Loop { .. }
             | ExprKind::LogicalOp { .. }
             | ExprKind::Call { .. }
diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs
index f679a00035d..ae5289986e7 100644
--- a/src/librustc_mir/build/expr/category.rs
+++ b/src/librustc_mir/build/expr/category.rs
@@ -48,11 +48,12 @@ impl Category {
             | ExprKind::Match { .. }
             | ExprKind::NeverToAny { .. }
             | ExprKind::Use { .. }
+            | ExprKind::Adt { .. }
+            | ExprKind::Borrow { .. }
             | ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
 
             ExprKind::Array { .. }
             | ExprKind::Tuple { .. }
-            | ExprKind::Adt { .. }
             | ExprKind::Closure { .. }
             | ExprKind::Unary { .. }
             | ExprKind::Binary { .. }
@@ -60,7 +61,6 @@ impl Category {
             | ExprKind::Cast { .. }
             | ExprKind::Pointer { .. }
             | ExprKind::Repeat { .. }
-            | ExprKind::Borrow { .. }
             | ExprKind::Assign { .. }
             | ExprKind::AssignOp { .. }
             | ExprKind::Yield { .. }
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index e7388b92054..404ca3204e6 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -4,7 +4,9 @@ use crate::build::expr::category::{Category, RvalueFunc};
 use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
 use crate::hair::*;
 use rustc::mir::*;
-use rustc::ty;
+use rustc::ty::{self, CanonicalUserTypeAnnotation};
+use rustc_data_structures::fx::FxHashMap;
+use syntax_pos::symbol::sym;
 
 use rustc_target::spec::abi::Abi;
 
@@ -200,16 +202,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     ty::FnDef(def_id, _) => {
                         let f = ty.fn_sig(this.hir.tcx());
                         if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
-                            Some(this.hir.tcx().item_name(def_id).as_str())
+                            Some(this.hir.tcx().item_name(def_id))
                         } else {
                             None
                         }
                     }
                     _ => None,
                 };
-                let intrinsic = intrinsic.as_ref().map(|s| &s[..]);
                 let fun = unpack!(block = this.as_local_operand(block, fun));
-                if intrinsic == Some("move_val_init") {
+                if let Some(sym::move_val_init) = intrinsic {
                     // `move_val_init` has "magic" semantics - the second argument is
                     // always evaluated "directly" into the first one.
 
@@ -271,6 +272,102 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::Use { source } => {
                 this.into(destination, block, source)
             }
+            ExprKind::Borrow { arg, borrow_kind } => {
+                // We don't do this in `as_rvalue` because we use `as_place`
+                // for borrow expressions, so we cannot create an `RValue` that
+                // remains valid across user code. `as_rvalue` is usually called
+                // by this method anyway, so this shouldn't cause too many
+                // unnecessary temporaries.
+                let arg_place = match borrow_kind {
+                    BorrowKind::Shared => unpack!(block = this.as_read_only_place(block, arg)),
+                    _ => unpack!(block = this.as_place(block, arg)),
+                };
+                let borrow = Rvalue::Ref(
+                    this.hir.tcx().lifetimes.re_erased,
+                    borrow_kind,
+                    arg_place,
+                );
+                this.cfg.push_assign(block, source_info, destination, borrow);
+                block.unit()
+            }
+            ExprKind::Adt {
+                adt_def,
+                variant_index,
+                substs,
+                user_ty,
+                fields,
+                base,
+            } => {
+                // See the notes for `ExprKind::Array` in `as_rvalue` and for
+                // `ExprKind::Borrow` above.
+                let is_union = adt_def.is_union();
+                let active_field_index = if is_union {
+                    Some(fields[0].name.index())
+                } else {
+                    None
+                };
+
+                let scope =  this.local_scope();
+
+                // first process the set of fields that were provided
+                // (evaluating them in order given by user)
+                let fields_map: FxHashMap<_, _> = fields
+                    .into_iter()
+                    .map(|f| {
+                        (
+                            f.name,
+                            unpack!(block = this.as_operand(block, scope, f.expr)),
+                        )
+                    }).collect();
+
+                let field_names = this.hir.all_fields(adt_def, variant_index);
+
+                let fields = if let Some(FruInfo { base, field_types }) = base {
+                    let base = unpack!(block = this.as_place(block, base));
+
+                    // MIR does not natively support FRU, so for each
+                    // base-supplied field, generate an operand that
+                    // reads it from the base.
+                    field_names
+                        .into_iter()
+                        .zip(field_types.into_iter())
+                        .map(|(n, ty)| match fields_map.get(&n) {
+                            Some(v) => v.clone(),
+                            None => this.consume_by_copy_or_move(
+                                this.hir.tcx().mk_place_field(base.clone(), n, ty),
+                            ),
+                        }).collect()
+                } else {
+                    field_names
+                        .iter()
+                        .filter_map(|n| fields_map.get(n).cloned())
+                        .collect()
+                };
+
+                let inferred_ty = expr.ty;
+                let user_ty = user_ty.map(|ty| {
+                    this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation {
+                        span: source_info.span,
+                        user_ty: ty,
+                        inferred_ty,
+                    })
+                });
+                let adt = box AggregateKind::Adt(
+                    adt_def,
+                    variant_index,
+                    substs,
+                    user_ty,
+                    active_field_index,
+                );
+                this.cfg.push_assign(
+                    block,
+                    source_info,
+                    destination,
+                    Rvalue::Aggregate(adt, fields)
+                );
+                block.unit()
+            }
+
 
             // These cases don't actually need a destination
             ExprKind::Assign { .. }
@@ -325,10 +422,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | ExprKind::Cast { .. }
             | ExprKind::Pointer { .. }
             | ExprKind::Repeat { .. }
-            | ExprKind::Borrow { .. }
             | ExprKind::Array { .. }
             | ExprKind::Tuple { .. }
-            | ExprKind::Adt { .. }
             | ExprKind::Closure { .. }
             | ExprKind::Literal { .. }
             | ExprKind::Yield { .. } => {
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index ffb70180bbb..fb605bb2b55 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -30,17 +30,22 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
     // Figure out what primary body this item has.
     let (body_id, return_ty_span) = match tcx.hir().get(id) {
         Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. })
-        | Node::Item(hir::Item { kind: hir::ItemKind::Fn(decl, _, _, body_id), .. })
+        | Node::Item(
+            hir::Item {
+                kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
+                ..
+            }
+        )
         | Node::ImplItem(
             hir::ImplItem {
-                kind: hir::ImplItemKind::Method(hir::MethodSig { decl, .. }, body_id),
+                kind: hir::ImplItemKind::Method(hir::FnSig { decl, .. }, body_id),
                 ..
             }
         )
         | Node::TraitItem(
             hir::TraitItem {
                 kind: hir::TraitItemKind::Method(
-                    hir::MethodSig { decl, .. },
+                    hir::FnSig { decl, .. },
                     hir::TraitMethod::Provided(body_id),
                 ),
                 ..
@@ -576,7 +581,7 @@ where
                 if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
                     debuginfo.debug_name = ident.name;
                     if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
-                        if bm == ty::BindByValue(hir::MutMutable) {
+                        if bm == ty::BindByValue(hir::Mutability::Mutable) {
                             mutability = Mutability::Mut;
                         } else {
                             mutability = Mutability::Not;
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 89bdf7391c3..707ad151182 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -118,7 +118,7 @@ fn op_to_const<'tcx>(
                     0,
                 ),
             };
-            let len = b.to_usize(&ecx.tcx.tcx).unwrap();
+            let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap();
             let start = start.try_into().unwrap();
             let len: usize = len.try_into().unwrap();
             ConstValue::Slice {
diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs
index 956716f8cea..b9e75a576ca 100644
--- a/src/librustc_mir/hair/constant.rs
+++ b/src/librustc_mir/hair/constant.rs
@@ -45,10 +45,7 @@ crate fn lit_to_const<'tcx>(
             trunc(n as u128)?
         },
         LitKind::Int(n, _) => trunc(n)?,
-        LitKind::Float(n, fty) => {
-            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
-        }
-        LitKind::FloatUnsuffixed(n) => {
+        LitKind::Float(n, _) => {
             let fty = match ty.kind {
                 ty::Float(fty) => fty,
                 _ => bug!()
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 7bb96661bb7..2ff690b7ccc 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -628,6 +628,11 @@ fn make_mirror_unadjusted<'a, 'tcx>(
             let cast = if cx.tables().is_coercion_cast(source.hir_id) {
                 // Convert the lexpr to a vexpr.
                 ExprKind::Use { source: source.to_ref() }
+            } else if cx.tables().expr_ty(source).is_region_ptr() {
+                // Special cased so that we can type check that the element
+                // type of the source matches the pointed to type of the
+                // destination.
+                ExprKind::Pointer { source: source.to_ref(), cast: PointerCast::ArrayToPointer }
             } else {
                 // check whether this is casting an enum variant discriminant
                 // to prevent cycles, we refer to the discriminant initializer
@@ -855,8 +860,8 @@ impl ToBorrowKind for AutoBorrowMutability {
 impl ToBorrowKind for hir::Mutability {
     fn to_borrow_kind(&self) -> BorrowKind {
         match *self {
-            hir::MutMutable => BorrowKind::Mut { allow_two_phase_borrow: false },
-            hir::MutImmutable => BorrowKind::Shared,
+            hir::Mutability::Mutable => BorrowKind::Mut { allow_two_phase_borrow: false },
+            hir::Mutability::Immutable => BorrowKind::Shared,
         }
     }
 }
@@ -1008,7 +1013,7 @@ fn convert_var(
                         let ref_closure_ty = cx.tcx.mk_ref(region,
                                                            ty::TypeAndMut {
                                                                ty: closure_ty,
-                                                               mutbl: hir::MutImmutable,
+                                                               mutbl: hir::Mutability::Immutable,
                                                            });
                         Expr {
                             ty: closure_ty,
@@ -1029,7 +1034,7 @@ fn convert_var(
                         let ref_closure_ty = cx.tcx.mk_ref(region,
                                                            ty::TypeAndMut {
                                                                ty: closure_ty,
-                                                               mutbl: hir::MutMutable,
+                                                               mutbl: hir::Mutability::Mutable,
                                                            });
                         Expr {
                             ty: closure_ty,
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index a76377d24bd..b43042f2b17 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -257,7 +257,7 @@ pub enum ExprKind<'tcx> {
         closure_id: DefId,
         substs: UpvarSubsts<'tcx>,
         upvars: Vec<ExprRef<'tcx>>,
-        movability: Option<hir::GeneratorMovability>,
+        movability: Option<hir::Movability>,
     },
     Literal {
         literal: &'tcx Const<'tcx>,
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 8989d2e15de..982330baf9c 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -586,8 +586,10 @@ enum Constructor<'tcx> {
     ConstantValue(&'tcx ty::Const<'tcx>, Span),
     /// Ranges of literal values (`2..=5` and `2..5`).
     ConstantRange(u128, u128, Ty<'tcx>, RangeEnd, Span),
-    /// Array patterns of length n.
-    Slice(u64),
+    /// Array patterns of length `n`.
+    FixedLenSlice(u64),
+    /// Slice patterns. Captures any array constructor of `length >= i + j`.
+    VarLenSlice(u64, u64),
 }
 
 // Ignore spans when comparing, they don't carry semantic information as they are only for lints.
@@ -601,7 +603,11 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> {
                 Constructor::ConstantRange(a_start, a_end, a_ty, a_range_end, _),
                 Constructor::ConstantRange(b_start, b_end, b_ty, b_range_end, _),
             ) => a_start == b_start && a_end == b_end && a_ty == b_ty && a_range_end == b_range_end,
-            (Constructor::Slice(a), Constructor::Slice(b)) => a == b,
+            (Constructor::FixedLenSlice(a), Constructor::FixedLenSlice(b)) => a == b,
+            (
+                Constructor::VarLenSlice(a_prefix, a_suffix),
+                Constructor::VarLenSlice(b_prefix, b_suffix),
+            ) => a_prefix == b_prefix && a_suffix == b_suffix,
             _ => false,
         }
     }
@@ -610,7 +616,7 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> {
 impl<'tcx> Constructor<'tcx> {
     fn is_slice(&self) -> bool {
         match self {
-            Slice { .. } => true,
+            FixedLenSlice { .. } | VarLenSlice { .. } => true,
             _ => false,
         }
     }
@@ -644,7 +650,8 @@ impl<'tcx> Constructor<'tcx> {
                     ty::Const::from_bits(tcx, *hi, ty),
                 )
             }
-            Constructor::Slice(val) => format!("[{}]", val),
+            Constructor::FixedLenSlice(val) => format!("[{}]", val),
+            Constructor::VarLenSlice(prefix, suffix) => format!("[{}, .., {}]", prefix, suffix),
             _ => bug!("bad constructor being displayed: `{:?}", self),
         }
     }
@@ -657,31 +664,114 @@ impl<'tcx> Constructor<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         other_ctors: &Vec<Constructor<'tcx>>,
     ) -> Vec<Constructor<'tcx>> {
-        let mut refined_ctors = vec![self.clone()];
-        for other_ctor in other_ctors {
-            if other_ctor == self {
-                // If a constructor appears in a `match` arm, we can
-                // eliminate it straight away.
-                refined_ctors = vec![]
-            } else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) {
-                // Refine the required constructors for the type by subtracting
-                // the range defined by the current constructor pattern.
-                refined_ctors = interval.subtract_from(tcx, param_env, refined_ctors);
+        match *self {
+            // Those constructors can only match themselves.
+            Single | Variant(_) => {
+                if other_ctors.iter().any(|c| c == self) {
+                    vec![]
+                } else {
+                    vec![self.clone()]
+                }
+            }
+            FixedLenSlice(self_len) => {
+                let overlaps = |c: &Constructor<'_>| match *c {
+                    FixedLenSlice(other_len) => other_len == self_len,
+                    VarLenSlice(prefix, suffix) => prefix + suffix <= self_len,
+                    _ => false,
+                };
+                if other_ctors.iter().any(overlaps) { vec![] } else { vec![self.clone()] }
             }
+            VarLenSlice(..) => {
+                let mut remaining_ctors = vec![self.clone()];
+
+                // For each used ctor, subtract from the current set of constructors.
+                // Naming: we remove the "neg" constructors from the "pos" ones.
+                // Remember, `VarLenSlice(i, j)` covers the union of `FixedLenSlice` from
+                // `i + j` to infinity.
+                for neg_ctor in other_ctors {
+                    remaining_ctors = remaining_ctors
+                        .into_iter()
+                        .flat_map(|pos_ctor| -> SmallVec<[Constructor<'tcx>; 1]> {
+                            // Compute `pos_ctor \ neg_ctor`.
+                            match (&pos_ctor, neg_ctor) {
+                                (&FixedLenSlice(pos_len), &VarLenSlice(neg_prefix, neg_suffix)) => {
+                                    let neg_len = neg_prefix + neg_suffix;
+                                    if neg_len <= pos_len {
+                                        smallvec![]
+                                    } else {
+                                        smallvec![pos_ctor]
+                                    }
+                                }
+                                (
+                                    &VarLenSlice(pos_prefix, pos_suffix),
+                                    &VarLenSlice(neg_prefix, neg_suffix),
+                                ) => {
+                                    let neg_len = neg_prefix + neg_suffix;
+                                    let pos_len = pos_prefix + pos_suffix;
+                                    if neg_len <= pos_len {
+                                        smallvec![]
+                                    } else {
+                                        (pos_len..neg_len).map(FixedLenSlice).collect()
+                                    }
+                                }
+                                (&VarLenSlice(pos_prefix, pos_suffix), &FixedLenSlice(neg_len)) => {
+                                    let pos_len = pos_prefix + pos_suffix;
+                                    if neg_len < pos_len {
+                                        smallvec![pos_ctor]
+                                    } else {
+                                        (pos_len..neg_len)
+                                            .map(FixedLenSlice)
+                                            // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
+                                            .chain(Some(VarLenSlice(
+                                                neg_len + 1 - pos_suffix,
+                                                pos_suffix,
+                                            )))
+                                            .collect()
+                                    }
+                                }
+                                _ if pos_ctor == *neg_ctor => smallvec![],
+                                _ => smallvec![pos_ctor],
+                            }
+                        })
+                        .collect();
+
+                    // If the constructors that have been considered so far already cover
+                    // the entire range of `self`, no need to look at more constructors.
+                    if remaining_ctors.is_empty() {
+                        break;
+                    }
+                }
 
-            // If the constructor patterns that have been considered so far
-            // already cover the entire range of values, then we know the
-            // constructor is not missing, and we can move on to the next one.
-            if refined_ctors.is_empty() {
-                break;
+                remaining_ctors
             }
-        }
+            ConstantRange(..) | ConstantValue(..) => {
+                let mut remaining_ctors = vec![self.clone()];
+                for other_ctor in other_ctors {
+                    if other_ctor == self {
+                        // If a constructor appears in a `match` arm, we can
+                        // eliminate it straight away.
+                        remaining_ctors = vec![]
+                    } else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) {
+                        // Refine the required constructors for the type by subtracting
+                        // the range defined by the current constructor pattern.
+                        remaining_ctors = interval.subtract_from(tcx, param_env, remaining_ctors);
+                    }
 
-        // If a constructor has not been matched, then it is missing.
-        // We add `refined_ctors` instead of `self`, because then we can
-        // provide more detailed error information about precisely which
-        // ranges have been omitted.
-        refined_ctors
+                    // If the constructor patterns that have been considered so far
+                    // already cover the entire range of values, then we know the
+                    // constructor is not missing, and we can move on to the next one.
+                    if remaining_ctors.is_empty() {
+                        break;
+                    }
+                }
+
+                // If a constructor has not been matched, then it is missing.
+                // We add `remaining_ctors` instead of `self`, because then we can
+                // provide more detailed error information about precisely which
+                // ranges have been omitted.
+                remaining_ctors
+            }
+        }
     }
 
     /// This returns one wildcard pattern for each argument to this constructor.
@@ -689,12 +779,68 @@ impl<'tcx> Constructor<'tcx> {
         &self,
         cx: &MatchCheckCtxt<'a, 'tcx>,
         ty: Ty<'tcx>,
-    ) -> impl Iterator<Item = Pat<'tcx>> + DoubleEndedIterator {
-        constructor_sub_pattern_tys(cx, self, ty).into_iter().map(|ty| Pat {
-            ty,
-            span: DUMMY_SP,
-            kind: box PatKind::Wild,
-        })
+    ) -> Vec<Pat<'tcx>> {
+        debug!("wildcard_subpatterns({:#?}, {:?})", self, ty);
+        match ty.kind {
+            ty::Tuple(ref fs) => {
+                fs.into_iter().map(|t| t.expect_ty()).map(Pat::wildcard_from_ty).collect()
+            }
+            ty::Slice(ty) | ty::Array(ty, _) => match *self {
+                FixedLenSlice(length) => (0..length).map(|_| Pat::wildcard_from_ty(ty)).collect(),
+                VarLenSlice(prefix, suffix) => {
+                    (0..prefix + suffix).map(|_| Pat::wildcard_from_ty(ty)).collect()
+                }
+                ConstantValue(..) => vec![],
+                _ => bug!("bad slice pattern {:?} {:?}", self, ty),
+            },
+            ty::Ref(_, rty, _) => vec![Pat::wildcard_from_ty(rty)],
+            ty::Adt(adt, substs) => {
+                if adt.is_box() {
+                    // Use T as the sub pattern type of Box<T>.
+                    vec![Pat::wildcard_from_ty(substs.type_at(0))]
+                } else {
+                    let variant = &adt.variants[self.variant_index_for_adt(cx, adt)];
+                    let is_non_exhaustive =
+                        variant.is_field_list_non_exhaustive() && !cx.is_local(ty);
+                    variant
+                        .fields
+                        .iter()
+                        .map(|field| {
+                            let is_visible =
+                                adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
+                            let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs));
+                            match (is_visible, is_non_exhaustive, is_uninhabited) {
+                                // Treat all uninhabited types in non-exhaustive variants as
+                                // `TyErr`.
+                                (_, true, true) => cx.tcx.types.err,
+                                // Treat all non-visible fields as `TyErr`. They can't appear in
+                                // any other pattern from this match (because they are private), so
+                                // their type does not matter - but we don't want to know they are
+                                // uninhabited.
+                                (false, ..) => cx.tcx.types.err,
+                                (true, ..) => {
+                                    let ty = field.ty(cx.tcx, substs);
+                                    match ty.kind {
+                                        // If the field type returned is an array of an unknown
+                                        // size return an TyErr.
+                                        ty::Array(_, len)
+                                            if len
+                                                .try_eval_usize(cx.tcx, cx.param_env)
+                                                .is_none() =>
+                                        {
+                                            cx.tcx.types.err
+                                        }
+                                        _ => ty,
+                                    }
+                                }
+                            }
+                        })
+                        .map(Pat::wildcard_from_ty)
+                        .collect()
+                }
+            }
+            _ => vec![],
+        }
     }
 
     /// This computes the arity of a constructor. The arity of a constructor
@@ -707,7 +853,8 @@ impl<'tcx> Constructor<'tcx> {
         match ty.kind {
             ty::Tuple(ref fs) => fs.len() as u64,
             ty::Slice(..) | ty::Array(..) => match *self {
-                Slice(length) => length,
+                FixedLenSlice(length) => length,
+                VarLenSlice(prefix, suffix) => prefix + suffix,
                 ConstantValue(..) => 0,
                 _ => bug!("bad slice pattern {:?} {:?}", self, ty),
             },
@@ -764,9 +911,18 @@ impl<'tcx> Constructor<'tcx> {
 
             ty::Ref(..) => PatKind::Deref { subpattern: subpatterns.nth(0).unwrap() },
 
-            ty::Slice(_) | ty::Array(..) => {
-                PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
-            }
+            ty::Slice(_) | ty::Array(..) => match self {
+                FixedLenSlice(_) => {
+                    PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
+                }
+                VarLenSlice(prefix_len, _suffix_len) => {
+                    let prefix = subpatterns.by_ref().take(*prefix_len as usize).collect();
+                    let suffix = subpatterns.collect();
+                    let wild = Pat::wildcard_from_ty(ty);
+                    PatKind::Slice { prefix, slice: Some(wild), suffix }
+                }
+                _ => bug!("bad slice pattern {:?} {:?}", self, ty),
+            },
 
             _ => match *self {
                 ConstantValue(value, _) => PatKind::Constant { value },
@@ -784,7 +940,7 @@ impl<'tcx> Constructor<'tcx> {
 
     /// Like `apply`, but where all the subpatterns are wildcards `_`.
     fn apply_wildcards<'a>(&self, cx: &MatchCheckCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> {
-        let subpatterns = self.wildcard_subpatterns(cx, ty).rev();
+        let subpatterns = self.wildcard_subpatterns(cx, ty).into_iter().rev();
         self.apply(cx, ty, subpatterns)
     }
 }
@@ -831,7 +987,7 @@ impl<'tcx> Usefulness<'tcx> {
     fn apply_wildcard(self, ty: Ty<'tcx>) -> Self {
         match self {
             UsefulWithWitness(witnesses) => {
-                let wild = Pat { ty, span: DUMMY_SP, kind: box PatKind::Wild };
+                let wild = Pat::wildcard_from_ty(ty);
                 UsefulWithWitness(
                     witnesses
                         .into_iter()
@@ -884,7 +1040,6 @@ pub enum WitnessPreference {
 #[derive(Copy, Clone, Debug)]
 struct PatCtxt<'tcx> {
     ty: Ty<'tcx>,
-    max_slice_length: u64,
     span: Span,
 }
 
@@ -980,14 +1135,14 @@ fn all_constructors<'a, 'tcx>(
             .collect(),
         ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
             let len = len.eval_usize(cx.tcx, cx.param_env);
-            if len != 0 && cx.is_uninhabited(sub_ty) { vec![] } else { vec![Slice(len)] }
+            if len != 0 && cx.is_uninhabited(sub_ty) { vec![] } else { vec![FixedLenSlice(len)] }
         }
         // Treat arrays of a constant but unknown length like slices.
         ty::Array(ref sub_ty, _) | ty::Slice(ref sub_ty) => {
             if cx.is_uninhabited(sub_ty) {
-                vec![Slice(0)]
+                vec![FixedLenSlice(0)]
             } else {
-                (0..pcx.max_slice_length + 1).map(|length| Slice(length)).collect()
+                vec![VarLenSlice(0, 0)]
             }
         }
         ty::Adt(def, substs) if def.is_enum() => def
@@ -1042,108 +1197,6 @@ fn all_constructors<'a, 'tcx>(
     ctors
 }
 
-fn max_slice_length<'p, 'a, 'tcx, I>(cx: &mut MatchCheckCtxt<'a, 'tcx>, patterns: I) -> u64
-where
-    I: Iterator<Item = &'p Pat<'tcx>>,
-    'tcx: 'p,
-{
-    // The exhaustiveness-checking paper does not include any details on
-    // checking variable-length slice patterns. However, they are matched
-    // by an infinite collection of fixed-length array patterns.
-    //
-    // Checking the infinite set directly would take an infinite amount
-    // of time. However, it turns out that for each finite set of
-    // patterns `P`, all sufficiently large array lengths are equivalent:
-    //
-    // Each slice `s` with a "sufficiently-large" length `l ≥ L` that applies
-    // to exactly the subset `Pₜ` of `P` can be transformed to a slice
-    // `sₘ` for each sufficiently-large length `m` that applies to exactly
-    // the same subset of `P`.
-    //
-    // Because of that, each witness for reachability-checking from one
-    // of the sufficiently-large lengths can be transformed to an
-    // equally-valid witness from any other length, so we only have
-    // to check slice lengths from the "minimal sufficiently-large length"
-    // and below.
-    //
-    // Note that the fact that there is a *single* `sₘ` for each `m`
-    // not depending on the specific pattern in `P` is important: if
-    // you look at the pair of patterns
-    //     `[true, ..]`
-    //     `[.., false]`
-    // Then any slice of length ≥1 that matches one of these two
-    // patterns can be trivially turned to a slice of any
-    // other length ≥1 that matches them and vice-versa - for
-    // but the slice from length 2 `[false, true]` that matches neither
-    // of these patterns can't be turned to a slice from length 1 that
-    // matches neither of these patterns, so we have to consider
-    // slices from length 2 there.
-    //
-    // Now, to see that that length exists and find it, observe that slice
-    // patterns are either "fixed-length" patterns (`[_, _, _]`) or
-    // "variable-length" patterns (`[_, .., _]`).
-    //
-    // For fixed-length patterns, all slices with lengths *longer* than
-    // the pattern's length have the same outcome (of not matching), so
-    // as long as `L` is greater than the pattern's length we can pick
-    // any `sₘ` from that length and get the same result.
-    //
-    // For variable-length patterns, the situation is more complicated,
-    // because as seen above the precise value of `sₘ` matters.
-    //
-    // However, for each variable-length pattern `p` with a prefix of length
-    // `plₚ` and suffix of length `slₚ`, only the first `plₚ` and the last
-    // `slₚ` elements are examined.
-    //
-    // Therefore, as long as `L` is positive (to avoid concerns about empty
-    // types), all elements after the maximum prefix length and before
-    // the maximum suffix length are not examined by any variable-length
-    // pattern, and therefore can be added/removed without affecting
-    // them - creating equivalent patterns from any sufficiently-large
-    // length.
-    //
-    // Of course, if fixed-length patterns exist, we must be sure
-    // that our length is large enough to miss them all, so
-    // we can pick `L = max(FIXED_LEN+1 ∪ {max(PREFIX_LEN) + max(SUFFIX_LEN)})`
-    //
-    // for example, with the above pair of patterns, all elements
-    // but the first and last can be added/removed, so any
-    // witness of length ≥2 (say, `[false, false, true]`) can be
-    // turned to a witness from any other length ≥2.
-
-    let mut max_prefix_len = 0;
-    let mut max_suffix_len = 0;
-    let mut max_fixed_len = 0;
-
-    for row in patterns {
-        match *row.kind {
-            PatKind::Constant { value } => {
-                // extract the length of an array/slice from a constant
-                match (value.val, &value.ty.kind) {
-                    (_, ty::Array(_, n)) => {
-                        max_fixed_len = cmp::max(max_fixed_len, n.eval_usize(cx.tcx, cx.param_env))
-                    }
-                    (ConstValue::Slice { start, end, .. }, ty::Slice(_)) => {
-                        max_fixed_len = cmp::max(max_fixed_len, (end - start) as u64)
-                    }
-                    _ => {}
-                }
-            }
-            PatKind::Slice { ref prefix, slice: None, ref suffix } => {
-                let fixed_len = prefix.len() as u64 + suffix.len() as u64;
-                max_fixed_len = cmp::max(max_fixed_len, fixed_len);
-            }
-            PatKind::Slice { ref prefix, slice: Some(_), ref suffix } => {
-                max_prefix_len = cmp::max(max_prefix_len, prefix.len() as u64);
-                max_suffix_len = cmp::max(max_suffix_len, suffix.len() as u64);
-            }
-            _ => {}
-        }
-    }
-
-    cmp::max(max_fixed_len + 1, max_prefix_len + max_suffix_len)
-}
-
 /// An inclusive interval, used for precise integer exhaustiveness checking.
 /// `IntRange`s always store a contiguous range. This means that values are
 /// encoded such that `0` encodes the minimum value for the integer,
@@ -1508,20 +1561,19 @@ pub fn is_useful<'p, 'a, 'tcx>(
         // introducing uninhabited patterns for inaccessible fields. We
         // need to figure out how to model that.
         ty,
-        max_slice_length: max_slice_length(cx, matrix.heads().chain(Some(v.head()))),
         span,
     };
 
     debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v.head());
 
-    if let Some(constructors) = pat_constructors(cx, v.head(), pcx) {
-        debug!("is_useful - expanding constructors: {:#?}", constructors);
+    if let Some(constructor) = pat_constructor(cx, v.head(), pcx) {
+        debug!("is_useful - expanding constructor: {:#?}", constructor);
         split_grouped_constructors(
             cx.tcx,
             cx.param_env,
-            constructors,
+            pcx,
+            vec![constructor],
             matrix,
-            pcx.ty,
             pcx.span,
             Some(hir_id),
         )
@@ -1533,7 +1585,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
         debug!("is_useful - expanding wildcard");
 
         let used_ctors: Vec<Constructor<'_>> =
-            matrix.heads().flat_map(|p| pat_constructors(cx, p, pcx).unwrap_or(vec![])).collect();
+            matrix.heads().filter_map(|p| pat_constructor(cx, p, pcx)).collect();
         debug!("used_ctors = {:#?}", used_ctors);
         // `all_ctors` are all the constructors for the given type, which
         // should all be represented (or caught with the wild pattern `_`).
@@ -1583,19 +1635,13 @@ pub fn is_useful<'p, 'a, 'tcx>(
 
         if missing_ctors.is_empty() && !is_non_exhaustive {
             let (all_ctors, _) = missing_ctors.into_inner();
-            split_grouped_constructors(
-                cx.tcx,
-                cx.param_env,
-                all_ctors,
-                matrix,
-                pcx.ty,
-                DUMMY_SP,
-                None,
-            )
-            .into_iter()
-            .map(|c| is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id))
-            .find(|result| result.is_useful())
-            .unwrap_or(NotUseful)
+            split_grouped_constructors(cx.tcx, cx.param_env, pcx, all_ctors, matrix, DUMMY_SP, None)
+                .into_iter()
+                .map(|c| {
+                    is_useful_specialized(cx, matrix, v, c, pcx.ty, witness_preference, hir_id)
+                })
+                .find(|result| result.is_useful())
+                .unwrap_or(NotUseful)
         } else {
             let matrix = matrix.specialize_wildcard();
             let v = v.to_tail();
@@ -1673,7 +1719,7 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
 ) -> Usefulness<'tcx> {
     debug!("is_useful_specialized({:#?}, {:#?}, {:?})", v, ctor, lty);
 
-    let ctor_wild_subpatterns_owned: Vec<_> = ctor.wildcard_subpatterns(cx, lty).collect();
+    let ctor_wild_subpatterns_owned: Vec<_> = ctor.wildcard_subpatterns(cx, lty);
     let ctor_wild_subpatterns: Vec<_> = ctor_wild_subpatterns_owned.iter().collect();
     let matrix = matrix.specialize_constructor(cx, &ctor, &ctor_wild_subpatterns);
     v.specialize_constructor(cx, &ctor, &ctor_wild_subpatterns)
@@ -1682,44 +1728,39 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
         .unwrap_or(NotUseful)
 }
 
-/// Determines the constructors that the given pattern can be specialized to.
-///
-/// In most cases, there's only one constructor that a specific pattern
-/// represents, such as a specific enum variant or a specific literal value.
-/// Slice patterns, however, can match slices of different lengths. For instance,
-/// `[a, b, tail @ ..]` can match a slice of length 2, 3, 4 and so on.
-///
+/// Determines the constructor that the given pattern can be specialized to.
 /// Returns `None` in case of a catch-all, which can't be specialized.
-fn pat_constructors<'tcx>(
+fn pat_constructor<'tcx>(
     cx: &mut MatchCheckCtxt<'_, 'tcx>,
     pat: &Pat<'tcx>,
     pcx: PatCtxt<'tcx>,
-) -> Option<Vec<Constructor<'tcx>>> {
+) -> Option<Constructor<'tcx>> {
     match *pat.kind {
-        PatKind::AscribeUserType { ref subpattern, .. } => pat_constructors(cx, subpattern, pcx),
+        PatKind::AscribeUserType { ref subpattern, .. } => pat_constructor(cx, subpattern, pcx),
         PatKind::Binding { .. } | PatKind::Wild => None,
-        PatKind::Leaf { .. } | PatKind::Deref { .. } => Some(vec![Single]),
+        PatKind::Leaf { .. } | PatKind::Deref { .. } => Some(Single),
         PatKind::Variant { adt_def, variant_index, .. } => {
-            Some(vec![Variant(adt_def.variants[variant_index].def_id)])
+            Some(Variant(adt_def.variants[variant_index].def_id))
         }
-        PatKind::Constant { value } => Some(vec![ConstantValue(value, pat.span)]),
-        PatKind::Range(PatRange { lo, hi, end }) => Some(vec![ConstantRange(
+        PatKind::Constant { value } => Some(ConstantValue(value, pat.span)),
+        PatKind::Range(PatRange { lo, hi, end }) => Some(ConstantRange(
             lo.eval_bits(cx.tcx, cx.param_env, lo.ty),
             hi.eval_bits(cx.tcx, cx.param_env, hi.ty),
             lo.ty,
             end,
             pat.span,
-        )]),
+        )),
         PatKind::Array { .. } => match pcx.ty.kind {
-            ty::Array(_, length) => Some(vec![Slice(length.eval_usize(cx.tcx, cx.param_env))]),
+            ty::Array(_, length) => Some(FixedLenSlice(length.eval_usize(cx.tcx, cx.param_env))),
             _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pcx.ty),
         },
         PatKind::Slice { ref prefix, ref slice, ref suffix } => {
-            let pat_len = prefix.len() as u64 + suffix.len() as u64;
+            let prefix = prefix.len() as u64;
+            let suffix = suffix.len() as u64;
             if slice.is_some() {
-                Some((pat_len..pcx.max_slice_length + 1).map(Slice).collect())
+                Some(VarLenSlice(prefix, suffix))
             } else {
-                Some(vec![Slice(pat_len)])
+                Some(FixedLenSlice(prefix + suffix))
             }
         }
         PatKind::Or { .. } => {
@@ -1728,68 +1769,6 @@ fn pat_constructors<'tcx>(
     }
 }
 
-/// This computes the types of the sub patterns that a constructor should be
-/// expanded to.
-///
-/// For instance, a tuple pattern (43u32, 'a') has sub pattern types [u32, char].
-fn constructor_sub_pattern_tys<'a, 'tcx>(
-    cx: &MatchCheckCtxt<'a, 'tcx>,
-    ctor: &Constructor<'tcx>,
-    ty: Ty<'tcx>,
-) -> Vec<Ty<'tcx>> {
-    debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty);
-    match ty.kind {
-        ty::Tuple(ref fs) => fs.into_iter().map(|t| t.expect_ty()).collect(),
-        ty::Slice(ty) | ty::Array(ty, _) => match *ctor {
-            Slice(length) => (0..length).map(|_| ty).collect(),
-            ConstantValue(..) => vec![],
-            _ => bug!("bad slice pattern {:?} {:?}", ctor, ty),
-        },
-        ty::Ref(_, rty, _) => vec![rty],
-        ty::Adt(adt, substs) => {
-            if adt.is_box() {
-                // Use T as the sub pattern type of Box<T>.
-                vec![substs.type_at(0)]
-            } else {
-                let variant = &adt.variants[ctor.variant_index_for_adt(cx, adt)];
-                let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !cx.is_local(ty);
-                variant
-                    .fields
-                    .iter()
-                    .map(|field| {
-                        let is_visible =
-                            adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
-                        let is_uninhabited = cx.is_uninhabited(field.ty(cx.tcx, substs));
-                        match (is_visible, is_non_exhaustive, is_uninhabited) {
-                            // Treat all uninhabited types in non-exhaustive variants as `TyErr`.
-                            (_, true, true) => cx.tcx.types.err,
-                            // Treat all non-visible fields as `TyErr`. They can't appear in any
-                            // other pattern from this match (because they are private), so their
-                            // type does not matter - but we don't want to know they are
-                            // uninhabited.
-                            (false, ..) => cx.tcx.types.err,
-                            (true, ..) => {
-                                let ty = field.ty(cx.tcx, substs);
-                                match ty.kind {
-                                    // If the field type returned is an array of an unknown size
-                                    // return an TyErr.
-                                    ty::Array(_, len)
-                                        if len.try_eval_usize(cx.tcx, cx.param_env).is_none() =>
-                                    {
-                                        cx.tcx.types.err
-                                    }
-                                    _ => ty,
-                                }
-                            }
-                        }
-                    })
-                    .collect()
-            }
-        }
-        _ => vec![],
-    }
-}
-
 // checks whether a constant is equal to a user-written slice pattern. Only supports byte slices,
 // meaning all other types will compare unequal and thus equal patterns often do not cause the
 // second pattern to lint about unreachable match arms.
@@ -1900,21 +1879,22 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>)
 ///
 /// `hir_id` is `None` when we're evaluating the wildcard pattern, do not lint for overlapping in
 /// ranges that case.
+///
+/// This also splits variable-length slices into fixed-length slices.
 fn split_grouped_constructors<'p, 'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
+    pcx: PatCtxt<'tcx>,
     ctors: Vec<Constructor<'tcx>>,
     matrix: &Matrix<'p, 'tcx>,
-    ty: Ty<'tcx>,
     span: Span,
     hir_id: Option<HirId>,
 ) -> Vec<Constructor<'tcx>> {
+    let ty = pcx.ty;
     let mut split_ctors = Vec::with_capacity(ctors.len());
 
     for ctor in ctors.into_iter() {
         match ctor {
-            // For now, only ranges may denote groups of "subconstructors", so we only need to
-            // special-case constant ranges.
             ConstantRange(..) if should_treat_range_exhaustively(tcx, &ctor) => {
                 // We only care about finding all the subranges within the range of the constructor
                 // range. Anything else is irrelevant, because it is guaranteed to result in
@@ -1996,6 +1976,121 @@ fn split_grouped_constructors<'p, 'tcx>(
                     split_ctors.push(IntRange::range_to_ctor(tcx, ty, range, span));
                 }
             }
+            VarLenSlice(self_prefix, self_suffix) => {
+                // The exhaustiveness-checking paper does not include any details on
+                // checking variable-length slice patterns. However, they are matched
+                // by an infinite collection of fixed-length array patterns.
+                //
+                // Checking the infinite set directly would take an infinite amount
+                // of time. However, it turns out that for each finite set of
+                // patterns `P`, all sufficiently large array lengths are equivalent:
+                //
+                // Each slice `s` with a "sufficiently-large" length `l ≥ L` that applies
+                // to exactly the subset `Pₜ` of `P` can be transformed to a slice
+                // `sₘ` for each sufficiently-large length `m` that applies to exactly
+                // the same subset of `P`.
+                //
+                // Because of that, each witness for reachability-checking from one
+                // of the sufficiently-large lengths can be transformed to an
+                // equally-valid witness from any other length, so we only have
+                // to check slice lengths from the "minimal sufficiently-large length"
+                // and below.
+                //
+                // Note that the fact that there is a *single* `sₘ` for each `m`
+                // not depending on the specific pattern in `P` is important: if
+                // you look at the pair of patterns
+                //     `[true, ..]`
+                //     `[.., false]`
+                // Then any slice of length ≥1 that matches one of these two
+                // patterns can be trivially turned to a slice of any
+                // other length ≥1 that matches them and vice-versa - for
+                // but the slice from length 2 `[false, true]` that matches neither
+                // of these patterns can't be turned to a slice from length 1 that
+                // matches neither of these patterns, so we have to consider
+                // slices from length 2 there.
+                //
+                // Now, to see that that length exists and find it, observe that slice
+                // patterns are either "fixed-length" patterns (`[_, _, _]`) or
+                // "variable-length" patterns (`[_, .., _]`).
+                //
+                // For fixed-length patterns, all slices with lengths *longer* than
+                // the pattern's length have the same outcome (of not matching), so
+                // as long as `L` is greater than the pattern's length we can pick
+                // any `sₘ` from that length and get the same result.
+                //
+                // For variable-length patterns, the situation is more complicated,
+                // because as seen above the precise value of `sₘ` matters.
+                //
+                // However, for each variable-length pattern `p` with a prefix of length
+                // `plₚ` and suffix of length `slₚ`, only the first `plₚ` and the last
+                // `slₚ` elements are examined.
+                //
+                // Therefore, as long as `L` is positive (to avoid concerns about empty
+                // types), all elements after the maximum prefix length and before
+                // the maximum suffix length are not examined by any variable-length
+                // pattern, and therefore can be added/removed without affecting
+                // them - creating equivalent patterns from any sufficiently-large
+                // length.
+                //
+                // Of course, if fixed-length patterns exist, we must be sure
+                // that our length is large enough to miss them all, so
+                // we can pick `L = max(max(FIXED_LEN)+1, max(PREFIX_LEN) + max(SUFFIX_LEN))`
+                //
+                // for example, with the above pair of patterns, all elements
+                // but the first and last can be added/removed, so any
+                // witness of length ≥2 (say, `[false, false, true]`) can be
+                // turned to a witness from any other length ≥2.
+
+                let mut max_prefix_len = self_prefix;
+                let mut max_suffix_len = self_suffix;
+                let mut max_fixed_len = 0;
+
+                for row in matrix.heads() {
+                    match *row.kind {
+                        PatKind::Constant { value } => {
+                            // extract the length of an array/slice from a constant
+                            match (value.val, &value.ty.kind) {
+                                (_, ty::Array(_, n)) => {
+                                    max_fixed_len =
+                                        cmp::max(max_fixed_len, n.eval_usize(tcx, param_env))
+                                }
+                                (ConstValue::Slice { start, end, .. }, ty::Slice(_)) => {
+                                    max_fixed_len = cmp::max(max_fixed_len, (end - start) as u64)
+                                }
+                                _ => {}
+                            }
+                        }
+                        PatKind::Slice { ref prefix, slice: None, ref suffix } => {
+                            let fixed_len = prefix.len() as u64 + suffix.len() as u64;
+                            max_fixed_len = cmp::max(max_fixed_len, fixed_len);
+                        }
+                        PatKind::Slice { ref prefix, slice: Some(_), ref suffix } => {
+                            max_prefix_len = cmp::max(max_prefix_len, prefix.len() as u64);
+                            max_suffix_len = cmp::max(max_suffix_len, suffix.len() as u64);
+                        }
+                        _ => {}
+                    }
+                }
+
+                // For diagnostics, we keep the prefix and suffix lengths separate, so in the case
+                // where `max_fixed_len + 1` is the largest, we adapt `max_prefix_len` accordingly,
+                // so that `L = max_prefix_len + max_suffix_len`.
+                if max_fixed_len + 1 >= max_prefix_len + max_suffix_len {
+                    // The subtraction can't overflow thanks to the above check.
+                    // The new `max_prefix_len` is also guaranteed to be larger than its previous
+                    // value.
+                    max_prefix_len = max_fixed_len + 1 - max_suffix_len;
+                }
+
+                // `ctor` originally covered the range `(self_prefix + self_suffix..infinity)`. We
+                // now split it into two: lengths smaller than `max_prefix_len + max_suffix_len`
+                // are treated independently as fixed-lengths slices, and lengths above are
+                // captured by a final VarLenSlice constructor.
+                split_ctors.extend(
+                    (self_prefix + self_suffix..max_prefix_len + max_suffix_len).map(FixedLenSlice),
+                );
+                split_ctors.push(VarLenSlice(max_prefix_len, max_suffix_len));
+            }
             // Any other constructor can be used unchanged.
             _ => split_ctors.push(ctor),
         }
@@ -2238,7 +2333,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
 
         PatKind::Array { ref prefix, ref slice, ref suffix }
         | PatKind::Slice { ref prefix, ref slice, ref suffix } => match *constructor {
-            Slice(..) => {
+            FixedLenSlice(..) | VarLenSlice(..) => {
                 let pat_len = prefix.len() + suffix.len();
                 if let Some(slice_count) = ctor_wild_subpatterns.len().checked_sub(pat_len) {
                     if slice_count == 0 || slice.is_some() {
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 9d370554e86..ffb3ae44ae1 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -18,7 +18,7 @@ use rustc::hir::{self, Pat};
 
 use std::slice;
 
-use syntax_pos::{MultiSpan, Span, DUMMY_SP};
+use syntax_pos::{MultiSpan, Span};
 
 crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
     let body_id = match tcx.hir().as_local_hir_id(def_id) {
@@ -351,7 +351,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_>, pat: &Pa
     pat.walk(|p| {
         if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
             if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) {
-                if bm != ty::BindByValue(hir::MutImmutable) {
+                if bm != ty::BindByValue(hir::Mutability::Immutable) {
                     // Nothing to check.
                     return true;
                 }
@@ -491,7 +491,7 @@ fn check_not_useful(
     matrix: &Matrix<'_, 'tcx>,
     hir_id: HirId,
 ) -> Result<(), Vec<super::Pat<'tcx>>> {
-    let wild_pattern = super::Pat { ty, span: DUMMY_SP, kind: box PatKind::Wild };
+    let wild_pattern = super::Pat::wildcard_from_ty(ty);
     match is_useful(cx, matrix, &PatStack::from_pattern(&wild_pattern), ConstructWitness, hir_id) {
         NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable.
         UsefulWithWitness(pats) => Err(if pats.is_empty() {
@@ -548,7 +548,7 @@ fn joined_uncovered_patterns(witnesses: &[super::Pat<'_>]) -> String {
 }
 
 fn pattern_not_covered_label(witnesses: &[super::Pat<'_>], joined_patterns: &str) -> String {
-    format!("pattern{} {} not covered", rustc_errors::pluralise!(witnesses.len()), joined_patterns)
+    format!("pattern{} {} not covered", rustc_errors::pluralize!(witnesses.len()), joined_patterns)
 }
 
 /// Point at the definition of non-covered `enum` variants.
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 1ecc78ba227..f613f6f4b99 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -26,7 +26,7 @@ use rustc_index::vec::Idx;
 use std::cmp::Ordering;
 use std::fmt;
 use syntax::ast;
-use syntax_pos::Span;
+use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Clone, Debug)]
 pub enum PatternError {
@@ -55,6 +55,11 @@ pub struct Pat<'tcx> {
     pub kind: Box<PatKind<'tcx>>,
 }
 
+impl<'tcx> Pat<'tcx> {
+    pub(crate) fn wildcard_from_ty(ty: Ty<'tcx>) -> Self {
+        Pat { ty, span: DUMMY_SP, kind: Box::new(PatKind::Wild) }
+    }
+}
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub struct PatTyProj<'tcx> {
@@ -293,10 +298,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                 match self.ty.kind {
                     ty::Adt(def, _) if def.is_box() => write!(f, "box ")?,
                     ty::Ref(_, _, mutbl) => {
-                        write!(f, "&")?;
-                        if mutbl == hir::MutMutable {
-                            write!(f, "mut ")?;
-                        }
+                        write!(f, "&{}", mutbl.prefix_str())?;
                     }
                     _ => bug!("{} is a bad Deref pattern type", self.ty)
                 }
@@ -594,14 +596,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
                                                          .expect("missing binding mode");
                 let (mutability, mode) = match bm {
-                    ty::BindByValue(hir::MutMutable) =>
+                    ty::BindByValue(hir::Mutability::Mutable) =>
                         (Mutability::Mut, BindingMode::ByValue),
-                    ty::BindByValue(hir::MutImmutable) =>
+                    ty::BindByValue(hir::Mutability::Immutable) =>
                         (Mutability::Not, BindingMode::ByValue),
-                    ty::BindByReference(hir::MutMutable) =>
+                    ty::BindByReference(hir::Mutability::Mutable) =>
                         (Mutability::Not, BindingMode::ByRef(
                             BorrowKind::Mut { allow_two_phase_borrow: false })),
-                    ty::BindByReference(hir::MutImmutable) =>
+                    ty::BindByReference(hir::Mutability::Immutable) =>
                         (Mutability::Not, BindingMode::ByRef(
                             BorrowKind::Shared)),
                 };
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 9ab347957f9..1fb8b3ca63f 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -26,7 +26,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.unsize_into(src, dest)?;
             }
 
-            Misc | Pointer(PointerCast::MutToConstPointer) => {
+            Misc
+            | Pointer(PointerCast::MutToConstPointer)
+            | Pointer(PointerCast::ArrayToPointer) => {
                 let src = self.read_immediate(src)?;
                 let res = self.cast_immediate(src, dest.layout)?;
                 self.write_immediate(res, dest)?;
@@ -260,7 +262,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         match (&src_pointee_ty.kind, &dest_pointee_ty.kind) {
             (&ty::Array(_, length), &ty::Slice(_)) => {
-                let ptr = self.read_immediate(src)?.to_scalar_ptr()?;
+                let ptr = self.read_immediate(src)?.to_scalar()?;
                 // u64 cast is from usize to u64, which is always good
                 let val = Immediate::new_slice(
                     ptr,
@@ -279,7 +281,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             (_, &ty::Dynamic(ref data, _)) => {
                 // Initial cast from sized to dyn trait
                 let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
-                let ptr = self.read_immediate(src)?.to_scalar_ptr()?;
+                let ptr = self.read_immediate(src)?.to_scalar()?;
                 let val = Immediate::new_dyn_trait(ptr, vtable);
                 self.write_immediate(val, dest)
             }
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index d929e958f05..8e901068a8d 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -447,7 +447,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
 
             ty::Slice(_) | ty::Str => {
-                let len = metadata.expect("slice fat ptr must have vtable").to_usize(self)?;
+                let len = metadata.expect("slice fat ptr must have length").to_machine_usize(self)?;
                 let elem = layout.field(self, 0)?;
 
                 // Make sure the slice is not too big.
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 924529d7f55..68bb0a3e435 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -192,20 +192,18 @@ for
         let ty = mplace.layout.ty;
         if let ty::Ref(_, referenced_ty, mutability) = ty.kind {
             let value = self.ecx.read_immediate(mplace.into())?;
+            let mplace = self.ecx.ref_to_mplace(value)?;
             // Handle trait object vtables
-            if let Ok(meta) = value.to_meta() {
-                if let ty::Dynamic(..) =
-                    self.ecx.tcx.struct_tail_erasing_lifetimes(
-                        referenced_ty, self.ecx.param_env).kind
-                {
-                    if let Ok(vtable) = meta.unwrap().to_ptr() {
-                        // explitly choose `Immutable` here, since vtables are immutable, even
-                        // if the reference of the fat pointer is mutable
-                        self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
-                    }
+            if let ty::Dynamic(..) =
+                self.ecx.tcx.struct_tail_erasing_lifetimes(
+                    referenced_ty, self.ecx.param_env).kind
+            {
+                if let Ok(vtable) = mplace.meta.unwrap().to_ptr() {
+                    // explitly choose `Immutable` here, since vtables are immutable, even
+                    // if the reference of the fat pointer is mutable
+                    self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
                 }
             }
-            let mplace = self.ecx.ref_to_mplace(value)?;
             // Check if we have encountered this pointer+layout combination before.
             // Only recurse for allocation-backed pointers.
             if let Scalar::Ptr(ptr) = mplace.ptr {
@@ -216,21 +214,21 @@ for
                 // const qualification enforces it. We can lift it in the future.
                 match (self.mode, mutability) {
                     // immutable references are fine everywhere
-                    (_, hir::Mutability::MutImmutable) => {},
+                    (_, hir::Mutability::Immutable) => {},
                     // all is "good and well" in the unsoundness of `static mut`
 
                     // mutable references are ok in `static`. Either they are treated as immutable
                     // because they are behind an immutable one, or they are behind an `UnsafeCell`
                     // and thus ok.
-                    (InternMode::Static, hir::Mutability::MutMutable) => {},
+                    (InternMode::Static, hir::Mutability::Mutable) => {},
                     // we statically prevent `&mut T` via `const_qualif` and double check this here
-                    (InternMode::ConstBase, hir::Mutability::MutMutable) |
-                    (InternMode::Const, hir::Mutability::MutMutable) => {
+                    (InternMode::ConstBase, hir::Mutability::Mutable) |
+                    (InternMode::Const, hir::Mutability::Mutable) => {
                         match referenced_ty.kind {
                             ty::Array(_, n)
                                 if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
                             ty::Slice(_)
-                                if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
+                                if mplace.meta.unwrap().to_machine_usize(self.ecx)? == 0 => {}
                             _ => bug!("const qualif failed to prevent mutable references"),
                         }
                     },
@@ -243,7 +241,7 @@ for
                     // If there's an immutable reference or we are inside a static, then our
                     // mutable reference is equivalent to an immutable one. As an example:
                     // `&&mut Foo` is semantically equivalent to `&&Foo`
-                    (Mutability::Mutable, hir::Mutability::MutMutable) => Mutability::Mutable,
+                    (Mutability::Mutable, hir::Mutability::Mutable) => Mutability::Mutable,
                     _ => Mutability::Immutable,
                 };
                 // Recursing behind references changes the intern mode for constants in order to
@@ -275,9 +273,9 @@ pub fn intern_const_alloc_recursive(
 ) -> InterpResult<'tcx> {
     let tcx = ecx.tcx;
     let (base_mutability, base_intern_mode) = match place_mut {
-        Some(hir::Mutability::MutImmutable) => (Mutability::Immutable, InternMode::Static),
+        Some(hir::Mutability::Immutable) => (Mutability::Immutable, InternMode::Static),
         // `static mut` doesn't care about interior mutability, it's mutable anyway
-        Some(hir::Mutability::MutMutable) => (Mutability::Mutable, InternMode::Static),
+        Some(hir::Mutability::Mutable) => (Mutability::Mutable, InternMode::Static),
         // consts, promoteds. FIXME: what about array lengths, array initializers?
         None => (Mutability::Immutable, InternMode::ConstBase),
     };
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 04032847385..39f10d8e604 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -95,10 +95,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, bool> {
         let substs = instance.substs;
 
-        let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
+        let intrinsic_name = &*self.tcx.item_name(instance.def_id()).as_str();
         match intrinsic_name {
             "caller_location" => {
-                let caller = self.tcx.sess.source_map().lookup_char_pos(span.lo());
+                let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
+                let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
                 let location = self.alloc_caller_location(
                     Symbol::intern(&caller.file.name.to_string()),
                     caller.line as u32,
@@ -262,8 +263,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // This is the dual to the special exception for offset-by-0
                 // in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`).
                 if a.is_bits() && b.is_bits() {
-                    let a = a.to_usize(self)?;
-                    let b = b.to_usize(self)?;
+                    let a = a.to_machine_usize(self)?;
+                    let b = b.to_machine_usize(self)?;
                     if a == b && a != 0 {
                         self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?;
                         return Ok(true);
diff --git a/src/librustc_mir/interpret/intrinsics/caller_location.rs b/src/librustc_mir/interpret/intrinsics/caller_location.rs
index 249d2f9ff53..88bfcd63129 100644
--- a/src/librustc_mir/interpret/intrinsics/caller_location.rs
+++ b/src/librustc_mir/interpret/intrinsics/caller_location.rs
@@ -37,7 +37,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let col_out = self.force_ptr(self.mplace_field(location, 2)?.ptr)?;
 
         let layout = &self.tcx.data_layout;
-        let alloc = self.memory.get_mut(file_ptr_out.alloc_id)?;
+        // We just allocated this, so we can skip the bounds checks.
+        let alloc = self.memory.get_raw_mut(file_ptr_out.alloc_id)?;
 
         alloc.write_scalar(layout, file_ptr_out, file.into(), ptr_size)?;
         alloc.write_scalar(layout, file_len_out, file_len.into(), ptr_size)?;
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index d113ee33162..e929b085583 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -210,7 +210,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         let new_ptr = self.allocate(new_size, new_align, kind);
         let old_size = match old_size_and_align {
             Some((size, _align)) => size,
-            None => self.get(ptr.alloc_id)?.size,
+            None => self.get_raw(ptr.alloc_id)?.size,
         };
         self.copy(
             ptr,
@@ -314,16 +314,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         align: Align,
     ) -> InterpResult<'tcx, Option<Pointer<M::PointerTag>>> {
         let align = if M::CHECK_ALIGN { Some(align) } else { None };
-        self.check_ptr_access_align(sptr, size, align)
+        self.check_ptr_access_align(sptr, size, align, CheckInAllocMsg::MemoryAccessTest)
     }
 
     /// Like `check_ptr_access`, but *definitely* checks alignment when `align`
-    /// is `Some` (overriding `M::CHECK_ALIGN`).
-    pub(super) fn check_ptr_access_align(
+    /// is `Some` (overriding `M::CHECK_ALIGN`). Also lets the caller control
+    /// the error message for the out-of-bounds case.
+    pub fn check_ptr_access_align(
         &self,
         sptr: Scalar<M::PointerTag>,
         size: Size,
         align: Option<Align>,
+        msg: CheckInAllocMsg,
     ) -> InterpResult<'tcx, Option<Pointer<M::PointerTag>>> {
         fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
             if offset % align.bytes() == 0 {
@@ -368,7 +370,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                 // It is sufficient to check this for the end pointer. The addition
                 // checks for overflow.
                 let end_ptr = ptr.offset(size, self)?;
-                end_ptr.check_inbounds_alloc(allocation_size, CheckInAllocMsg::MemoryAccessTest)?;
+                end_ptr.check_inbounds_alloc(allocation_size, msg)?;
                 // Test align. Check this last; if both bounds and alignment are violated
                 // we want the error to be about the bounds.
                 if let Some(align) = align {
@@ -478,7 +480,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         ).0)
     }
 
-    pub fn get(
+    /// Gives raw access to the `Allocation`, without bounds or alignment checks.
+    /// Use the higher-level, `PlaceTy`- and `OpTy`-based APIs in `InterpCtx` instead!
+    pub fn get_raw(
         &self,
         id: AllocId,
     ) -> InterpResult<'tcx, &Allocation<M::PointerTag, M::AllocExtra>> {
@@ -511,7 +515,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         }
     }
 
-    pub fn get_mut(
+    /// Gives raw mutable access to the `Allocation`, without bounds or alignment checks.
+    /// Use the higher-level, `PlaceTy`- and `OpTy`-based APIs in `InterpCtx` instead!
+    pub fn get_raw_mut(
         &mut self,
         id: AllocId,
     ) -> InterpResult<'tcx, &mut Allocation<M::PointerTag, M::AllocExtra>> {
@@ -553,7 +559,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         liveness: AllocCheck,
     ) -> InterpResult<'static, (Size, Align)> {
         // # Regular allocations
-        // Don't use `self.get` here as that will
+        // Don't use `self.get_raw` here as that will
         // a) cause cycles in case `id` refers to a static
         // b) duplicate a static's allocation in miri
         if let Some((_, alloc)) = self.alloc_map.get(id) {
@@ -625,7 +631,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
     }
 
     pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {
-        self.get_mut(id)?.mutability = Mutability::Immutable;
+        self.get_raw_mut(id)?.mutability = Mutability::Immutable;
         Ok(())
     }
 
@@ -774,7 +780,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             Some(ptr) => ptr,
             None => return Ok(&[]), // zero-sized access
         };
-        self.get(ptr.alloc_id)?.get_bytes(self, ptr, size)
+        self.get_raw(ptr.alloc_id)?.get_bytes(self, ptr, size)
     }
 
     /// Reads a 0-terminated sequence of bytes from memory. Returns them as a slice.
@@ -782,7 +788,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
     /// Performs appropriate bounds checks.
     pub fn read_c_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, &[u8]> {
         let ptr = self.force_ptr(ptr)?; // We need to read at least 1 byte, so we *need* a ptr.
-        self.get(ptr.alloc_id)?.read_c_str(self, ptr)
+        self.get_raw(ptr.alloc_id)?.read_c_str(self, ptr)
     }
 
     /// Writes the given stream of bytes into memory.
@@ -802,7 +808,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             None => return Ok(()), // zero-sized access
         };
         let tcx = self.tcx.tcx;
-        self.get_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
+        self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
     }
 
     /// Expects the caller to have checked bounds and alignment.
@@ -830,16 +836,16 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // since we don't want to keep any relocations at the target.
         // (`get_bytes_with_undef_and_ptr` below checks that there are no
         // relocations overlapping the edges; those would not be handled correctly).
-        let relocations = self.get(src.alloc_id)?
+        let relocations = self.get_raw(src.alloc_id)?
             .prepare_relocation_copy(self, src, size, dest, length);
 
         let tcx = self.tcx.tcx;
 
         // This checks relocation edges on the src.
-        let src_bytes = self.get(src.alloc_id)?
+        let src_bytes = self.get_raw(src.alloc_id)?
             .get_bytes_with_undef_and_ptr(&tcx, src, size)?
             .as_ptr();
-        let dest_bytes = self.get_mut(dest.alloc_id)?
+        let dest_bytes = self.get_raw_mut(dest.alloc_id)?
             .get_bytes_mut(&tcx, dest, size * length)?
             .as_mut_ptr();
 
@@ -878,7 +884,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // copy definedness to the destination
         self.copy_undef_mask(src, dest, size, length)?;
         // copy the relocations to the destination
-        self.get_mut(dest.alloc_id)?.mark_relocation_range(relocations);
+        self.get_raw_mut(dest.alloc_id)?.mark_relocation_range(relocations);
 
         Ok(())
     }
@@ -897,11 +903,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // The bits have to be saved locally before writing to dest in case src and dest overlap.
         assert_eq!(size.bytes() as usize as u64, size.bytes());
 
-        let src_alloc = self.get(src.alloc_id)?;
+        let src_alloc = self.get_raw(src.alloc_id)?;
         let compressed = src_alloc.compress_undef_range(src, size);
 
         // now fill in all the data
-        let dest_allocation = self.get_mut(dest.alloc_id)?;
+        let dest_allocation = self.get_raw_mut(dest.alloc_id)?;
         dest_allocation.mark_compressed_undef_range(&compressed, dest, size, repeat);
 
         Ok(())
@@ -913,7 +919,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
         match scalar {
             Scalar::Ptr(ptr) => Ok(ptr),
-            _ => M::int_to_ptr(&self, scalar.to_usize(self)?)
+            _ => M::int_to_ptr(&self, scalar.to_machine_usize(self)?)
         }
     }
 
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index ae23971849e..79762b87b0a 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -82,26 +82,6 @@ impl<'tcx, Tag> Immediate<Tag> {
             Immediate::ScalarPair(a, b) => Ok((a.not_undef()?, b.not_undef()?))
         }
     }
-
-    /// Converts the immediate into a pointer (or a pointer-sized integer).
-    /// Throws away the second half of a ScalarPair!
-    #[inline]
-    pub fn to_scalar_ptr(self) -> InterpResult<'tcx, Scalar<Tag>> {
-        match self {
-            Immediate::Scalar(ptr) |
-            Immediate::ScalarPair(ptr, _) => ptr.not_undef(),
-        }
-    }
-
-    /// Converts the value into its metadata.
-    /// Throws away the first half of a ScalarPair!
-    #[inline]
-    pub fn to_meta(self) -> InterpResult<'tcx, Option<Scalar<Tag>>> {
-        Ok(match self {
-            Immediate::Scalar(_) => None,
-            Immediate::ScalarPair(_, meta) => Some(meta.not_undef()?),
-        })
-    }
 }
 
 // ScalarPair needs a type to interpret, so we often have an immediate and a type together
@@ -268,7 +248,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         match mplace.layout.abi {
             layout::Abi::Scalar(..) => {
                 let scalar = self.memory
-                    .get(ptr.alloc_id)?
+                    .get_raw(ptr.alloc_id)?
                     .read_scalar(self, ptr, mplace.layout.size)?;
                 Ok(Some(ImmTy {
                     imm: scalar.into(),
@@ -286,10 +266,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 assert!(b_offset.bytes() > 0); // we later use the offset to tell apart the fields
                 let b_ptr = ptr.offset(b_offset, self)?;
                 let a_val = self.memory
-                    .get(ptr.alloc_id)?
+                    .get_raw(ptr.alloc_id)?
                     .read_scalar(self, a_ptr, a_size)?;
                 let b_val = self.memory
-                    .get(ptr.alloc_id)?
+                    .get_raw(ptr.alloc_id)?
                     .read_scalar(self, b_ptr, b_size)?;
                 Ok(Some(ImmTy {
                     imm: Immediate::ScalarPair(a_val, b_val),
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 0289c52fd37..0bd47edc046 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -195,7 +195,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
             // We need to consult `meta` metadata
             match self.layout.ty.kind {
                 ty::Slice(..) | ty::Str =>
-                    return self.mplace.meta.unwrap().to_usize(cx),
+                    return self.mplace.meta.unwrap().to_machine_usize(cx),
                 _ => bug!("len not supported on unsized type {:?}", self.layout.ty),
             }
         } else {
@@ -287,17 +287,23 @@ where
         &self,
         val: ImmTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
-        let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
+        let pointee_type = val.layout.ty.builtin_deref(true)
+            .expect("`ref_to_mplace` called on non-ptr type")
+            .ty;
         let layout = self.layout_of(pointee_type)?;
+        let (ptr, meta) = match *val {
+            Immediate::Scalar(ptr) => (ptr.not_undef()?, None),
+            Immediate::ScalarPair(ptr, meta) => (ptr.not_undef()?, Some(meta.not_undef()?)),
+        };
 
         let mplace = MemPlace {
-            ptr: val.to_scalar_ptr()?,
+            ptr,
             // We could use the run-time alignment here. For now, we do not, because
             // the point of tracking the alignment here is to make sure that the *static*
             // alignment information emitted with the loads is correct. The run-time
             // alignment can only be more restrictive.
             align: layout.align.abi,
-            meta: val.to_meta()?,
+            meta,
         };
         Ok(MPlaceTy { mplace, layout })
     }
@@ -802,7 +808,7 @@ where
                     _ => bug!("write_immediate_to_mplace: invalid Scalar layout: {:#?}",
                             dest.layout)
                 }
-                self.memory.get_mut(ptr.alloc_id)?.write_scalar(
+                self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar(
                     tcx, ptr, scalar, dest.layout.size
                 )
             }
@@ -824,10 +830,10 @@ where
                 // fields do not match the `ScalarPair` components.
 
                 self.memory
-                    .get_mut(ptr.alloc_id)?
+                    .get_raw_mut(ptr.alloc_id)?
                     .write_scalar(tcx, ptr, a_val, a_size)?;
                 self.memory
-                    .get_mut(b_ptr.alloc_id)?
+                    .get_raw_mut(b_ptr.alloc_id)?
                     .write_scalar(tcx, b_ptr, b_val, b_size)
             }
         }
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index 7ce151e087a..1df98f079cc 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -392,7 +392,7 @@ impl<'b, 'mir, 'tcx> SnapshotContext<'b>
     for Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>
 {
     fn resolve(&'b self, id: &AllocId) -> Option<&'b Allocation> {
-        self.get(*id).ok()
+        self.get_raw(*id).ok()
     }
 }
 
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index d90f2058aa7..e10bb85d52d 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -445,7 +445,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     ptr_size,
                     self.tcx.data_layout.pointer_align.abi,
                 )?.expect("cannot be a ZST");
-                let fn_ptr = self.memory.get(vtable_slot.alloc_id)?
+                let fn_ptr = self.memory.get_raw(vtable_slot.alloc_id)?
                     .read_ptr_sized(self, vtable_slot)?.not_undef()?;
                 let drop_fn = self.memory.get_fn(fn_ptr)?;
 
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index 10b767ebba1..c15425321ec 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -63,35 +63,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let drop = Instance::resolve_drop_in_place(*tcx, ty);
         let drop = self.memory.create_fn_alloc(FnVal::Instance(drop));
 
-        // no need to do any alignment checks on the memory accesses below, because we know the
+        // No need to do any alignment checks on the memory accesses below, because we know the
         // allocation is correctly aligned as we created it above. Also we're only offsetting by
         // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
-        self.memory
-            .get_mut(vtable.alloc_id)?
-            .write_ptr_sized(tcx, vtable, Scalar::Ptr(drop).into())?;
-
-        let size_ptr = vtable.offset(ptr_size, self)?;
-        self.memory
-            .get_mut(size_ptr.alloc_id)?
-            .write_ptr_sized(tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?;
-        let align_ptr = vtable.offset(ptr_size * 2, self)?;
-        self.memory
-            .get_mut(align_ptr.alloc_id)?
-            .write_ptr_sized(tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?;
+        let vtable_alloc = self.memory.get_raw_mut(vtable.alloc_id)?;
+        vtable_alloc.write_ptr_sized(tcx, vtable, Scalar::Ptr(drop).into())?;
+
+        let size_ptr = vtable.offset(ptr_size, tcx)?;
+        vtable_alloc.write_ptr_sized(tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?;
+        let align_ptr = vtable.offset(ptr_size * 2, tcx)?;
+        vtable_alloc.write_ptr_sized(tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?;
 
         for (i, method) in methods.iter().enumerate() {
             if let Some((def_id, substs)) = *method {
                 // resolve for vtable: insert shims where needed
                 let instance = ty::Instance::resolve_for_vtable(
-                    *self.tcx,
+                    *tcx,
                     self.param_env,
                     def_id,
                     substs,
                 ).ok_or_else(|| err_inval!(TooGeneric))?;
                 let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
-                let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?;
-                self.memory
-                    .get_mut(method_ptr.alloc_id)?
+                // We cannot use `vtable_allic` as we are creating fn ptrs in this loop.
+                let method_ptr = vtable.offset(ptr_size * (3 + i as u64), tcx)?;
+                self.memory.get_raw_mut(vtable.alloc_id)?
                     .write_ptr_sized(tcx, method_ptr, Scalar::Ptr(fn_ptr).into())?;
             }
         }
@@ -114,7 +109,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             self.tcx.data_layout.pointer_align.abi,
         )?.expect("cannot be a ZST");
         let drop_fn = self.memory
-            .get(vtable.alloc_id)?
+            .get_raw(vtable.alloc_id)?
             .read_ptr_sized(self, vtable)?
             .not_undef()?;
         // We *need* an instance here, no other kind of function value, to be able
@@ -140,7 +135,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             3*pointer_size,
             self.tcx.data_layout.pointer_align.abi,
         )?.expect("cannot be a ZST");
-        let alloc = self.memory.get(vtable.alloc_id)?;
+        let alloc = self.memory.get_raw(vtable.alloc_id)?;
         let size = alloc.read_ptr_sized(
             self,
             vtable.offset(pointer_size, self)?
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 3444fb60f33..d698b2e8d8f 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -16,7 +16,7 @@ use rustc_data_structures::fx::FxHashSet;
 use std::hash::Hash;
 
 use super::{
-    GlobalAlloc, InterpResult,
+    GlobalAlloc, InterpResult, CheckInAllocMsg,
     Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
 };
 
@@ -282,7 +282,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
                 // FIXME: More checks for the vtable.
             }
             ty::Slice(..) | ty::Str => {
-                let _len = try_validation!(meta.unwrap().to_usize(self.ecx),
+                let _len = try_validation!(meta.unwrap().to_machine_usize(self.ecx),
                     "non-integer slice length in wide pointer", self.path);
                 // We do not check that `len * elem_size <= isize::MAX`:
                 // that is only required for references, and there it falls out of the
@@ -388,49 +388,41 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 }
             }
             ty::RawPtr(..) => {
-                // Check pointer part.
-                if self.ref_tracking_for_consts.is_some() {
-                    // Integers/floats in CTFE: For consistency with integers, we do not
-                    // accept undef.
-                    let _ptr = try_validation!(value.to_scalar_ptr(),
-                        "undefined address in raw pointer", self.path);
-                } else {
-                    // Remain consistent with `usize`: Accept anything.
-                }
-
-                // Check metadata.
-                let meta = try_validation!(value.to_meta(),
-                    "uninitialized data in wide pointer metadata", self.path);
-                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
-                if layout.is_unsized() {
-                    self.check_wide_ptr_meta(meta, layout)?;
+                // We are conservative with undef for integers, but try to
+                // actually enforce our current rules for raw pointers.
+                let place = try_validation!(self.ecx.ref_to_mplace(value),
+                    "undefined pointer", self.path);
+                if place.layout.is_unsized() {
+                    self.check_wide_ptr_meta(place.meta, place.layout)?;
                 }
             }
             _ if ty.is_box() || ty.is_region_ptr() => {
                 // Handle wide pointers.
                 // Check metadata early, for better diagnostics
-                let ptr = try_validation!(value.to_scalar_ptr(),
-                    "undefined address in pointer", self.path);
-                let meta = try_validation!(value.to_meta(),
-                    "uninitialized data in wide pointer metadata", self.path);
-                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
-                if layout.is_unsized() {
-                    self.check_wide_ptr_meta(meta, layout)?;
+                let place = try_validation!(self.ecx.ref_to_mplace(value),
+                    "undefined pointer", self.path);
+                if place.layout.is_unsized() {
+                    self.check_wide_ptr_meta(place.meta, place.layout)?;
                 }
                 // Make sure this is dereferencable and all.
-                let (size, align) = self.ecx.size_and_align_of(meta, layout)?
+                let (size, align) = self.ecx.size_and_align_of(place.meta, place.layout)?
                     // for the purpose of validity, consider foreign types to have
                     // alignment and size determined by the layout (size will be 0,
                     // alignment should take attributes into account).
-                    .unwrap_or_else(|| (layout.size, layout.align.abi));
+                    .unwrap_or_else(|| (place.layout.size, place.layout.align.abi));
                 let ptr: Option<_> = match
-                    self.ecx.memory.check_ptr_access_align(ptr, size, Some(align))
+                    self.ecx.memory.check_ptr_access_align(
+                        place.ptr,
+                        size,
+                        Some(align),
+                        CheckInAllocMsg::InboundsTest,
+                    )
                 {
                     Ok(ptr) => ptr,
                     Err(err) => {
                         info!(
                             "{:?} did not pass access check for size {:?}, align {:?}",
-                            ptr, size, align
+                            place.ptr, size, align
                         );
                         match err.kind {
                             err_unsup!(InvalidNullPointerUsage) =>
@@ -454,7 +446,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 };
                 // Recursive checking
                 if let Some(ref mut ref_tracking) = self.ref_tracking_for_consts {
-                    let place = self.ecx.ref_to_mplace(value)?;
                     if let Some(ptr) = ptr { // not a ZST
                         // Skip validation entirely for some external statics
                         let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
@@ -595,6 +586,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                     _ => false,
                 }
             } => {
+                // Optimized handling for arrays of integer/float type.
+
                 // bailing out for zsts is ok, since the array element type can only be int/float
                 if op.layout.is_zst() {
                     return Ok(());
@@ -614,6 +607,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 // Size is not 0, get a pointer.
                 let ptr = self.ecx.force_ptr(mplace.ptr)?;
 
+                // This is the optimization: we just check the entire range at once.
                 // NOTE: Keep this in sync with the handling of integer and float
                 // types above, in `visit_primitive`.
                 // In run-time mode, we accept pointers in here.  This is actually more
@@ -622,8 +616,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 // reject it.  However, that's good: We don't inherently want
                 // to reject those pointers, we just do not have the machinery to
                 // talk about parts of a pointer.
-                // We also accept undef, for consistency with the type-based checks.
-                match self.ecx.memory.get(ptr.alloc_id)?.check_bytes(
+                // We also accept undef, for consistency with the slow path.
+                match self.ecx.memory.get_raw(ptr.alloc_id)?.check_bytes(
                     self.ecx,
                     ptr,
                     size,
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 4d604cb025c..be3bbf46f1c 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -26,6 +26,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(associated_type_bounds)]
 #![feature(range_is_empty)]
 #![feature(stmt_expr_attributes)]
+#![feature(bool_to_option)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 5e31b80bec6..49cdd914234 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1071,7 +1071,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
 
     fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
         match ii.kind {
-            hir::ImplItemKind::Method(hir::MethodSig { .. }, _) => {
+            hir::ImplItemKind::Method(hir::FnSig { .. }, _) => {
                 let def_id = self.tcx.hir().local_def_id(ii.hir_id);
                 self.push_if_root(def_id);
             }
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 177639956f7..2913d6e59eb 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -456,7 +456,7 @@ impl CloneShimBuilder<'tcx> {
             Mutability::Not,
             tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut {
                 ty,
-                mutbl: hir::Mutability::MutImmutable,
+                mutbl: hir::Mutability::Immutable,
             })
         );
 
@@ -736,7 +736,7 @@ fn build_call_shim<'tcx>(
                 Mutability::Not,
                 tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut {
                     ty: sig.inputs()[0],
-                    mutbl: hir::Mutability::MutMutable
+                    mutbl: hir::Mutability::Mutable
                 }),
                 span
             ));
diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs
index 364e23ed8d0..a5b711e75a6 100644
--- a/src/librustc_mir/transform/check_consts/mod.rs
+++ b/src/librustc_mir/transform/check_consts/mod.rs
@@ -82,8 +82,8 @@ impl ConstKind {
 
             HirKind::Const => ConstKind::Const,
 
-            HirKind::Static(hir::MutImmutable) => ConstKind::Static,
-            HirKind::Static(hir::MutMutable) => ConstKind::StaticMut,
+            HirKind::Static(hir::Mutability::Immutable) => ConstKind::Static,
+            HirKind::Static(hir::Mutability::Mutable) => ConstKind::StaticMut,
         };
 
         Some(mode)
diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs
index 840ad303016..496a5679067 100644
--- a/src/librustc_mir/transform/check_consts/qualifs.rs
+++ b/src/librustc_mir/transform/check_consts/qualifs.rs
@@ -123,7 +123,7 @@ pub trait Qualif {
                     if cx.tcx.trait_of_item(def_id).is_some() {
                         Self::in_any_value_of_ty(cx, constant.literal.ty)
                     } else {
-                        let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(def_id);
+                        let bits = cx.tcx.at(constant.span).mir_const_qualif(def_id);
 
                         let qualif = QualifSet(bits).contains::<Self>();
 
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index d9b983ab790..e29239a4536 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -8,7 +8,7 @@ use rustc::ty::cast::CastTy;
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::hir::def_id::DefId;
-use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
+use rustc::lint::builtin::{SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
 use rustc::mir::*;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
 
@@ -208,23 +208,20 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             }
             PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => {
                 if self.tcx.is_mutable_static(def_id) {
-                    self.require_unsafe("use of mutable static",
+                    self.require_unsafe(
+                        "use of mutable static",
                         "mutable statics can be mutated by multiple threads: aliasing \
-                         violations or data races will cause undefined behavior",
-                         UnsafetyViolationKind::General);
+                        violations or data races will cause undefined behavior",
+                        UnsafetyViolationKind::General,
+                    );
                 } else if self.tcx.is_foreign_item(def_id) {
-                    let source_info = self.source_info;
-                    let lint_root =
-                        self.source_scope_local_data[source_info.scope].lint_root;
-                    self.register_violations(&[UnsafetyViolation {
-                        source_info,
-                        description: Symbol::intern("use of extern static"),
-                        details: Symbol::intern(
-                            "extern statics are not controlled by the Rust type system: \
-                            invalid data, aliasing violations or data races will cause \
-                            undefined behavior"),
-                        kind: UnsafetyViolationKind::ExternStatic(lint_root)
-                    }], &[]);
+                    self.require_unsafe(
+                        "use of extern static",
+                        "extern statics are not controlled by the Rust type system: \
+                        invalid data, aliasing violations or data races will cause \
+                        undefined behavior",
+                        UnsafetyViolationKind::General,
+                    );
                 }
             }
         }
@@ -351,8 +348,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                     match violation.kind {
                         UnsafetyViolationKind::GeneralAndConstFn |
                         UnsafetyViolationKind::General => {},
-                        UnsafetyViolationKind::BorrowPacked(_) |
-                        UnsafetyViolationKind::ExternStatic(_) => if self.min_const_fn {
+                        UnsafetyViolationKind::BorrowPacked(_) => if self.min_const_fn {
                             // const fns don't need to be backwards compatible and can
                             // emit these violations as a hard error instead of a backwards
                             // compat lint
@@ -380,8 +376,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                             UnsafetyViolationKind::GeneralAndConstFn => {},
                             // these things are forbidden in const fns
                             UnsafetyViolationKind::General |
-                            UnsafetyViolationKind::BorrowPacked(_) |
-                            UnsafetyViolationKind::ExternStatic(_) => {
+                            UnsafetyViolationKind::BorrowPacked(_) => {
                                 let mut violation = violation.clone();
                                 // const fns don't need to be backwards compatible and can
                                 // emit these violations as a hard error instead of a backwards
@@ -576,10 +571,10 @@ fn is_enclosed(
         if used_unsafe.contains(&parent_id) {
             Some(("block".to_string(), parent_id))
         } else if let Some(Node::Item(&hir::Item {
-            kind: hir::ItemKind::Fn(_, header, _, _),
+            kind: hir::ItemKind::Fn(ref sig, _, _),
             ..
         })) = tcx.hir().find(parent_id) {
-            match header.unsafety {
+            match sig.header.unsafety {
                 hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
                 hir::Unsafety::Normal => None,
             }
@@ -642,18 +637,10 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
                 struct_span_err!(
                     tcx.sess, source_info.span, E0133,
                     "{} is unsafe and requires unsafe function or block", description)
-                    .span_label(source_info.span, &description.as_str()[..])
-                    .note(&details.as_str()[..])
+                    .span_label(source_info.span, &*description.as_str())
+                    .note(&details.as_str())
                     .emit();
             }
-            UnsafetyViolationKind::ExternStatic(lint_hir_id) => {
-                tcx.lint_node_note(SAFE_EXTERN_STATICS,
-                              lint_hir_id,
-                              source_info.span,
-                              &format!("{} is unsafe and requires unsafe function or block \
-                                        (error E0133)", &description.as_str()[..]),
-                              &details.as_str()[..]);
-            }
             UnsafetyViolationKind::BorrowPacked(lint_hir_id) => {
                 if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
                     tcx.unsafe_derive_on_repr_packed(impl_def_id);
@@ -662,8 +649,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
                                   lint_hir_id,
                                   source_info.span,
                                   &format!("{} is unsafe and requires unsafe function or block \
-                                            (error E0133)", &description.as_str()[..]),
-                                  &details.as_str()[..]);
+                                            (error E0133)", description),
+                                  &details.as_str());
                 }
             }
         }
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index e7095101f46..a0d04bd5932 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -9,7 +9,7 @@ use rustc::hir::def_id::DefId;
 use rustc::mir::{
     AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue, Local, UnOp,
     StatementKind, Statement, LocalKind, TerminatorKind, Terminator,  ClearCrossCrate, SourceInfo,
-    BinOp, SourceScope, SourceScopeLocalData, LocalDecl, BasicBlock,
+    BinOp, SourceScope, SourceScopeLocalData, LocalDecl, BasicBlock, RETURN_PLACE,
 };
 use rustc::mir::visit::{
     Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
@@ -25,6 +25,7 @@ use rustc::ty::layout::{
     LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
 };
 
+use crate::rustc::ty::subst::Subst;
 use crate::interpret::{
     self, InterpCx, ScalarMaybeUndef, Immediate, OpTy,
     StackPopCleanup, LocalValue, LocalState, AllocId, Frame,
@@ -269,6 +270,7 @@ struct ConstPropagator<'mir, 'tcx> {
     param_env: ParamEnv<'tcx>,
     source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
     local_decls: IndexVec<Local, LocalDecl<'tcx>>,
+    ret: Option<OpTy<'tcx, ()>>,
 }
 
 impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> {
@@ -308,11 +310,21 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ());
         let can_const_prop = CanConstProp::check(body);
 
+        let substs = &InternalSubsts::identity_for_item(tcx, def_id);
+
+        let ret =
+            ecx
+                .layout_of(body.return_ty().subst(tcx, substs))
+                .ok()
+                // Don't bother allocating memory for ZST types which have no values.
+                .filter(|ret_layout| !ret_layout.is_zst())
+                .map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack));
+
         ecx.push_stack_frame(
-            Instance::new(def_id, &InternalSubsts::identity_for_item(tcx, def_id)),
+            Instance::new(def_id, substs),
             span,
             dummy_body,
-            None,
+            ret.map(Into::into),
             StackPopCleanup::None {
                 cleanup: false,
             },
@@ -327,6 +339,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             source_scope_local_data,
             //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it
             local_decls: body.local_decls.clone(),
+            ret: ret.map(Into::into),
         }
     }
 
@@ -335,6 +348,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     }
 
     fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
+        if local == RETURN_PLACE {
+            // Try to read the return place as an immediate so that if it is representable as a
+            // scalar, we can handle it as such, but otherwise, just return the value as is.
+            return match self.ret.map(|ret| self.ecx.try_read_immediate(ret)) {
+                Some(Ok(Ok(imm))) => Some(imm.into()),
+                _ => self.ret,
+            };
+        }
+
         self.ecx.access_local(self.ecx.frame(), local, None).ok()
     }
 
@@ -643,7 +665,8 @@ impl CanConstProp {
             //        lint for x != y
             // FIXME(oli-obk): lint variables until they are used in a condition
             // FIXME(oli-obk): lint if return value is constant
-            *val = body.local_kind(local) == LocalKind::Temp;
+            let local_kind = body.local_kind(local);
+            *val = local_kind == LocalKind::Temp || local_kind == LocalKind::ReturnPointer;
 
             if !*val {
                 trace!("local {:?} can't be propagated because it's not a temporary", local);
@@ -731,7 +754,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                             }
                         } else {
                             trace!("can't propagate into {:?}", local);
-                            self.remove_const(local);
+                            if local != RETURN_PLACE {
+                                self.remove_const(local);
+                            }
                         }
                     }
                 }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 911901be36b..37c239001a5 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -392,7 +392,7 @@ fn make_generator_state_argument_indirect<'tcx>(
 
     let ref_gen_ty = tcx.mk_ref(region, ty::TypeAndMut {
         ty: gen_ty,
-        mutbl: hir::MutMutable
+        mutbl: hir::Mutability::Mutable
     });
 
     // Replace the by value generator argument
@@ -977,7 +977,7 @@ fn create_generator_drop_shim<'tcx>(
         mutability: Mutability::Mut,
         ty: tcx.mk_ptr(ty::TypeAndMut {
             ty: gen_ty,
-            mutbl: hir::Mutability::MutMutable,
+            mutbl: hir::Mutability::Mutable,
         }),
         user_ty: UserTypeProjections::none(),
         name: None,
@@ -1192,7 +1192,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
                 (substs.upvar_tys(def_id, tcx).collect(),
                  substs.witness(def_id, tcx),
                  substs.discr_ty(tcx),
-                 movability == hir::GeneratorMovability::Movable)
+                 movability == hir::Movability::Movable)
             }
             _ => bug!(),
         };
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index dbe6c784592..02ed12eda67 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -36,6 +36,7 @@ pub mod const_prop;
 pub mod generator;
 pub mod inline;
 pub mod uniform_array_move_out;
+pub mod uninhabited_enum_branching;
 
 pub(crate) fn provide(providers: &mut Providers<'_>) {
     self::qualify_consts::provide(providers);
@@ -210,13 +211,14 @@ fn mir_validated(
     }
 
     let mut body = tcx.mir_const(def_id).steal();
-    let qualify_and_promote_pass = qualify_consts::QualifyAndPromoteConstants::default();
+    let promote_pass = promote_consts::PromoteTemps::default();
     run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Validated, &[
         // What we need to run borrowck etc.
-        &qualify_and_promote_pass,
+        &qualify_consts::QualifyAndPromoteConstants::default(),
+        &promote_pass,
         &simplify::SimplifyCfg::new("qualify-consts"),
     ]);
-    let promoted = qualify_and_promote_pass.promoted.into_inner();
+    let promoted = promote_pass.promoted_fragments.into_inner();
     (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
 }
 
@@ -257,6 +259,8 @@ fn run_optimization_passes<'tcx>(
 
 
         // Optimizations begin.
+        &uninhabited_enum_branching::UninhabitedEnumBranching,
+        &simplify::SimplifyCfg::new("after-uninhabited-enum-branching"),
         &uniform_array_move_out::RestoreSubsliceArrayMoveOut::new(tcx),
         &inline::Inline,
 
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 83f3aafc55c..48a58f1d0ee 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -17,7 +17,7 @@ use rustc::mir::*;
 use rustc::mir::interpret::ConstValue;
 use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor};
 use rustc::mir::traversal::ReversePostorder;
-use rustc::ty::{self, List, TyCtxt};
+use rustc::ty::{self, List, TyCtxt, TypeFoldable};
 use rustc::ty::subst::InternalSubsts;
 use rustc::ty::cast::CastTy;
 use syntax::ast::LitKind;
@@ -25,12 +25,68 @@ use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
 use rustc_index::vec::{IndexVec, Idx};
+use rustc_index::bit_set::HybridBitSet;
 use rustc_target::spec::abi::Abi;
 
+use std::cell::Cell;
 use std::{iter, mem, usize};
 
+use crate::transform::{MirPass, MirSource};
 use crate::transform::check_consts::{qualifs, Item, ConstKind, is_lang_panic_fn};
 
+/// A `MirPass` for promotion.
+///
+/// In this case, "promotion" entails the following:
+/// - Extract promotable temps in `fn` and `const fn` into their own MIR bodies.
+/// - Extend lifetimes in `const` and `static` by removing `Drop` and `StorageDead`.
+/// - Emit errors if the requirements of `#[rustc_args_required_const]` are not met.
+///
+/// After this pass is run, `promoted_fragments` will hold the MIR body corresponding to each
+/// newly created `StaticKind::Promoted`.
+#[derive(Default)]
+pub struct PromoteTemps<'tcx> {
+    pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
+}
+
+impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+        // There's not really any point in promoting errorful MIR.
+        //
+        // This does not include MIR that failed const-checking, which we still try to promote.
+        if body.return_ty().references_error() {
+            tcx.sess.delay_span_bug(body.span, "PromoteTemps: MIR had errors");
+            return;
+        }
+
+        if src.promoted.is_some() {
+            return;
+        }
+
+        let def_id = src.def_id();
+
+        let item = Item::new(tcx, def_id, body);
+        let mut rpo = traversal::reverse_postorder(body);
+        let (temps, all_candidates) = collect_temps_and_candidates(tcx, body, &mut rpo);
+
+        let promotable_candidates = validate_candidates(tcx, body, def_id, &temps, &all_candidates);
+
+        // For now, lifetime extension is done in `const` and `static`s without creating promoted
+        // MIR fragments by removing `Drop` and `StorageDead` for each referent. However, this will
+        // not work inside loops when they are allowed in `const`s.
+        //
+        // FIXME: use promoted MIR fragments everywhere?
+        let promoted_fragments = if should_create_promoted_mir_fragments(item.const_kind) {
+            promote_candidates(def_id, body, tcx, temps, promotable_candidates)
+        } else {
+            // FIXME: promote const array initializers in consts.
+            remove_drop_and_storage_dead_on_promoted_locals(tcx, body, &promotable_candidates);
+            IndexVec::new()
+        };
+
+        self.promoted_fragments.set(promoted_fragments);
+    }
+}
+
 /// State of a temporary during collection and promotion.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum TempState {
@@ -199,6 +255,8 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
                             bb: location.block,
                             index: 2,
                         });
+
+                        return; // Don't double count `simd_shuffle` candidates
                     }
                 }
 
@@ -536,7 +594,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                         // is gone - we can always promote constants even if they
                         // fail to pass const-checking, as compilation would've
                         // errored independently and promotion can't change that.
-                        let (bits, _) = self.tcx.at(constant.span).mir_const_qualif(def_id);
+                        let bits = self.tcx.at(constant.span).mir_const_qualif(def_id);
                         if bits == super::qualify_consts::QUALIF_ERROR_BIT {
                             self.tcx.sess.delay_span_bug(
                                 constant.span,
@@ -1152,3 +1210,83 @@ crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>(
             should_promote={:?} feature_flag={:?}", mir_def_id, should_promote, feature_flag);
     should_promote && !feature_flag
 }
+
+fn should_create_promoted_mir_fragments(const_kind: Option<ConstKind>) -> bool {
+    match const_kind {
+        Some(ConstKind::ConstFn) | None => true,
+        Some(ConstKind::Const) | Some(ConstKind::Static) | Some(ConstKind::StaticMut) => false,
+    }
+}
+
+/// In `const` and `static` everything without `StorageDead`
+/// is `'static`, we don't have to create promoted MIR fragments,
+/// just remove `Drop` and `StorageDead` on "promoted" locals.
+fn remove_drop_and_storage_dead_on_promoted_locals(
+    tcx: TyCtxt<'tcx>,
+    body: &mut Body<'tcx>,
+    promotable_candidates: &[Candidate],
+) {
+    debug!("run_pass: promotable_candidates={:?}", promotable_candidates);
+
+    // Removing `StorageDead` will cause errors for temps declared inside a loop body. For now we
+    // simply skip promotion if a loop exists, since loops are not yet allowed in a `const`.
+    //
+    // FIXME: Just create MIR fragments for `const`s instead of using this hackish approach?
+    if body.is_cfg_cyclic() {
+        tcx.sess.delay_span_bug(body.span, "Control-flow cycle detected in `const`");
+        return;
+    }
+
+    // The underlying local for promotion contexts like `&temp` and `&(temp.proj)`.
+    let mut requires_lifetime_extension = HybridBitSet::new_empty(body.local_decls.len());
+
+    promotable_candidates
+        .iter()
+        .filter_map(|c| {
+            match c {
+                Candidate::Ref(loc) => Some(loc),
+                Candidate::Repeat(_) | Candidate::Argument { .. } => None,
+            }
+        })
+        .map(|&Location { block, statement_index }| {
+            // FIXME: store the `Local` for each `Candidate` when it is created.
+            let place = match &body[block].statements[statement_index].kind {
+                StatementKind::Assign(box ( _, Rvalue::Ref(_, _, place))) => place,
+                _ => bug!("`Candidate::Ref` without corresponding assignment"),
+            };
+
+            match place.base {
+                PlaceBase::Local(local) => local,
+                PlaceBase::Static(_) => bug!("`Candidate::Ref` for a non-local"),
+            }
+        })
+        .for_each(|local| {
+            requires_lifetime_extension.insert(local);
+        });
+
+    // Remove `Drop` terminators and `StorageDead` statements for all promotable temps that require
+    // lifetime extension.
+    for block in body.basic_blocks_mut() {
+        block.statements.retain(|statement| {
+            match statement.kind {
+                StatementKind::StorageDead(index) => !requires_lifetime_extension.contains(index),
+                _ => true
+            }
+        });
+        let terminator = block.terminator_mut();
+        match &terminator.kind {
+            TerminatorKind::Drop {
+                location,
+                target,
+                ..
+            } => {
+                if let Some(index) = location.as_local() {
+                    if requires_lifetime_extension.contains(index) {
+                        terminator.kind = TerminatorKind::Goto { target: *target };
+                    }
+                }
+            }
+            _ => {}
+        }
+    }
+}
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 5463b944473..39720af4cb5 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -6,7 +6,6 @@
 
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
-use rustc_data_structures::fx::FxHashSet;
 use rustc_target::spec::abi::Abi;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -16,11 +15,9 @@ use rustc::ty::cast::CastTy;
 use rustc::ty::query::Providers;
 use rustc::mir::*;
 use rustc::mir::interpret::ConstValue;
-use rustc::mir::traversal::ReversePostorder;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
 use rustc::middle::lang_items;
 use rustc::session::config::nightly_options;
-use syntax::ast::LitKind;
 use syntax::feature_gate::{emit_feature_err, GateIssue};
 use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
@@ -33,7 +30,6 @@ use std::usize;
 
 use rustc::hir::HirId;
 use crate::transform::{MirPass, MirSource};
-use super::promote_consts::{self, Candidate, TempState};
 use crate::transform::check_consts::ops::{self, NonConstOp};
 
 /// What kind of item we are in.
@@ -71,7 +67,7 @@ impl fmt::Display for Mode {
     }
 }
 
-const QUALIF_COUNT: usize = 4;
+const QUALIF_COUNT: usize = 2;
 
 // FIXME(eddyb) once we can use const generics, replace this array with
 // something like `IndexVec` but for fixed-size arrays (`IndexArray`?).
@@ -80,20 +76,20 @@ struct PerQualif<T>([T; QUALIF_COUNT]);
 
 impl<T: Clone> PerQualif<T> {
     fn new(x: T) -> Self {
-        PerQualif([x.clone(), x.clone(), x.clone(), x])
+        PerQualif([x.clone(), x])
     }
 }
 
 impl<T> PerQualif<T> {
     fn as_mut(&mut self) -> PerQualif<&mut T> {
-        let [x0, x1, x2, x3] = &mut self.0;
-        PerQualif([x0, x1, x2, x3])
+        let [x0, x1] = &mut self.0;
+        PerQualif([x0, x1])
     }
 
     fn zip<U>(self, other: PerQualif<U>) -> PerQualif<(T, U)> {
-        let [x0, x1, x2, x3] = self.0;
-        let [y0, y1, y2, y3] = other.0;
-        PerQualif([(x0, y0), (x1, y1), (x2, y2), (x3, y3)])
+        let [x0, x1] = self.0;
+        let [y0, y1] = other.0;
+        PerQualif([(x0, y0), (x1, y1)])
     }
 }
 
@@ -260,7 +256,7 @@ trait Qualif {
                     if cx.tcx.trait_of_item(def_id).is_some() {
                         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);
+                        let bits = cx.tcx.at(constant.span).mir_const_qualif(def_id);
 
                         let qualif = PerQualif::decode_from_bits(bits).0[Self::IDX];
 
@@ -429,195 +425,6 @@ impl Qualif for NeedsDrop {
     }
 }
 
-/// Not promotable at all - non-`const fn` calls, `asm!`,
-/// pointer comparisons, ptr-to-int casts, etc.
-/// Inside a const context all constness rules apply, so promotion simply has to follow the regular
-/// constant rules (modulo interior mutability or `Drop` rules which are handled `HasMutInterior`
-/// and `NeedsDrop` respectively). Basically this duplicates the checks that the const-checking
-/// visitor enforces by emitting errors when working in const context.
-struct IsNotPromotable;
-
-impl Qualif for IsNotPromotable {
-    const IDX: usize = 2;
-
-    fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
-        match static_.kind {
-            StaticKind::Promoted(_, _) => unreachable!(),
-            StaticKind::Static => {
-                // Only allow statics (not consts) to refer to other statics.
-                // FIXME(eddyb) does this matter at all for promotion?
-                let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut;
-
-                !allowed ||
-                    cx.tcx.get_attrs(static_.def_id).iter().any(
-                        |attr| attr.check_name(sym::thread_local)
-                    )
-            }
-        }
-    }
-
-    fn in_projection(
-        cx: &ConstCx<'_, 'tcx>,
-        place: PlaceRef<'_, 'tcx>,
-    ) -> bool {
-        if let [proj_base @ .., elem] = place.projection {
-            match elem {
-                ProjectionElem::Deref |
-                ProjectionElem::Downcast(..) => return true,
-
-                ProjectionElem::ConstantIndex {..} |
-                ProjectionElem::Subslice {..} |
-                ProjectionElem::Index(_) => {}
-
-                ProjectionElem::Field(..) => {
-                    if cx.mode == Mode::NonConstFn {
-                        let base_ty = Place::ty_from(place.base, proj_base, cx.body, cx.tcx).ty;
-                        if let Some(def) = base_ty.ty_adt_def() {
-                            // No promotion of union field accesses.
-                            if def.is_union() {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-
-            Self::in_projection_structurally(cx, place)
-        } else {
-            bug!("This should be called if projection is not empty");
-        }
-    }
-
-    fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {
-        match *rvalue {
-            Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) if cx.mode == Mode::NonConstFn => {
-                let operand_ty = operand.ty(cx.body, cx.tcx);
-                let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
-                let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
-                match (cast_in, cast_out) {
-                    (CastTy::Ptr(_), CastTy::Int(_)) |
-                    (CastTy::FnPtr, CastTy::Int(_)) => {
-                        // in normal functions, mark such casts as not promotable
-                        return true;
-                    }
-                    _ => {}
-                }
-            }
-
-            Rvalue::BinaryOp(op, ref lhs, _) if cx.mode == Mode::NonConstFn => {
-                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(cx.body, cx.tcx).kind {
-                    assert!(op == BinOp::Eq || op == BinOp::Ne ||
-                            op == BinOp::Le || op == BinOp::Lt ||
-                            op == BinOp::Ge || op == BinOp::Gt ||
-                            op == BinOp::Offset);
-
-                    // raw pointer operations are not allowed inside promoteds
-                    return true;
-                }
-            }
-
-            Rvalue::NullaryOp(NullOp::Box, _) => return true,
-
-            _ => {}
-        }
-
-        Self::in_rvalue_structurally(cx, rvalue)
-    }
-
-    fn in_call(
-        cx: &ConstCx<'_, 'tcx>,
-        callee: &Operand<'tcx>,
-        args: &[Operand<'tcx>],
-        _return_ty: Ty<'tcx>,
-    ) -> bool {
-        let fn_ty = callee.ty(cx.body, cx.tcx);
-        match fn_ty.kind {
-            ty::FnDef(def_id, _) => {
-                match cx.tcx.fn_sig(def_id).abi() {
-                    Abi::RustIntrinsic |
-                    Abi::PlatformIntrinsic => {
-                        assert!(!cx.tcx.is_const_fn(def_id));
-                        match &cx.tcx.item_name(def_id).as_str()[..] {
-                            | "size_of"
-                            | "min_align_of"
-                            | "needs_drop"
-                            | "type_id"
-                            | "bswap"
-                            | "bitreverse"
-                            | "ctpop"
-                            | "cttz"
-                            | "cttz_nonzero"
-                            | "ctlz"
-                            | "ctlz_nonzero"
-                            | "wrapping_add"
-                            | "wrapping_sub"
-                            | "wrapping_mul"
-                            | "unchecked_shl"
-                            | "unchecked_shr"
-                            | "rotate_left"
-                            | "rotate_right"
-                            | "add_with_overflow"
-                            | "sub_with_overflow"
-                            | "mul_with_overflow"
-                            | "saturating_add"
-                            | "saturating_sub"
-                            | "transmute"
-                            | "simd_insert"
-                            | "simd_extract"
-                            | "ptr_offset_from"
-                            => return true,
-
-                            _ => {}
-                        }
-                    }
-                    _ => {
-                        let is_const_fn =
-                            cx.tcx.is_const_fn(def_id) ||
-                            cx.tcx.is_unstable_const_fn(def_id).is_some() ||
-                            cx.is_const_panic_fn(def_id);
-                        if !is_const_fn {
-                            return true;
-                        }
-                    }
-                }
-            }
-            _ => return true,
-        }
-
-        Self::in_operand(cx, callee) || args.iter().any(|arg| Self::in_operand(cx, arg))
-    }
-}
-
-/// Refers to temporaries which cannot be promoted *implicitly*.
-/// Explicit promotion happens e.g. for constant arguments declared via `rustc_args_required_const`.
-/// Implicit promotion has almost the same rules, except that disallows `const fn` except for
-/// those marked `#[rustc_promotable]`. This is to avoid changing a legitimate run-time operation
-/// into a failing compile-time operation e.g. due to addresses being compared inside the function.
-struct IsNotImplicitlyPromotable;
-
-impl Qualif for IsNotImplicitlyPromotable {
-    const IDX: usize = 3;
-
-    fn in_call(
-        cx: &ConstCx<'_, 'tcx>,
-        callee: &Operand<'tcx>,
-        args: &[Operand<'tcx>],
-        _return_ty: Ty<'tcx>,
-    ) -> bool {
-        if cx.mode == Mode::NonConstFn {
-            if let ty::FnDef(def_id, _) = callee.ty(cx.body, cx.tcx).kind {
-                // Never promote runtime `const fn` calls of
-                // functions without `#[rustc_promotable]`.
-                if !cx.tcx.is_promotable_const_fn(def_id) {
-                    return true;
-                }
-            }
-        }
-
-        Self::in_operand(cx, callee) || args.iter().any(|arg| Self::in_operand(cx, arg))
-    }
-}
-
 // Ensure the `IDX` values are sequential (`0..QUALIF_COUNT`).
 macro_rules! static_assert_seq_qualifs {
     ($i:expr => $first:ident $(, $rest:ident)*) => {
@@ -632,7 +439,7 @@ macro_rules! static_assert_seq_qualifs {
     };
 }
 static_assert_seq_qualifs!(
-    0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable
+    0 => HasMutInterior, NeedsDrop
 );
 
 impl ConstCx<'_, 'tcx> {
@@ -640,9 +447,6 @@ impl ConstCx<'_, 'tcx> {
         let mut qualifs = PerQualif::default();
         qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false);
         qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false);
-        qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
-        qualifs[IsNotImplicitlyPromotable] =
-            IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
         qualifs
     }
 
@@ -650,8 +454,6 @@ impl ConstCx<'_, 'tcx> {
         let mut qualifs = PerQualif::default();
         qualifs[HasMutInterior] = HasMutInterior::in_local(self, local);
         qualifs[NeedsDrop] = NeedsDrop::in_local(self, local);
-        qualifs[IsNotPromotable] = IsNotPromotable::in_local(self, local);
-        qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_local(self, local);
         qualifs
     }
 
@@ -659,8 +461,6 @@ impl ConstCx<'_, 'tcx> {
         let mut qualifs = PerQualif::default();
         qualifs[HasMutInterior] = HasMutInterior::in_value(self, source);
         qualifs[NeedsDrop] = NeedsDrop::in_value(self, source);
-        qualifs[IsNotPromotable] = IsNotPromotable::in_value(self, source);
-        qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_value(self, source);
         qualifs
     }
 }
@@ -675,11 +475,6 @@ struct Checker<'a, 'tcx> {
 
     span: Span,
     def_id: DefId,
-    rpo: ReversePostorder<'a, 'tcx>,
-
-    temp_promotion_state: IndexVec<Local, TempState>,
-    promotion_candidates: Vec<Candidate>,
-    unchecked_promotion_candidates: Vec<Candidate>,
 
     /// If `true`, do not emit errors to the user, merely collect them in `errors`.
     suppress_errors: bool,
@@ -708,10 +503,6 @@ impl Deref for Checker<'a, 'tcx> {
 impl<'a, 'tcx> Checker<'a, 'tcx> {
     fn new(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>, mode: Mode) -> Self {
         assert!(def_id.is_local());
-        let mut rpo = traversal::reverse_postorder(body);
-        let (temps, unchecked_promotion_candidates) =
-            promote_consts::collect_temps_and_candidates(tcx, body, &mut rpo);
-        rpo.reset();
 
         let param_env = tcx.param_env(def_id);
 
@@ -732,24 +523,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     }
                 }
             }
-            if !temps[local].is_promotable() {
-                cx.per_local[IsNotPromotable].insert(local);
-            }
-            if let LocalKind::Var = body.local_kind(local) {
-                // Sanity check to prevent implicit and explicit promotion of
-                // named locals
-                assert!(cx.per_local[IsNotPromotable].contains(local));
-            }
         }
 
         Checker {
             cx,
             span: body.span,
             def_id,
-            rpo,
-            temp_promotion_state: temps,
-            promotion_candidates: vec![],
-            unchecked_promotion_candidates,
             errors: vec![],
             suppress_errors: false,
         }
@@ -794,16 +573,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
         let mut qualifs = self.qualifs_in_value(source);
 
         match source {
-            ValueSource::Rvalue(&Rvalue::Ref(_, kind, ref place)) => {
+            ValueSource::Rvalue(&Rvalue::Ref(_, kind, _)) => {
                 // Getting `true` from `HasMutInterior::in_rvalue` means
                 // the borrowed place is disallowed from being borrowed,
                 // due to either a mutable borrow (with some exceptions),
                 // or an shared borrow of a value with interior mutability.
-                // Then `HasMutInterior` is replaced with `IsNotPromotable`,
+                // Then `HasMutInterior` is cleared
                 // to avoid duplicate errors (e.g. from reborrowing).
                 if qualifs[HasMutInterior] {
                     qualifs[HasMutInterior] = false;
-                    qualifs[IsNotPromotable] = true;
 
                     debug!("suppress_errors: {}", self.suppress_errors);
                     if self.mode.requires_const_checking() && !self.suppress_errors {
@@ -833,57 +611,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                             }
                         }
                     }
-                } else if let BorrowKind::Mut { .. } | BorrowKind::Shared = kind {
-                    // Don't promote BorrowKind::Shallow borrows, as they don't
-                    // reach codegen.
-                    // FIXME(eddyb) the two other kinds of borrow (`Shallow` and `Unique`)
-                    // aren't promoted here but *could* be promoted as part of a larger
-                    // value because `IsNotPromotable` isn't being set for them,
-                    // need to figure out what is the intended behavior.
-
-                    // We might have a candidate for promotion.
-                    let candidate = Candidate::Ref(location);
-                    // Start by traversing to the "base", with non-deref projections removed.
-                    let deref_proj =
-                        place.projection.iter().rev().find(|&elem| *elem == ProjectionElem::Deref);
-
-                    debug!(
-                        "qualify_consts: promotion candidate: place={:?} {:?}",
-                        place.base, deref_proj
-                    );
-                    // We can only promote interior borrows of promotable temps (non-temps
-                    // don't get promoted anyway).
-                    // (If we bailed out of the loop due to a `Deref` above, we will definitely
-                    // not enter the conditional here.)
-                    if let (PlaceBase::Local(local), None) = (&place.base, deref_proj) {
-                        if self.body.local_kind(*local) == LocalKind::Temp {
-                            debug!("qualify_consts: promotion candidate: local={:?}", local);
-                            // The borrowed place doesn't have `HasMutInterior`
-                            // (from `in_rvalue`), so we can safely ignore
-                            // `HasMutInterior` from the local's qualifications.
-                            // This allows borrowing fields which don't have
-                            // `HasMutInterior`, from a type that does, e.g.:
-                            // `let _: &'static _ = &(Cell::new(1), 2).1;`
-                            let mut local_qualifs = self.qualifs_in_local(*local);
-                            // Any qualifications, except HasMutInterior (see above), disqualify
-                            // from promotion.
-                            // This is, in particular, the "implicit promotion" version of
-                            // the check making sure that we don't run drop glue during const-eval.
-                            local_qualifs[HasMutInterior] = false;
-                            if !local_qualifs.0.iter().any(|&qualif| qualif) {
-                                debug!("qualify_consts: promotion candidate: {:?}", candidate);
-                                self.promotion_candidates.push(candidate);
-                            }
-                        }
-                    }
-                }
-            },
-            ValueSource::Rvalue(&Rvalue::Repeat(ref operand, _)) => {
-                debug!("assign: self.cx.mode={:?} self.def_id={:?} location={:?} operand={:?}",
-                       self.cx.mode, self.def_id, location, operand);
-                if self.should_promote_repeat_expression(operand) &&
-                        self.tcx.features().const_in_array_repeat_expressions {
-                    self.promotion_candidates.push(Candidate::Repeat(location));
                 }
             },
             _ => {},
@@ -922,14 +649,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
         let kind = self.body.local_kind(index);
         debug!("store to {:?} {:?}", kind, index);
 
-        // Only handle promotable temps in non-const functions.
-        if self.mode == Mode::NonConstFn {
-            if kind != LocalKind::Temp ||
-               !self.temp_promotion_state[index].is_promotable() {
-                return;
-            }
-        }
-
         // this is overly restrictive, because even full assignments do not clear the qualif
         // While we could special case full assignments, this would be inconsistent with
         // aggregates where we overwrite all fields via assignments, which would not get
@@ -939,22 +658,10 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                 per_local.insert(index);
             }
         }
-
-        // Ensure the `IsNotPromotable` qualification is preserved.
-        // NOTE(eddyb) this is actually unnecessary right now, as
-        // we never replace the local's qualif, but we might in
-        // the future, and so it serves to catch changes that unset
-        // important bits (in which case, asserting `contains` could
-        // be replaced with calling `insert` to re-set the bit).
-        if kind == LocalKind::Temp {
-            if !self.temp_promotion_state[index].is_promotable() {
-                assert!(self.cx.per_local[IsNotPromotable].contains(index));
-            }
-        }
     }
 
     /// Check a whole const, static initializer or const fn.
-    fn check_const(&mut self) -> (u8, &'tcx BitSet<Local>) {
+    fn check_const(&mut self) -> u8 {
         use crate::transform::check_consts as new_checker;
 
         debug!("const-checking {} {:?}", self.mode, self.def_id);
@@ -976,7 +683,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
 
         let mut seen_blocks = BitSet::new_empty(body.basic_blocks().len());
         let mut bb = START_BLOCK;
-        let mut has_controlflow_error = false;
         loop {
             seen_blocks.insert(bb.index());
 
@@ -1017,7 +723,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     bb = target;
                 }
                 _ => {
-                    has_controlflow_error = true;
                     self.not_const(ops::Loop);
                     validator.check_op(ops::Loop);
                     break;
@@ -1044,118 +749,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
             }
         }
 
-        // Collect all the temps we need to promote.
-        let mut promoted_temps = BitSet::new_empty(self.temp_promotion_state.len());
-
-        // HACK(eddyb) don't try to validate promotion candidates if any
-        // parts of the control-flow graph were skipped due to an error.
-        let promotion_candidates = if has_controlflow_error {
-            let unleash_miri = self
-                .tcx
-                .sess
-                .opts
-                .debugging_opts
-                .unleash_the_miri_inside_of_you;
-            if !unleash_miri {
-                self.tcx.sess.delay_span_bug(
-                    body.span,
-                    "check_const: expected control-flow error(s)",
-                );
-            }
-            self.promotion_candidates.clone()
-        } else {
-            self.valid_promotion_candidates()
-        };
-        debug!("qualify_const: promotion_candidates={:?}", promotion_candidates);
-        for candidate in promotion_candidates {
-            match candidate {
-                Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => {
-                    if let StatementKind::Assign(box(_, Rvalue::Repeat(
-                        Operand::Move(place),
-                        _
-                    ))) = &self.body[bb].statements[stmt_idx].kind {
-                        if let Some(index) = place.as_local() {
-                            promoted_temps.insert(index);
-                        }
-                    }
-                }
-                Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
-                    if let StatementKind::Assign(
-                        box(
-                            _,
-                            Rvalue::Ref(_, _, place)
-                        )
-                    ) = &self.body[bb].statements[stmt_idx].kind {
-                        if let Some(index) = place.as_local() {
-                            promoted_temps.insert(index);
-                        }
-                    }
-                }
-                Candidate::Argument { .. } => {}
-            }
-        }
-
-        let mut qualifs = self.qualifs_in_local(RETURN_PLACE);
-
-        // Account for errors in consts by using the
-        // conservative type qualification instead.
-        if qualifs[IsNotPromotable] {
-            qualifs = self.qualifs_in_any_value_of_ty(body.return_ty());
-        }
-
-        (qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
-    }
-
-    /// Get the subset of `unchecked_promotion_candidates` that are eligible
-    /// for promotion.
-    // FIXME(eddyb) replace the old candidate gathering with this.
-    fn valid_promotion_candidates(&self) -> Vec<Candidate> {
-        // Sanity-check the promotion candidates.
-        let candidates = promote_consts::validate_candidates(
-            self.tcx,
-            self.body,
-            self.def_id,
-            &self.temp_promotion_state,
-            &self.unchecked_promotion_candidates,
-        );
-
-        if candidates != self.promotion_candidates {
-            let report = |msg, candidate| {
-                let span = match candidate {
-                    Candidate::Ref(loc) |
-                    Candidate::Repeat(loc) => self.body.source_info(loc).span,
-                    Candidate::Argument { bb, .. } => {
-                        self.body[bb].terminator().source_info.span
-                    }
-                };
-                self.tcx.sess.span_err(span, &format!("{}: {:?}", msg, candidate));
-            };
-
-            for &c in &self.promotion_candidates {
-                if !candidates.contains(&c) {
-                    report("invalidated old candidate", c);
-                }
-            }
-
-            for &c in &candidates {
-                if !self.promotion_candidates.contains(&c) {
-                    report("extra new candidate", c);
-                }
-            }
-
-            bug!("promotion candidate validation mismatches (see above)");
-        }
-
-        candidates
-    }
-
-    /// Returns `true` if the operand of a repeat expression is promotable.
-    fn should_promote_repeat_expression(&self, operand: &Operand<'tcx>) -> bool {
-        let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
-                             IsNotPromotable::in_operand(self, operand);
-        debug!("should_promote_repeat_expression: operand={:?} not_promotable={:?}",
-               operand, not_promotable);
-        !not_promotable
+        self.qualifs_in_local(RETURN_PLACE).encode_to_bits()
     }
 }
 
@@ -1468,16 +1062,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
             }
 
             let fn_ty = func.ty(self.body, self.tcx);
-            let mut callee_def_id = None;
-            let mut is_shuffle = false;
             match fn_ty.kind {
                 ty::FnDef(def_id, _) => {
-                    callee_def_id = Some(def_id);
                     match self.tcx.fn_sig(def_id).abi() {
                         Abi::RustIntrinsic |
                         Abi::PlatformIntrinsic => {
                             assert!(!self.tcx.is_const_fn(def_id));
-                            match &self.tcx.item_name(def_id).as_str()[..] {
+                            match &*self.tcx.item_name(def_id).as_str() {
                                 // special intrinsic that can be called diretly without an intrinsic
                                 // feature gate needs a language feature gate
                                 "transmute" => {
@@ -1496,10 +1087,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                     }
                                 }
 
-                                name if name.starts_with("simd_shuffle") => {
-                                    is_shuffle = true;
-                                }
-
                                 // no need to check feature gates, intrinsics are only callable
                                 // from the libstd or with forever unstable feature gates
                                 _ => {}
@@ -1587,36 +1174,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                 }
             }
 
-            // No need to do anything in constants and statics, as everything is "constant" anyway
-            // so promotion would be useless.
-            if self.mode != Mode::Static && self.mode != Mode::Const {
-                let constant_args = callee_def_id.and_then(|id| {
-                    args_required_const(self.tcx, id)
-                }).unwrap_or_default();
-                for (i, arg) in args.iter().enumerate() {
-                    if !(is_shuffle && i == 2 || constant_args.contains(&i)) {
-                        continue;
-                    }
-
-                    let candidate = Candidate::Argument { bb: location.block, index: i };
-                    // Since the argument is required to be constant,
-                    // we care about constness, not promotability.
-                    // If we checked for promotability, we'd miss out on
-                    // the results of function calls (which are never promoted
-                    // in runtime code).
-                    // This is not a problem, because the argument explicitly
-                    // requests constness, in contrast to regular promotion
-                    // which happens even without the user requesting it.
-                    //
-                    // `promote_consts` is responsible for emitting the error if
-                    // the argument is not promotable.
-                    if !IsNotPromotable::in_operand(self, arg) {
-                        debug!("visit_terminator_kind: candidate={:?}", candidate);
-                        self.promotion_candidates.push(candidate);
-                    }
-                }
-            }
-
             // Check callee and argument operands.
             self.visit_operand(func, location);
             for arg in args {
@@ -1720,9 +1277,9 @@ pub fn provide(providers: &mut Providers<'_>) {
 
 // FIXME(eddyb) this is only left around for the validation logic
 // in `promote_consts`, see the comment in `validate_operand`.
-pub(super) const QUALIF_ERROR_BIT: u8 = 1 << IsNotPromotable::IDX;
+pub(super) const QUALIF_ERROR_BIT: u8 = 1 << 2;
 
-fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
+fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
     // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
     // cannot yet be stolen), because `mir_validated()`, which steals
     // from `mir_const(), forces this query to execute before
@@ -1731,7 +1288,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
 
     if body.return_ty().references_error() {
         tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
-        return (QUALIF_ERROR_BIT, tcx.arena.alloc(BitSet::new_empty(0)));
+        return QUALIF_ERROR_BIT;
     }
 
     Checker::new(tcx, def_id, body, Mode::Const).check_const()
@@ -1767,53 +1324,34 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
         let mode = determine_mode(tcx, hir_id, def_id);
 
         debug!("run_pass: mode={:?}", mode);
-        if let Mode::NonConstFn | Mode::ConstFn = mode {
-            // This is ugly because Checker holds onto mir,
-            // which can't be mutated until its scope ends.
-            let (temps, candidates) = {
-                let mut checker = Checker::new(tcx, def_id, body, mode);
-                if let Mode::ConstFn = mode {
-                    let use_min_const_fn_checks =
-                        !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you &&
-                        tcx.is_min_const_fn(def_id);
-                    if use_min_const_fn_checks {
-                        // Enforce `min_const_fn` for stable `const fn`s.
-                        use super::qualify_min_const_fn::is_min_const_fn;
-                        if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
-                            error_min_const_fn_violation(tcx, span, err);
-                            return;
-                        }
-
-                        // `check_const` should not produce any errors, but better safe than sorry
-                        // FIXME(#53819)
-                        // NOTE(eddyb) `check_const` is actually needed for promotion inside
-                        // `min_const_fn` functions.
-                    }
-
-                    // Enforce a constant-like CFG for `const fn`.
-                    checker.check_const();
-                } else {
-                    while let Some((bb, data)) = checker.rpo.next() {
-                        checker.visit_basic_block_data(bb, data);
-                    }
+        if let Mode::NonConstFn = mode {
+            // No need to const-check a non-const `fn` now that we don't do promotion here.
+            return;
+        } else if let Mode::ConstFn = mode {
+            let mut checker = Checker::new(tcx, def_id, body, mode);
+            let use_min_const_fn_checks =
+                !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you &&
+                tcx.is_min_const_fn(def_id);
+            if use_min_const_fn_checks {
+                // Enforce `min_const_fn` for stable `const fn`s.
+                use super::qualify_min_const_fn::is_min_const_fn;
+                if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
+                    error_min_const_fn_violation(tcx, span, err);
+                    return;
                 }
+            }
 
-                let promotion_candidates = checker.valid_promotion_candidates();
-                (checker.temp_promotion_state, promotion_candidates)
-            };
-
-            // Do the actual promotion, now that we know what's viable.
-            self.promoted.set(
-                promote_consts::promote_candidates(def_id, body, tcx, temps, candidates)
-            );
+            // `check_const` should not produce any errors, but better safe than sorry
+            // FIXME(#53819)
+            // Enforce a constant-like CFG for `const fn`.
+            checker.check_const();
         } else {
             check_short_circuiting_in_const_local(tcx, body, mode);
 
-            let promoted_temps = match mode {
-                Mode::Const => tcx.mir_const_qualif(def_id).1,
-                _ => Checker::new(tcx, def_id, body, mode).check_const().1,
+            match mode {
+                Mode::Const => tcx.mir_const_qualif(def_id),
+                _ => Checker::new(tcx, def_id, body, mode).check_const(),
             };
-            remove_drop_and_storage_dead_on_promoted_locals(body, promoted_temps);
         }
 
         if mode == Mode::Static && !tcx.has_attr(def_id, sym::thread_local) {
@@ -1829,8 +1367,8 @@ fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode {
         hir::BodyOwnerKind::Fn if tcx.is_const_fn(def_id) => Mode::ConstFn,
         hir::BodyOwnerKind::Fn => Mode::NonConstFn,
         hir::BodyOwnerKind::Const => Mode::Const,
-        hir::BodyOwnerKind::Static(hir::MutImmutable) => Mode::Static,
-        hir::BodyOwnerKind::Static(hir::MutMutable) => Mode::StaticMut,
+        hir::BodyOwnerKind::Static(hir::Mutability::Immutable) => Mode::Static,
+        hir::BodyOwnerKind::Static(hir::Mutability::Mutable) => Mode::StaticMut,
     }
 }
 
@@ -1874,40 +1412,6 @@ fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>,
     }
 }
 
-/// In `const` and `static` everything without `StorageDead`
-/// is `'static`, we don't have to create promoted MIR fragments,
-/// just remove `Drop` and `StorageDead` on "promoted" locals.
-fn remove_drop_and_storage_dead_on_promoted_locals(
-    body: &mut Body<'tcx>,
-    promoted_temps: &BitSet<Local>,
-) {
-    debug!("run_pass: promoted_temps={:?}", promoted_temps);
-
-    for block in body.basic_blocks_mut() {
-        block.statements.retain(|statement| {
-            match statement.kind {
-                StatementKind::StorageDead(index) => !promoted_temps.contains(index),
-                _ => true
-            }
-        });
-        let terminator = block.terminator_mut();
-        match &terminator.kind {
-            TerminatorKind::Drop {
-                location,
-                target,
-                ..
-            } => {
-                if let Some(index) = location.as_local() {
-                    if promoted_temps.contains(index) {
-                        terminator.kind = TerminatorKind::Goto { target: *target };
-                    }
-                }
-            }
-            _ => {}
-        }
-    }
-}
-
 fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId) {
     let ty = body.return_ty();
     tcx.infer_ctxt().enter(|infcx| {
@@ -1921,19 +1425,6 @@ fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId)
     });
 }
 
-fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize>> {
-    let attrs = tcx.get_attrs(def_id);
-    let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
-    let mut ret = FxHashSet::default();
-    for meta in attr.meta_item_list()? {
-        match meta.literal()?.kind {
-            LitKind::Int(a, _) => { ret.insert(a as usize); }
-            _ => return None,
-        }
-    }
-    Some(ret)
-}
-
 fn validator_mismatch(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index c4e44091bc9..83bde5ed34e 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -80,7 +80,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
 fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> McfResult {
     for ty in ty.walk() {
         match ty.kind {
-            ty::Ref(_, _, hir::Mutability::MutMutable) => return Err((
+            ty::Ref(_, _, hir::Mutability::Mutable) => return Err((
                 span,
                 "mutable references in const fn are unstable".into(),
             )),
@@ -150,7 +150,8 @@ fn check_rvalue(
                 _ => check_operand(tcx, operand, span, def_id, body),
             }
         }
-        Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _) => {
+        Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer), operand, _)
+        | Rvalue::Cast(CastKind::Pointer(PointerCast::ArrayToPointer), operand, _) => {
             check_operand(tcx, operand, span, def_id, body)
         }
         Rvalue::Cast(CastKind::Pointer(PointerCast::UnsafeFnPointer), _, _) |
@@ -402,7 +403,7 @@ fn check_terminator(
 ///
 /// Adding more intrinsics requires sign-off from @rust-lang/lang.
 fn is_intrinsic_whitelisted(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
-    match &tcx.item_name(def_id).as_str()[..] {
+    match &*tcx.item_name(def_id).as_str() {
         | "size_of"
         | "min_align_of"
         | "needs_drop"
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 1b90ea78c64..f6b09f20bab 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -359,13 +359,20 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> {
         // Ignore stores of constants because `ConstProp` and `CopyProp` can remove uses of many
         // of these locals. However, if the local is still needed, then it will be referenced in
         // another place and we'll mark it as being used there.
-        if ctx == PlaceContext::MutatingUse(MutatingUseContext::Store) {
-            let stmt =
-                &self.body.basic_blocks()[location.block].statements[location.statement_index];
-            if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) = &stmt.kind {
-                if p.as_local().is_some() {
-                    trace!("skipping store of const value {:?} to {:?}", c, local);
-                    return;
+        if ctx == PlaceContext::MutatingUse(MutatingUseContext::Store) ||
+           ctx == PlaceContext::MutatingUse(MutatingUseContext::Projection) {
+            let block = &self.body.basic_blocks()[location.block];
+            if location.statement_index != block.statements.len() {
+                let stmt =
+                    &block.statements[location.statement_index];
+
+                if let StatementKind::Assign(
+                    box (p, Rvalue::Use(Operand::Constant(c)))
+                ) = &stmt.kind {
+                    if !p.is_indirect() {
+                        trace!("skipping store of const value {:?} to {:?}", c, p);
+                        return;
+                    }
                 }
             }
         }
@@ -392,7 +399,7 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> {
                     self.map[*l].is_some()
                 }
                 StatementKind::Assign(box (place, _)) => {
-                    if let Some(local) = place.as_local() {
+                    if let PlaceBase::Local(local) = place.base {
                         self.map[local].is_some()
                     } else {
                         true
diff --git a/src/librustc_mir/transform/uninhabited_enum_branching.rs b/src/librustc_mir/transform/uninhabited_enum_branching.rs
new file mode 100644
index 00000000000..a6c18aee6a8
--- /dev/null
+++ b/src/librustc_mir/transform/uninhabited_enum_branching.rs
@@ -0,0 +1,126 @@
+//! A pass that eliminates branches on uninhabited enum variants.
+
+use crate::transform::{MirPass, MirSource};
+use rustc::mir::{
+    BasicBlock, BasicBlockData, Body, Local, Operand, Rvalue, StatementKind, TerminatorKind,
+};
+use rustc::ty::layout::{Abi, TyLayout, Variants};
+use rustc::ty::{Ty, TyCtxt};
+
+pub struct UninhabitedEnumBranching;
+
+fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
+    if let TerminatorKind::SwitchInt { discr: Operand::Move(p), .. } = terminator {
+        p.as_local()
+    } else {
+        None
+    }
+}
+
+/// If the basic block terminates by switching on a discriminant, this returns the `Ty` the
+/// discriminant is read from. Otherwise, returns None.
+fn get_switched_on_type<'tcx>(
+    block_data: &BasicBlockData<'tcx>,
+    body: &Body<'tcx>,
+) -> Option<Ty<'tcx>> {
+    let terminator = block_data.terminator();
+
+    // Only bother checking blocks which terminate by switching on a local.
+    if let Some(local) = get_discriminant_local(&terminator.kind) {
+        let stmt_before_term = (block_data.statements.len() > 0)
+            .then_with(|| &block_data.statements[block_data.statements.len() - 1].kind);
+
+        if let Some(StatementKind::Assign(box (l, Rvalue::Discriminant(place)))) = stmt_before_term
+        {
+            if l.as_local() == Some(local) {
+                if let Some(r_local) = place.as_local() {
+                    let ty = body.local_decls[r_local].ty;
+
+                    if ty.is_enum() {
+                        return Some(ty);
+                    }
+                }
+            }
+        }
+    }
+
+    None
+}
+
+fn variant_discriminants<'tcx>(
+    layout: &TyLayout<'tcx>,
+    ty: Ty<'tcx>,
+    tcx: TyCtxt<'tcx>,
+) -> Vec<u128> {
+    match &layout.details.variants {
+        Variants::Single { index } => vec![index.as_u32() as u128],
+        Variants::Multiple { variants, .. } => variants
+            .iter_enumerated()
+            .filter_map(|(idx, layout)| {
+                (layout.abi != Abi::Uninhabited)
+                    .then_with(|| ty.discriminant_for_variant(tcx, idx).unwrap().val)
+            })
+            .collect(),
+    }
+}
+
+impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+        if source.promoted.is_some() {
+            return;
+        }
+
+        trace!("UninhabitedEnumBranching starting for {:?}", source);
+
+        let basic_block_count = body.basic_blocks().len();
+
+        for bb in 0..basic_block_count {
+            let bb = BasicBlock::from_usize(bb);
+            trace!("processing block {:?}", bb);
+
+            let discriminant_ty =
+                if let Some(ty) = get_switched_on_type(&body.basic_blocks()[bb], body) {
+                    ty
+                } else {
+                    continue;
+                };
+
+            let layout = tcx.layout_of(tcx.param_env(source.def_id()).and(discriminant_ty));
+
+            let allowed_variants = if let Ok(layout) = layout {
+                variant_discriminants(&layout, discriminant_ty, tcx)
+            } else {
+                continue;
+            };
+
+            trace!("allowed_variants = {:?}", allowed_variants);
+
+            if let TerminatorKind::SwitchInt { values, targets, .. } =
+                &mut body.basic_blocks_mut()[bb].terminator_mut().kind
+            {
+                let vals = &*values;
+                let zipped = vals.iter().zip(targets.into_iter());
+
+                let mut matched_values = Vec::with_capacity(allowed_variants.len());
+                let mut matched_targets = Vec::with_capacity(allowed_variants.len() + 1);
+
+                for (val, target) in zipped {
+                    if allowed_variants.contains(val) {
+                        matched_values.push(*val);
+                        matched_targets.push(*target);
+                    } else {
+                        trace!("eliminating {:?} -> {:?}", val, target);
+                    }
+                }
+
+                // handle the "otherwise" branch
+                matched_targets.push(targets.pop().unwrap());
+
+                *values = matched_values.into();
+                *targets = matched_targets;
+            } else {
+                unreachable!()
+            }
+        }
+    }
+}
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index 96ba8293582..bf01ad1a023 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -395,23 +395,25 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
         )
     }
 
-    crate fn cannot_mutate_in_match_guard(
+    crate fn cannot_mutate_in_immutable_section(
         &self,
         mutate_span: Span,
-        match_span: Span,
-        match_place: &str,
+        immutable_span: Span,
+        immutable_place: &str,
+        immutable_section: &str,
         action: &str,
     ) -> DiagnosticBuilder<'cx> {
         let mut err = struct_span_err!(
             self,
             mutate_span,
             E0510,
-            "cannot {} `{}` in match guard",
+            "cannot {} `{}` in {}",
             action,
-            match_place,
+            immutable_place,
+            immutable_section,
         );
         err.span_label(mutate_span, format!("cannot {}", action));
-        err.span_label(match_span, String::from("value is immutable in match guard"));
+        err.span_label(immutable_span, format!("value is immutable in {}", immutable_section));
         err
     }
 
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index a1846a1fb5e..67e5bfafafd 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -521,7 +521,7 @@ where
 
         let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut {
             ty,
-            mutbl: hir::Mutability::MutMutable
+            mutbl: hir::Mutability::Mutable
         });
         let ref_place = self.new_temp(ref_ty);
         let unit_temp = Place::from(self.new_temp(tcx.mk_unit()));
@@ -580,7 +580,7 @@ where
 
         let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut {
             ty: ety,
-            mutbl: hir::Mutability::MutMutable
+            mutbl: hir::Mutability::Mutable
         });
         let ptr = &Place::from(self.new_temp(ref_ty));
         let can_go = &Place::from(self.new_temp(tcx.types.bool));
diff --git a/src/librustc_parse/Cargo.toml b/src/librustc_parse/Cargo.toml
new file mode 100644
index 00000000000..4579f9d472d
--- /dev/null
+++ b/src/librustc_parse/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_parse"
+version = "0.0.0"
+edition = "2018"
+
+[lib]
+name = "rustc_parse"
+path = "lib.rs"
+doctest = false
+
+[dependencies]
+bitflags = "1.0"
+log = "0.4"
+syntax_pos = { path = "../libsyntax_pos" }
+syntax = { path = "../libsyntax" }
+errors = { path = "../librustc_errors", package = "rustc_errors" }
+rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_lexer = { path = "../librustc_lexer" }
+rustc_target = { path = "../librustc_target" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_parse/error_codes.rs b/src/librustc_parse/error_codes.rs
new file mode 100644
index 00000000000..cf74e09a377
--- /dev/null
+++ b/src/librustc_parse/error_codes.rs
@@ -0,0 +1,174 @@
+// Error messages for EXXXX errors.
+// Each message should start and end with a new line, and be wrapped to 80
+// characters.  In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use
+// `:set tw=0` to disable.
+syntax::register_diagnostics! {
+
+E0178: r##"
+In types, the `+` type operator has low precedence, so it is often necessary
+to use parentheses.
+
+For example:
+
+```compile_fail,E0178
+trait Foo {}
+
+struct Bar<'a> {
+    w: &'a Foo + Copy,   // error, use &'a (Foo + Copy)
+    x: &'a Foo + 'a,     // error, use &'a (Foo + 'a)
+    y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a)
+    z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a)
+}
+```
+
+More details can be found in [RFC 438].
+
+[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
+"##,
+
+E0583: r##"
+A file wasn't found for an out-of-line module.
+
+Erroneous code example:
+
+```ignore (compile_fail not working here; see Issue #43707)
+mod file_that_doesnt_exist; // error: file not found for module
+
+fn main() {}
+```
+
+Please be sure that a file corresponding to the module exists. If you
+want to use a module named `file_that_doesnt_exist`, you need to have a file
+named `file_that_doesnt_exist.rs` or `file_that_doesnt_exist/mod.rs` in the
+same directory.
+"##,
+
+E0584: r##"
+A doc comment that is not attached to anything has been encountered.
+
+Erroneous code example:
+
+```compile_fail,E0584
+trait Island {
+    fn lost();
+
+    /// I'm lost!
+}
+```
+
+A little reminder: a doc comment has to be placed before the item it's supposed
+to document. So if you want to document the `Island` trait, you need to put a
+doc comment before it, not inside it. Same goes for the `lost` method: the doc
+comment needs to be before it:
+
+```
+/// I'm THE island!
+trait Island {
+    /// I'm lost!
+    fn lost();
+}
+```
+"##,
+
+E0585: r##"
+A documentation comment that doesn't document anything was found.
+
+Erroneous code example:
+
+```compile_fail,E0585
+fn main() {
+    // The following doc comment will fail:
+    /// This is a useless doc comment!
+}
+```
+
+Documentation comments need to be followed by items, including functions,
+types, modules, etc. Examples:
+
+```
+/// I'm documenting the following struct:
+struct Foo;
+
+/// I'm documenting the following function:
+fn foo() {}
+```
+"##,
+
+E0586: r##"
+An inclusive range was used with no end.
+
+Erroneous code example:
+
+```compile_fail,E0586
+fn main() {
+    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
+    let x = &tmp[1..=]; // error: inclusive range was used with no end
+}
+```
+
+An inclusive range needs an end in order to *include* it. If you just need a
+start and no end, use a non-inclusive range (with `..`):
+
+```
+fn main() {
+    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
+    let x = &tmp[1..]; // ok!
+}
+```
+
+Or put an end to your inclusive range:
+
+```
+fn main() {
+    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
+    let x = &tmp[1..=3]; // ok!
+}
+```
+"##,
+
+E0704: r##"
+This error indicates that a incorrect visibility restriction was specified.
+
+Example of erroneous code:
+
+```compile_fail,E0704
+mod foo {
+    pub(foo) struct Bar {
+        x: i32
+    }
+}
+```
+
+To make struct `Bar` only visible in module `foo` the `in` keyword should be
+used:
+```
+mod foo {
+    pub(in crate::foo) struct Bar {
+        x: i32
+    }
+}
+# fn main() {}
+```
+
+For more information see the Rust Reference on [Visibility].
+
+[Visibility]: https://doc.rust-lang.org/reference/visibility-and-privacy.html
+"##,
+
+E0743: r##"
+C-variadic has been used on a non-foreign function.
+
+Erroneous code example:
+
+```compile_fail,E0743
+fn foo2(x: u8, ...) {} // error!
+```
+
+Only foreign functions can use C-variadic (`...`). It is used to give an
+undefined number of parameters to a given function (like `printf` in C). The
+equivalent in Rust would be to use macros directly.
+"##,
+
+;
+
+}
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/librustc_parse/lexer/mod.rs
index 48cf117f65a..5de63cb39d1 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/librustc_parse/lexer/mod.rs
@@ -1,7 +1,7 @@
-use crate::parse::token::{self, Token, TokenKind};
-use crate::sess::ParseSess;
-use crate::symbol::{sym, Symbol};
-use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
+use syntax::token::{self, Token, TokenKind};
+use syntax::sess::ParseSess;
+use syntax::symbol::{sym, Symbol};
+use syntax::util::comments;
 
 use errors::{FatalError, DiagnosticBuilder};
 use syntax_pos::{BytePos, Pos, Span};
@@ -13,12 +13,10 @@ use std::convert::TryInto;
 use rustc_data_structures::sync::Lrc;
 use log::debug;
 
-#[cfg(test)]
-mod tests;
-
-pub mod comments;
 mod tokentrees;
 mod unicode_chars;
+mod unescape_error_reporting;
+use unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 #[derive(Clone, Debug)]
 pub struct UnmatchedBrace {
@@ -34,7 +32,8 @@ pub struct StringReader<'a> {
     /// Initial position, read-only.
     start_pos: BytePos,
     /// The absolute offset within the source_map of the current character.
-    pos: BytePos,
+    // FIXME(#64197): `pub` is needed by tests for now.
+    pub pos: BytePos,
     /// Stop reading src at this index.
     end_src_index: usize,
     /// Source text to tokenize.
@@ -68,7 +67,7 @@ impl<'a> StringReader<'a> {
         let end = sess.source_map().lookup_byte_offset(span.hi());
 
         // Make the range zero-length if the span is invalid.
-        if span.lo() > span.hi() || begin.sf.start_pos != end.sf.start_pos {
+        if begin.sf.start_pos != end.sf.start_pos {
             span = span.shrink_to_lo();
         }
 
@@ -178,7 +177,7 @@ impl<'a> StringReader<'a> {
             rustc_lexer::TokenKind::LineComment => {
                 let string = self.str_from(start);
                 // comments with only more "/"s are not doc comments
-                let tok = if is_doc_comment(string) {
+                let tok = if comments::is_line_doc_comment(string) {
                     self.forbid_bare_cr(start, string, "bare CR not allowed in doc-comment");
                     token::DocComment(Symbol::intern(string))
                 } else {
@@ -191,7 +190,7 @@ impl<'a> StringReader<'a> {
                 let string = self.str_from(start);
                 // block comments starting with "/**" or "/*!" are doc-comments
                 // but comments with only "*"s between two "/"s are not
-                let is_doc_comment = is_block_doc_comment(string);
+                let is_doc_comment = comments::is_block_doc_comment(string);
 
                 if !terminated {
                     let msg = if is_doc_comment {
@@ -642,18 +641,3 @@ impl<'a> StringReader<'a> {
         }
     }
 }
-
-fn is_doc_comment(s: &str) -> bool {
-    let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/') ||
-              s.starts_with("//!");
-    debug!("is {:?} a doc comment? {}", s, res);
-    res
-}
-
-fn is_block_doc_comment(s: &str) -> bool {
-    // Prevent `/**/` from being parsed as a doc comment
-    let res = ((s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*') ||
-               s.starts_with("/*!")) && s.len() >= 5;
-    debug!("is {:?} a doc comment? {}", s, res);
-    res
-}
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/librustc_parse/lexer/tokentrees.rs
index de8ac2c71e8..1353591308b 100644
--- a/src/libsyntax/parse/lexer/tokentrees.rs
+++ b/src/librustc_parse/lexer/tokentrees.rs
@@ -3,10 +3,11 @@ use syntax_pos::Span;
 
 use super::{StringReader, UnmatchedBrace};
 
-use crate::print::pprust::token_to_string;
-use crate::parse::token::{self, Token};
-use crate::parse::PResult;
-use crate::tokenstream::{DelimSpan, IsJoint::{self, *}, TokenStream, TokenTree, TreeAndJoint};
+use syntax::print::pprust::token_to_string;
+use syntax::token::{self, Token};
+use syntax::tokenstream::{DelimSpan, IsJoint::{self, *}, TokenStream, TokenTree, TreeAndJoint};
+
+use errors::PResult;
 
 impl<'a> StringReader<'a> {
     crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec<UnmatchedBrace>) {
diff --git a/src/libsyntax/parse/unescape_error_reporting.rs b/src/librustc_parse/lexer/unescape_error_reporting.rs
index 5565015179c..a5749d07e62 100644
--- a/src/libsyntax/parse/unescape_error_reporting.rs
+++ b/src/librustc_parse/lexer/unescape_error_reporting.rs
@@ -6,7 +6,7 @@ use std::iter::once;
 use rustc_lexer::unescape::{EscapeError, Mode};
 use syntax_pos::{Span, BytePos};
 
-use crate::errors::{Handler, Applicability};
+use syntax::errors::{Handler, Applicability};
 
 pub(crate) fn emit_unescape_error(
     handler: &Handler,
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/librustc_parse/lexer/unicode_chars.rs
index 525b4215aff..6eb995b61d3 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/librustc_parse/lexer/unicode_chars.rs
@@ -4,7 +4,7 @@
 use super::StringReader;
 use errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::{BytePos, Pos, Span, symbol::kw};
-use crate::parse::token;
+use crate::token;
 
 #[rustfmt::skip] // for line breaks
 const UNICODE_ARRAY: &[(char, &str, char)] = &[
diff --git a/src/libsyntax/parse/mod.rs b/src/librustc_parse/lib.rs
index 6d8ecdf805b..9f507d5319e 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/librustc_parse/lib.rs
@@ -1,15 +1,14 @@
 //! The main parser interface.
 
-use crate::ast;
-use crate::parse::parser::{Parser, emit_unclosed_delims, make_unclosed_delims_error};
-use crate::parse::token::Nonterminal;
-use crate::tokenstream::{self, TokenStream, TokenTree};
-use crate::print::pprust;
-use crate::sess::ParseSess;
-
-use errors::{FatalError, Level, Diagnostic, DiagnosticBuilder};
-#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert_size;
+#![feature(crate_visibility_modifier)]
+
+use syntax::ast;
+use syntax::print::pprust;
+use syntax::sess::ParseSess;
+use syntax::token::{self, Nonterminal};
+use syntax::tokenstream::{self, TokenStream, TokenTree};
+
+use errors::{PResult, FatalError, Level, Diagnostic};
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{Span, SourceFile, FileName};
 
@@ -19,24 +18,14 @@ use std::str;
 
 use log::info;
 
-#[cfg(test)]
-mod tests;
+pub const MACRO_ARGUMENTS: Option<&'static str> = Some("macro arguments");
 
 #[macro_use]
 pub mod parser;
+use parser::{Parser, emit_unclosed_delims, make_unclosed_delims_error};
 pub mod lexer;
-pub mod token;
-
-crate mod classify;
-crate mod literal;
-crate mod unescape_error_reporting;
-
-pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
-
-// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
-// (See also the comment on `DiagnosticBuilderInner`.)
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(PResult<'_, bool>, 16);
+pub mod validate_attr;
+pub mod error_codes;
 
 #[derive(Clone)]
 pub struct Directory<'a> {
@@ -51,7 +40,7 @@ pub enum DirectoryOwnership {
         relative: Option<ast::Ident>,
     },
     UnownedViaBlock,
-    UnownedViaMod(bool /* legacy warnings? */),
+    UnownedViaMod,
 }
 
 // A bunch of utility functions of the form `parse_<thing>_from_<source>`
@@ -287,7 +276,7 @@ pub fn parse_in_attr<'a, T>(
 ) -> PResult<'a, T> {
     let mut parser = Parser::new(
         sess,
-        attr.tokens.clone(),
+        attr.get_normal_item().tokens.clone(),
         None,
         false,
         false,
@@ -393,18 +382,22 @@ fn prepend_attrs(
 
         let source = pprust::attribute_to_string(attr);
         let macro_filename = FileName::macro_expansion_source_code(&source);
-        if attr.is_sugared_doc {
-            let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
-            builder.push(stream);
-            continue
-        }
+
+        let item = match attr.kind {
+            ast::AttrKind::Normal(ref item) => item,
+            ast::AttrKind::DocComment(_) => {
+                let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
+                builder.push(stream);
+                continue
+            }
+        };
 
         // synthesize # [ $path $tokens ] manually here
         let mut brackets = tokenstream::TokenStreamBuilder::new();
 
         // For simple paths, push the identifier directly
-        if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() {
-            let ident = attr.path.segments[0].ident;
+        if item.path.segments.len() == 1 && item.path.segments[0].args.is_none() {
+            let ident = item.path.segments[0].ident;
             let token = token::Ident(ident.name, ident.as_str().starts_with("r#"));
             brackets.push(tokenstream::TokenTree::token(token, ident.span));
 
@@ -415,7 +408,7 @@ fn prepend_attrs(
             brackets.push(stream);
         }
 
-        brackets.push(attr.tokens.clone());
+        brackets.push(item.tokens.clone());
 
         // The span we list here for `#` and for `[ ... ]` are both wrong in
         // that it encompasses more than each token, but it hopefully is "good
diff --git a/src/libsyntax/parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs
index 188a144cac9..524b551e54c 100644
--- a/src/libsyntax/parse/parser/attr.rs
+++ b/src/librustc_parse/parser/attr.rs
@@ -1,9 +1,11 @@
-use super::{SeqSep, PResult, Parser, TokenType, PathStyle};
-use crate::attr;
-use crate::ast;
-use crate::parse::token::{self, Nonterminal, DelimToken};
-use crate::tokenstream::{TokenStream, TokenTree};
-use crate::source_map::Span;
+use super::{SeqSep, Parser, TokenType, PathStyle};
+use syntax::attr;
+use syntax::ast;
+use syntax::util::comments;
+use syntax::token::{self, Nonterminal, DelimToken};
+use syntax::tokenstream::{TokenStream, TokenTree};
+use syntax_pos::{Span, Symbol};
+use errors::PResult;
 
 use log::debug;
 
@@ -43,7 +45,7 @@ impl<'a> Parser<'a> {
                     just_parsed_doc_comment = false;
                 }
                 token::DocComment(s) => {
-                    let attr = attr::mk_sugared_doc_attr(s, self.token.span);
+                    let attr = self.mk_doc_comment(s);
                     if attr.style != ast::AttrStyle::Outer {
                         let mut err = self.fatal("expected outer doc comment");
                         err.note("inner doc comments like this (starting with \
@@ -60,6 +62,11 @@ impl<'a> Parser<'a> {
         Ok(attrs)
     }
 
+    fn mk_doc_comment(&self, s: Symbol) -> ast::Attribute {
+        let style = comments::doc_comment_style(&s.as_str());
+        attr::mk_doc_comment(style, s, self.token.span)
+    }
+
     /// Matches `attribute = # ! [ meta_item ]`.
     ///
     /// If `permit_inner` is `true`, then a leading `!` indicates an inner
@@ -149,13 +156,7 @@ impl<'a> Parser<'a> {
             }
         };
 
-        Ok(ast::Attribute {
-            item,
-            id: attr::mk_attr_id(),
-            style,
-            is_sugared_doc: false,
-            span,
-        })
+        Ok(attr::mk_attr_from_item(style, item, span))
     }
 
     /// Parses an inner part of an attribute (the path and following tokens).
@@ -229,7 +230,7 @@ impl<'a> Parser<'a> {
                 }
                 token::DocComment(s) => {
                     // We need to get the position of this token before we bump.
-                    let attr = attr::mk_sugared_doc_attr(s, self.token.span);
+                    let attr = self.mk_doc_comment(s);
                     if attr.style == ast::AttrStyle::Inner {
                         attrs.push(attr);
                         self.bump();
@@ -260,7 +261,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited.
-    crate fn parse_cfg_attr(&mut self) -> PResult<'a, (ast::MetaItem, Vec<(ast::AttrItem, Span)>)> {
+    pub fn parse_cfg_attr(&mut self) -> PResult<'a, (ast::MetaItem, Vec<(ast::AttrItem, Span)>)> {
         self.expect(&token::OpenDelim(token::Paren))?;
 
         let cfg_predicate = self.parse_meta_item()?;
diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index fcf3b4c0aa8..38eae008537 100644
--- a/src/libsyntax/parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -1,18 +1,18 @@
-use super::{
-    BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType,
-    SeqSep, PResult, Parser
-};
-use crate::ast::{
+use super::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType, SeqSep, Parser};
+
+use syntax::ast::{
     self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
     Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
 };
-use crate::parse::token::{self, TokenKind, token_can_begin_expr};
-use crate::print::pprust;
-use crate::ptr::P;
-use crate::symbol::{kw, sym};
-use crate::ThinVec;
-use crate::util::parser::AssocOp;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
+use syntax::token::{self, TokenKind, token_can_begin_expr};
+use syntax::print::pprust;
+use syntax::ptr::P;
+use syntax::symbol::{kw, sym};
+use syntax::ThinVec;
+use syntax::util::parser::AssocOp;
+use syntax::struct_span_err;
+
+use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, pluralize};
 use rustc_data_structures::fx::FxHashSet;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
 use log::{debug, trace};
@@ -289,7 +289,7 @@ impl<'a> Parser<'a> {
             };
             (format!("expected one of {}, found {}", expect, actual),
                 (self.sess.source_map().next_point(self.prev_span),
-                format!("expected one of {} here", short_expect)))
+                format!("expected one of {}", short_expect)))
         } else if expected.is_empty() {
             (format!("unexpected token: {}", actual),
                 (self.prev_span, "unexpected token after this".to_string()))
@@ -360,11 +360,11 @@ impl<'a> Parser<'a> {
     }
 
     pub fn maybe_annotate_with_ascription(
-        &self,
+        &mut self,
         err: &mut DiagnosticBuilder<'_>,
         maybe_expected_semicolon: bool,
     ) {
-        if let Some((sp, likely_path)) = self.last_type_ascription {
+        if let Some((sp, likely_path)) = self.last_type_ascription.take() {
             let sm = self.sess.source_map();
             let next_pos = sm.lookup_char_pos(self.token.span.lo());
             let op_pos = sm.lookup_char_pos(sp.hi());
@@ -515,11 +515,11 @@ impl<'a> Parser<'a> {
             self.diagnostic()
                 .struct_span_err(
                     span,
-                    &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)),
+                    &format!("unmatched angle bracket{}", pluralize!(total_num_of_gt)),
                 )
                 .span_suggestion(
                     span,
-                    &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)),
+                    &format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)),
                     String::new(),
                     Applicability::MachineApplicable,
                 )
@@ -1088,8 +1088,15 @@ impl<'a> Parser<'a> {
     }
 
     pub(super) fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool {
-        self.token.is_ident() &&
-            if let ast::ExprKind::Path(..) = node { true } else { false } &&
+        (self.token == token::Lt && // `foo:<bar`, likely a typoed turbofish.
+            self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
+        ) ||
+            self.token.is_ident() &&
+            match node {
+                // `foo::` → `foo:` or `foo.bar::` → `foo.bar:`
+                ast::ExprKind::Path(..) | ast::ExprKind::Field(..) => true,
+                _ => false,
+            } &&
             !self.token.is_reserved_ident() &&           // v `foo:bar(baz)`
             self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) ||
             self.look_ahead(1, |t| t == &token::Lt) &&     // `foo:bar<baz`
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 97b1092452a..dadb91f8b3c 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -1,26 +1,24 @@
-use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode};
+use super::{Parser, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode};
 use super::{SemiColonMode, SeqSep, TokenExpectType};
 use super::pat::{GateOr, PARAM_EXPECTED};
 use super::diagnostics::Error;
+use crate::maybe_recover_from_interpolated_ty_qpath;
 
-use crate::parse::literal::LitError;
-
-use crate::ast::{
+use syntax::ast::{
     self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode,
     Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind,
     FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit,
 };
-use crate::maybe_recover_from_interpolated_ty_qpath;
-use crate::parse::classify;
-use crate::parse::token::{self, Token, TokenKind};
-use crate::print::pprust;
-use crate::ptr::P;
-use crate::source_map::{self, Span};
-use crate::symbol::{kw, sym};
-use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
-
-use errors::Applicability;
+use syntax::token::{self, Token, TokenKind};
+use syntax::print::pprust;
+use syntax::ptr::P;
+use syntax::source_map::{self, Span};
+use syntax::util::classify;
+use syntax::util::literal::LitError;
+use syntax::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
+use syntax_pos::symbol::{kw, sym};
 use syntax_pos::Symbol;
+use errors::{PResult, Applicability};
 use std::mem;
 use rustc_data_structures::thin_vec::ThinVec;
 
@@ -252,7 +250,7 @@ impl<'a> Parser<'a> {
                 self.last_type_ascription = Some((self.prev_span, maybe_path));
 
                 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
-                self.sess.gated_spans.type_ascription.borrow_mut().push(lhs.span);
+                self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
                 continue
             } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
                 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
@@ -455,7 +453,7 @@ impl<'a> Parser<'a> {
                 let e = self.parse_prefix_expr(None);
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 let span = lo.to(span);
-                self.sess.gated_spans.box_syntax.borrow_mut().push(span);
+                self.sess.gated_spans.gate(sym::box_syntax, span);
                 (span, ExprKind::Box(e))
             }
             token::Ident(..) if self.token.is_ident_named(sym::not) => {
@@ -1045,7 +1043,7 @@ impl<'a> Parser<'a> {
                     }
 
                     let span = lo.to(hi);
-                    self.sess.gated_spans.yields.borrow_mut().push(span);
+                    self.sess.gated_spans.gate(sym::generators, 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) {
@@ -1116,7 +1114,11 @@ impl<'a> Parser<'a> {
                 Err(self.span_fatal(token.span, &msg))
             }
             Err(err) => {
-                let (lit, span) = (token.expect_lit(), token.span);
+                let span = token.span;
+                let lit = match token.kind {
+                    token::Literal(lit) => lit,
+                    _ => unreachable!(),
+                };
                 self.bump();
                 self.error_literal_from_token(err, lit, span);
                 // Pack possible quotes and prefixes from the original literal into
@@ -1264,7 +1266,7 @@ impl<'a> Parser<'a> {
         outer_attrs: ThinVec<Attribute>,
     ) -> PResult<'a, P<Expr>> {
         if let Some(label) = opt_label {
-            self.sess.gated_spans.label_break_value.borrow_mut().push(label.ident.span);
+            self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
         }
 
         self.expect(&token::OpenDelim(token::Brace))?;
@@ -1293,7 +1295,7 @@ impl<'a> Parser<'a> {
         };
         if asyncness.is_async() {
             // Feature-gate `async ||` closures.
-            self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.gate(sym::async_closure, self.prev_span);
         }
 
         let capture_clause = self.parse_capture_clause();
@@ -1415,8 +1417,7 @@ impl<'a> Parser<'a> {
 
         if let ExprKind::Let(..) = cond.kind {
             // Remove the last feature gating of a `let` expression since it's stable.
-            let last = self.sess.gated_spans.let_chains.borrow_mut().pop();
-            debug_assert_eq!(cond.span, last.unwrap());
+            self.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
         }
 
         Ok(cond)
@@ -1433,7 +1434,7 @@ impl<'a> Parser<'a> {
             |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
         )?;
         let span = lo.to(expr.span);
-        self.sess.gated_spans.let_chains.borrow_mut().push(span);
+        self.sess.gated_spans.gate(sym::let_chains, span);
         Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
     }
 
@@ -1654,7 +1655,7 @@ impl<'a> Parser<'a> {
             Err(error)
         } else {
             let span = span_lo.to(body.span);
-            self.sess.gated_spans.try_blocks.borrow_mut().push(span);
+            self.sess.gated_spans.gate(sym::try_blocks, span);
             Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
         }
     }
diff --git a/src/libsyntax/parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs
index 51caae69c86..ba5eafc0ed7 100644
--- a/src/libsyntax/parse/parser/generics.rs
+++ b/src/librustc_parse/parser/generics.rs
@@ -1,9 +1,11 @@
-use super::{Parser, PResult};
+use super::Parser;
 
-use crate::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute};
-use crate::parse::token;
-use crate::source_map::DUMMY_SP;
-use crate::symbol::kw;
+use syntax::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute};
+use syntax::token;
+use syntax::source_map::DUMMY_SP;
+use syntax_pos::symbol::{kw, sym};
+
+use errors::PResult;
 
 impl<'a> Parser<'a> {
     /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -62,7 +64,7 @@ impl<'a> Parser<'a> {
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
 
-        self.sess.gated_spans.const_generics.borrow_mut().push(lo.to(self.prev_span));
+        self.sess.gated_spans.gate(sym::const_generics, lo.to(self.prev_span));
 
         Ok(GenericParam {
             ident,
diff --git a/src/libsyntax/parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 5b60e7e6dba..3e21436d313 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -1,25 +1,25 @@
-use super::{Parser, PResult, PathStyle};
+use super::{Parser, PathStyle};
 use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};
 
 use crate::maybe_whole;
-use crate::ptr::P;
-use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle, AnonConst, Item, ItemKind};
-use crate::ast::{ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
-use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
-use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
-use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
-use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, MethodSig, SelfKind, Param};
-use crate::parse::token;
-use crate::tokenstream::{TokenTree, TokenStream};
-use crate::symbol::{kw, sym};
-use crate::source_map::{self, respan, Span};
-use crate::ThinVec;
+
+use syntax::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
+use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
+use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
+use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
+use syntax::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
+use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
+use syntax::ptr::P;
+use syntax::ThinVec;
+use syntax::token;
+use syntax::tokenstream::{TokenTree, TokenStream};
+use syntax::source_map::{self, respan, Span};
+use syntax_pos::BytePos;
+use syntax_pos::symbol::{kw, sym};
 
 use log::debug;
 use std::mem;
-use rustc_target::spec::abi::Abi;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
-use syntax_pos::BytePos;
+use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
 
 /// Whether the type alias or associated type is a concrete type or an opaque type.
 #[derive(Debug)]
@@ -111,7 +111,7 @@ impl<'a> Parser<'a> {
                 return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
             }
 
-            let opt_abi = self.parse_opt_abi()?;
+            let abi = self.parse_opt_abi()?;
 
             if self.eat_keyword(kw::Fn) {
                 // EXTERN FUNCTION ITEM
@@ -120,12 +120,12 @@ impl<'a> Parser<'a> {
                     unsafety: Unsafety::Normal,
                     asyncness: respan(fn_span, IsAsync::NotAsync),
                     constness: respan(fn_span, Constness::NotConst),
-                    abi: opt_abi.unwrap_or(Abi::C),
+                    abi,
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             } else if self.check(&token::OpenDelim(token::Brace)) {
                 return Ok(Some(
-                    self.parse_item_foreign_mod(lo, opt_abi, vis, attrs, extern_sp)?,
+                    self.parse_item_foreign_mod(lo, abi, vis, attrs, extern_sp)?,
                 ));
             }
 
@@ -147,9 +147,7 @@ impl<'a> Parser<'a> {
                 let unsafety = self.parse_unsafety();
 
                 if self.check_keyword(kw::Extern) {
-                    self.sess.gated_spans.const_extern_fn.borrow_mut().push(
-                        lo.to(self.token.span)
-                    );
+                    self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span));
                 }
                 let abi = self.parse_extern_abi()?;
                 self.bump(); // `fn`
@@ -201,7 +199,7 @@ impl<'a> Parser<'a> {
                     unsafety,
                     asyncness,
                     constness: respan(fn_span, Constness::NotConst),
-                    abi: Abi::Rust,
+                    abi: Abi::new(sym::Rust, fn_span),
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             }
@@ -238,7 +236,7 @@ impl<'a> Parser<'a> {
                 unsafety: Unsafety::Normal,
                 asyncness: respan(fn_span, IsAsync::NotAsync),
                 constness: respan(fn_span, Constness::NotConst),
-                abi: Abi::Rust,
+                abi: Abi::new(sym::Rust, fn_span),
             };
             return self.parse_item_fn(lo, vis, attrs, header);
         }
@@ -483,12 +481,14 @@ impl<'a> Parser<'a> {
     /// Emits an expected-item-after-attributes error.
     fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a,  ()> {
         let message = match attrs.last() {
-            Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
-            _ => "expected item after attributes",
+            Some(&Attribute { kind: AttrKind::DocComment(_), .. }) =>
+                "expected item after doc comment",
+            _ =>
+                "expected item after attributes",
         };
 
         let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
-        if attrs.last().unwrap().is_sugared_doc {
+        if attrs.last().unwrap().is_doc_comment() {
             err.span_label(self.prev_span, "this doc comment doesn't document anything");
         }
         Err(err)
@@ -830,7 +830,7 @@ impl<'a> Parser<'a> {
                     .emit();
             }
 
-            self.sess.gated_spans.trait_alias.borrow_mut().push(whole_span);
+            self.sess.gated_spans.gate(sym::trait_alias, whole_span);
 
             Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
         } else {
@@ -1113,15 +1113,13 @@ impl<'a> Parser<'a> {
     fn parse_item_foreign_mod(
         &mut self,
         lo: Span,
-        opt_abi: Option<Abi>,
+        abi: Abi,
         visibility: Visibility,
         mut attrs: Vec<Attribute>,
         extern_sp: Span,
     ) -> PResult<'a, P<Item>> {
         self.expect(&token::OpenDelim(token::Brace))?;
 
-        let abi = opt_abi.unwrap_or(Abi::C);
-
         attrs.extend(self.parse_inner_attributes()?);
 
         let mut foreign_items = vec![];
@@ -1712,7 +1710,7 @@ impl<'a> Parser<'a> {
         let span = lo.to(self.prev_span);
 
         if !def.legacy {
-            self.sess.gated_spans.decl_macro.borrow_mut().push(span);
+            self.sess.gated_spans.gate(sym::decl_macro, span);
         }
 
         Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
@@ -1799,11 +1797,11 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, Option<P<Item>>> {
         let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
             is_self_allowed: false,
-            allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe,
+            allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe,
             is_name_required: |_| true,
         })?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
-        let kind = ItemKind::Fn(decl, header, generics, body);
+        let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
         self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
     }
 
@@ -1900,14 +1898,14 @@ impl<'a> Parser<'a> {
     fn parse_method_sig(
         &mut self,
         is_name_required: fn(&token::Token) -> bool,
-    ) -> PResult<'a, (Ident, MethodSig, Generics)> {
+    ) -> PResult<'a, (Ident, FnSig, Generics)> {
         let header = self.parse_fn_front_matter()?;
         let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
             is_self_allowed: true,
             allow_c_variadic: false,
             is_name_required,
         })?;
-        Ok((ident, MethodSig { header, decl }, generics))
+        Ok((ident, FnSig { header, decl }, generics))
     }
 
     /// Parses all the "front matter" for a `fn` declaration, up to
@@ -1928,7 +1926,7 @@ impl<'a> Parser<'a> {
         let asyncness = respan(self.prev_span, asyncness);
         let unsafety = self.parse_unsafety();
         let (constness, unsafety, abi) = if is_const_fn {
-            (respan(const_span, Constness::Const), unsafety, Abi::Rust)
+            (respan(const_span, Constness::Const), unsafety, Abi::default())
         } else {
             let abi = self.parse_extern_abi()?;
             (respan(self.prev_span, Constness::NotConst), unsafety, abi)
diff --git a/src/libsyntax/parse/parser.rs b/src/librustc_parse/parser/mod.rs
index e81d4573b73..a491d91e20f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -11,25 +11,26 @@ mod generics;
 mod diagnostics;
 use diagnostics::Error;
 
-use crate::ast::{
-    self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
+use crate::{Directory, DirectoryOwnership};
+use crate::lexer::UnmatchedBrace;
+
+use syntax::ast::{
+    self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
     IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
 };
-use crate::parse::{PResult, Directory, DirectoryOwnership};
-use crate::parse::lexer::UnmatchedBrace;
-use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
-use crate::parse::token::{self, Token, TokenKind, DelimToken};
-use crate::print::pprust;
-use crate::ptr::P;
-use crate::sess::ParseSess;
-use crate::source_map::respan;
-use crate::symbol::{kw, sym, Symbol};
-use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
-use crate::ThinVec;
-
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
-use rustc_target::spec::abi::{self, Abi};
+
+use syntax::print::pprust;
+use syntax::ptr::P;
+use syntax::token::{self, Token, TokenKind, DelimToken};
+use syntax::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
+use syntax::sess::ParseSess;
+use syntax::source_map::respan;
+use syntax::struct_span_err;
+use syntax::util::comments::{doc_comment_style, strip_doc_comment_decoration};
+use syntax_pos::symbol::{kw, sym, Symbol};
 use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
+use rustc_data_structures::thin_vec::ThinVec;
+use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use log::debug;
 
 use std::borrow::Cow;
@@ -209,12 +210,12 @@ impl TokenCursor {
         loop {
             let tree = if !self.frame.open_delim {
                 self.frame.open_delim = true;
-                TokenTree::open_tt(self.frame.span.open, self.frame.delim)
+                TokenTree::open_tt(self.frame.span, self.frame.delim)
             } else if let Some(tree) = self.frame.tree_cursor.next() {
                 tree
             } else if !self.frame.close_delim {
                 self.frame.close_delim = true;
-                TokenTree::close_tt(self.frame.span.close, self.frame.delim)
+                TokenTree::close_tt(self.frame.span, self.frame.delim)
             } else if let Some(frame) = self.stack.pop() {
                 self.frame = frame;
                 continue
@@ -1121,7 +1122,7 @@ impl<'a> Parser<'a> {
         self.expected_tokens.push(TokenType::Keyword(kw::Crate));
         if self.is_crate_vis() {
             self.bump(); // `crate`
-            self.sess.gated_spans.crate_visibility_modifier.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.gate(sym::crate_visibility_modifier, self.prev_span);
             return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate)));
         }
 
@@ -1206,48 +1207,41 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
-    /// Parses `extern` followed by an optional ABI string, or nothing.
+    /// Parses `extern string_literal?`.
+    /// If `extern` is not found, the Rust ABI is used.
+    /// If `extern` is found and a `string_literal` does not follow, the C ABI is used.
     fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
-        if self.eat_keyword(kw::Extern) {
-            Ok(self.parse_opt_abi()?.unwrap_or(Abi::C))
+        Ok(if self.eat_keyword(kw::Extern) {
+            self.parse_opt_abi()?
         } else {
-            Ok(Abi::Rust)
-        }
+            Abi::default()
+        })
     }
 
-    /// Parses a string as an ABI spec on an extern type or module. Consumes
-    /// the `extern` keyword, if one is found.
-    fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
-        match self.token.kind {
-            token::Literal(token::Lit { kind: token::Str, symbol, suffix }) |
-            token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => {
-                self.expect_no_suffix(self.token.span, "an ABI spec", suffix);
-                self.bump();
-                match abi::lookup(&symbol.as_str()) {
-                    Some(abi) => Ok(Some(abi)),
-                    None => {
-                        self.error_on_invalid_abi(symbol);
-                        Ok(None)
-                    }
+    /// Parses a string literal as an ABI spec.
+    /// If one is not found, the "C" ABI is used.
+    fn parse_opt_abi(&mut self) -> PResult<'a, Abi> {
+        let span = if self.token.can_begin_literal_or_bool() {
+            let ast::Lit { span, kind, .. } = self.parse_lit()?;
+            match kind {
+                ast::LitKind::Str(symbol, _) => return Ok(Abi::new(symbol, span)),
+                ast::LitKind::Err(_) => {}
+                _ => {
+                    self.struct_span_err(span, "non-string ABI literal")
+                        .span_suggestion(
+                            span,
+                            "specify the ABI with a string literal",
+                            "\"C\"".to_string(),
+                            Applicability::MaybeIncorrect,
+                        )
+                        .emit();
                 }
             }
-            _ => Ok(None),
-        }
-    }
-
-    /// Emit an error where `symbol` is an invalid ABI.
-    fn error_on_invalid_abi(&self, symbol: Symbol) {
-        let prev_span = self.prev_span;
-        struct_span_err!(
-            self.sess.span_diagnostic,
-            prev_span,
-            E0703,
-            "invalid ABI: found `{}`",
-            symbol
-        )
-        .span_label(prev_span, "invalid ABI")
-        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
-        .emit();
+            span
+        } else {
+            self.prev_span
+        };
+        Ok(Abi::new(sym::C, span))
     }
 
     /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
diff --git a/src/libsyntax/parse/parser/module.rs b/src/librustc_parse/parser/module.rs
index a0e4d2bbb7a..3110f15e80b 100644
--- a/src/libsyntax/parse/parser/module.rs
+++ b/src/librustc_parse/parser/module.rs
@@ -1,13 +1,16 @@
-use super::{Parser, PResult};
+use super::Parser;
 use super::item::ItemInfo;
 use super::diagnostics::Error;
 
-use crate::attr;
-use crate::ast::{self, Ident, Attribute, ItemKind, Mod, Crate};
-use crate::parse::{new_sub_parser_from_file, DirectoryOwnership};
-use crate::parse::token::{self, TokenKind};
-use crate::source_map::{SourceMap, Span, DUMMY_SP, FileName};
-use crate::symbol::sym;
+use crate::{new_sub_parser_from_file, DirectoryOwnership};
+
+use syntax::attr;
+use syntax::ast::{self, Ident, Attribute, ItemKind, Mod, Crate};
+use syntax::token::{self, TokenKind};
+use syntax::source_map::{SourceMap, Span, DUMMY_SP, FileName};
+
+use syntax_pos::symbol::sym;
+use errors::PResult;
 
 use std::path::{self, Path, PathBuf};
 
@@ -21,7 +24,6 @@ pub(super) struct ModulePath {
 pub(super) struct ModulePathSuccess {
     pub path: PathBuf,
     pub directory_ownership: DirectoryOwnership,
-    warn: bool,
 }
 
 impl<'a> Parser<'a> {
@@ -38,34 +40,22 @@ impl<'a> Parser<'a> {
 
     /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
     pub(super) fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
-        let (in_cfg, outer_attrs) = {
-            // FIXME(Centril): This results in a cycle between config and parsing.
-            // Consider using dynamic dispatch via `self.sess` to disentangle the knot.
-            let mut strip_unconfigured = crate::config::StripUnconfigured {
-                sess: self.sess,
-                features: None, // Don't perform gated feature checking.
-            };
-            let mut outer_attrs = outer_attrs.to_owned();
-            strip_unconfigured.process_cfg_attrs(&mut outer_attrs);
-            (!self.cfg_mods || strip_unconfigured.in_cfg(&outer_attrs), outer_attrs)
-        };
+        // HACK(Centril): See documentation on `ParseSess::process_cfg_mod`.
+        let (in_cfg, outer_attrs) = (self.sess.process_cfg_mod)(
+            self.sess,
+            self.cfg_mods,
+            outer_attrs,
+        );
 
         let id_span = self.token.span;
         let id = self.parse_ident()?;
         if self.eat(&token::Semi) {
             if in_cfg && self.recurse_into_file_modules {
                 // This mod is in an external file. Let's go get it!
-                let ModulePathSuccess { path, directory_ownership, warn } =
+                let ModulePathSuccess { path, directory_ownership } =
                     self.submod_path(id, &outer_attrs, id_span)?;
-                let (module, mut attrs) =
+                let (module, attrs) =
                     self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
-                // Record that we fetched the mod from an external file.
-                if warn {
-                    let attr = attr::mk_attr_outer(
-                        attr::mk_word_item(Ident::with_dummy_span(sym::warn_directory_ownership)));
-                    attr::mark_known(&attr);
-                    attrs.push(attr);
-                }
                 Ok((id, ItemKind::Mod(module), Some(attrs)))
             } else {
                 let placeholder = ast::Mod {
@@ -136,17 +126,16 @@ impl<'a> Parser<'a> {
                     // `#[path]` included and contains a `mod foo;` declaration.
                     // If you encounter this, it's your own darn fault :P
                     Some(_) => DirectoryOwnership::Owned { relative: None },
-                    _ => DirectoryOwnership::UnownedViaMod(true),
+                    _ => DirectoryOwnership::UnownedViaMod,
                 },
                 path,
-                warn: false,
             });
         }
 
         let relative = match self.directory.ownership {
             DirectoryOwnership::Owned { relative } => relative,
             DirectoryOwnership::UnownedViaBlock |
-            DirectoryOwnership::UnownedViaMod(_) => None,
+            DirectoryOwnership::UnownedViaMod => None,
         };
         let paths = Parser::default_submod_path(
                         id, relative, &self.directory.path, self.sess.source_map());
@@ -167,12 +156,7 @@ impl<'a> Parser<'a> {
                 }
                 Err(err)
             }
-            DirectoryOwnership::UnownedViaMod(warn) => {
-                if warn {
-                    if let Ok(result) = paths.result {
-                        return Ok(ModulePathSuccess { warn: true, ..result });
-                    }
-                }
+            DirectoryOwnership::UnownedViaMod => {
                 let mut err = self.diagnostic().struct_span_err(id_sp,
                     "cannot declare a new module at this location");
                 if !id_sp.is_dummy() {
@@ -210,7 +194,7 @@ impl<'a> Parser<'a> {
             // `/` to `\`.
             #[cfg(windows)]
             let s = s.replace("/", "\\");
-            Some(dir_path.join(s))
+            Some(dir_path.join(&*s))
         } else {
             None
         }
@@ -229,7 +213,7 @@ impl<'a> Parser<'a> {
         // `./<id>.rs` and `./<id>/mod.rs`.
         let relative_prefix_string;
         let relative_prefix = if let Some(ident) = relative {
-            relative_prefix_string = format!("{}{}", ident.as_str(), path::MAIN_SEPARATOR);
+            relative_prefix_string = format!("{}{}", ident, path::MAIN_SEPARATOR);
             &relative_prefix_string
         } else {
             ""
@@ -250,14 +234,12 @@ impl<'a> Parser<'a> {
                 directory_ownership: DirectoryOwnership::Owned {
                     relative: Some(id),
                 },
-                warn: false,
             }),
             (false, true) => Ok(ModulePathSuccess {
                 path: secondary_path,
                 directory_ownership: DirectoryOwnership::Owned {
                     relative: None,
                 },
-                warn: false,
             }),
             (false, false) => Err(Error::FileNotFoundForModule {
                 mod_name: mod_name.clone(),
@@ -314,7 +296,7 @@ impl<'a> Parser<'a> {
 
     fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
         if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
-            self.directory.path.to_mut().push(&path.as_str());
+            self.directory.path.to_mut().push(&*path.as_str());
             self.directory.ownership = DirectoryOwnership::Owned { relative: None };
         } else {
             // We have to push on the current module name in the case of relative
@@ -325,10 +307,10 @@ impl<'a> Parser<'a> {
             // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
             if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
                 if let Some(ident) = relative.take() { // remove the relative offset
-                    self.directory.path.to_mut().push(ident.as_str());
+                    self.directory.path.to_mut().push(&*ident.as_str());
                 }
             }
-            self.directory.path.to_mut().push(&id.as_str());
+            self.directory.path.to_mut().push(&*id.as_str());
         }
     }
 }
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs
index 969d5dd8374..b068a4f16a5 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/librustc_parse/parser/pat.rs
@@ -1,17 +1,15 @@
-use super::{Parser, PResult, PathStyle};
-
+use super::{Parser, PathStyle};
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
-use crate::ptr::P;
-use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
-use crate::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind};
-use crate::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor};
-use crate::parse::token::{self};
-use crate::print::pprust;
-use crate::source_map::{respan, Span, Spanned};
-use crate::symbol::kw;
-use crate::ThinVec;
-
-use errors::{Applicability, DiagnosticBuilder};
+use syntax::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
+use syntax::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind};
+use syntax::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor};
+use syntax::ptr::P;
+use syntax::print::pprust;
+use syntax::ThinVec;
+use syntax::token;
+use syntax::source_map::{respan, Span, Spanned};
+use syntax_pos::symbol::{kw, sym};
+use errors::{PResult, Applicability, DiagnosticBuilder};
 
 type Expected = Option<&'static str>;
 
@@ -52,11 +50,8 @@ impl<'a> Parser<'a> {
         // and no other gated or-pattern has been parsed thus far,
         // then we should really gate the leading `|`.
         // This complicated procedure is done purely for diagnostics UX.
-        if gated_leading_vert {
-            let mut or_pattern_spans = self.sess.gated_spans.or_patterns.borrow_mut();
-            if or_pattern_spans.is_empty() {
-                or_pattern_spans.push(leading_vert_span);
-            }
+        if gated_leading_vert && self.sess.gated_spans.is_ungated(sym::or_patterns) {
+            self.sess.gated_spans.gate(sym::or_patterns, leading_vert_span);
         }
 
         Ok(pat)
@@ -117,7 +112,7 @@ impl<'a> Parser<'a> {
 
         // Feature gate the or-pattern if instructed:
         if gate_or == GateOr::Yes {
-            self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
+            self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
         }
 
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
@@ -325,7 +320,7 @@ impl<'a> Parser<'a> {
             } else if self.eat_keyword(kw::Box) {
                 // Parse `box pat`
                 let pat = self.parse_pat_with_range_pat(false, None)?;
-                self.sess.gated_spans.box_patterns.borrow_mut().push(lo.to(self.prev_span));
+                self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_span));
                 PatKind::Box(pat)
             } else if self.can_be_ident_pat() {
                 // Parse `ident @ pat`
@@ -612,7 +607,7 @@ impl<'a> Parser<'a> {
     }
 
     fn excluded_range_end(&self, span: Span) -> RangeEnd {
-        self.sess.gated_spans.exclusive_range_pattern.borrow_mut().push(span);
+        self.sess.gated_spans.gate(sym::exclusive_range_pattern, span);
         RangeEnd::Excluded
     }
 
diff --git a/src/libsyntax/parse/parser/path.rs b/src/librustc_parse/parser/path.rs
index 38a28224dab..68307440712 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/librustc_parse/parser/path.rs
@@ -1,15 +1,15 @@
-use super::{Parser, PResult, TokenType};
-
-use crate::{maybe_whole, ThinVec};
-use crate::ast::{self, QSelf, Path, PathSegment, Ident, ParenthesizedArgs, AngleBracketedArgs};
-use crate::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
-use crate::parse::token::{self, Token};
-use crate::source_map::{Span, BytePos};
-use crate::symbol::kw;
+use super::{Parser, TokenType};
+use crate::maybe_whole;
+use syntax::ast::{self, QSelf, Path, PathSegment, Ident, ParenthesizedArgs, AngleBracketedArgs};
+use syntax::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
+use syntax::ThinVec;
+use syntax::token::{self, Token};
+use syntax::source_map::{Span, BytePos};
+use syntax_pos::symbol::{kw, sym};
 
 use std::mem;
 use log::debug;
-use errors::{Applicability, pluralise};
+use errors::{PResult, Applicability, pluralize};
 
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -368,14 +368,14 @@ impl<'a> Parser<'a> {
                         span,
                         &format!(
                             "unmatched angle bracket{}",
-                            pluralise!(snapshot.unmatched_angle_bracket_count)
+                            pluralize!(snapshot.unmatched_angle_bracket_count)
                         ),
                     )
                     .span_suggestion(
                         span,
                         &format!(
                             "remove extra angle bracket{}",
-                            pluralise!(snapshot.unmatched_angle_bracket_count)
+                            pluralize!(snapshot.unmatched_angle_bracket_count)
                         ),
                         String::new(),
                         Applicability::MachineApplicable,
@@ -426,7 +426,7 @@ impl<'a> Parser<'a> {
 
                 // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
                 if let AssocTyConstraintKind::Bound { .. } = kind {
-                    self.sess.gated_spans.associated_type_bounds.borrow_mut().push(span);
+                    self.sess.gated_spans.gate(sym::associated_type_bounds, span);
                 }
 
                 constraints.push(AssocTyConstraint {
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index 4f51fefe66f..a5f20691d07 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -1,20 +1,23 @@
-use super::{Parser, PResult, Restrictions, PrevTokenKind, SemiColonMode, BlockMode};
+use super::{Parser, Restrictions, PrevTokenKind, SemiColonMode, BlockMode};
 use super::expr::LhsExpr;
 use super::path::PathStyle;
 use super::pat::GateOr;
 use super::diagnostics::Error;
-
-use crate::ptr::P;
-use crate::{maybe_whole, ThinVec};
-use crate::ast::{self, DUMMY_NODE_ID, Stmt, StmtKind, Local, Block, BlockCheckMode, Expr, ExprKind};
-use crate::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac, MacDelimiter};
-use crate::parse::{classify, DirectoryOwnership};
-use crate::parse::token;
-use crate::source_map::{respan, Span};
-use crate::symbol::{kw, sym};
+use crate::maybe_whole;
+use crate::DirectoryOwnership;
+
+use syntax::ThinVec;
+use syntax::ptr::P;
+use syntax::ast;
+use syntax::ast::{DUMMY_NODE_ID, Stmt, StmtKind, Local, Block, BlockCheckMode, Expr, ExprKind};
+use syntax::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac, MacDelimiter};
+use syntax::util::classify;
+use syntax::token;
+use syntax::source_map::{respan, Span};
+use syntax::symbol::{kw, sym};
 
 use std::mem;
-use errors::Applicability;
+use errors::{PResult, Applicability};
 
 impl<'a> Parser<'a> {
     /// Parses a statement. This stops just before trailing semicolons on everything but items.
@@ -397,6 +400,7 @@ impl<'a> Parser<'a> {
             }
             let stmt = match self.parse_full_stmt(false) {
                 Err(mut err) => {
+                    self.maybe_annotate_with_ascription(&mut err, false);
                     err.emit();
                     self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
                     Some(Stmt {
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index e8f718a2483..fccabee2404 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -1,16 +1,18 @@
-use super::{Parser, PResult, PathStyle, PrevTokenKind, TokenType};
+use super::{Parser, PathStyle, PrevTokenKind, TokenType};
 use super::item::ParamCfg;
 
 use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath};
-use crate::ptr::P;
-use crate::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam, Lifetime, Ident};
-use crate::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef};
-use crate::ast::{Mutability, AnonConst, Mac};
-use crate::parse::token::{self, Token};
-use crate::source_map::Span;
-use crate::symbol::{kw};
 
-use errors::{Applicability, pluralise};
+use syntax::ptr::P;
+use syntax::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam, Lifetime, Ident};
+use syntax::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef};
+use syntax::ast::{Mutability, AnonConst, Mac};
+use syntax::token::{self, Token};
+use syntax::source_map::Span;
+use syntax::struct_span_fatal;
+use syntax_pos::symbol::kw;
+
+use errors::{PResult, Applicability, pluralize};
 
 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
 /// `IDENT<<u8 as Trait>::AssocTy>`.
@@ -412,7 +414,7 @@ impl<'a> Parser<'a> {
                 }
                 err.span_suggestion_hidden(
                     bound_list,
-                    &format!("remove the trait bound{}", pluralise!(negative_bounds_len)),
+                    &format!("remove the trait bound{}", pluralize!(negative_bounds_len)),
                     new_bound_list,
                     Applicability::MachineApplicable,
                 );
diff --git a/src/librustc_parse/validate_attr.rs b/src/librustc_parse/validate_attr.rs
new file mode 100644
index 00000000000..bbe0dc1c35f
--- /dev/null
+++ b/src/librustc_parse/validate_attr.rs
@@ -0,0 +1,111 @@
+//! Meta-syntax validation logic of attributes for post-expansion.
+
+use errors::{PResult, Applicability};
+use syntax::ast::{self, Attribute, AttrKind, Ident, MetaItem};
+use syntax::attr::{AttributeTemplate, mk_name_value_item_str};
+use syntax::early_buffered_lints::BufferedEarlyLintId;
+use syntax::feature_gate::BUILTIN_ATTRIBUTE_MAP;
+use syntax::token;
+use syntax::tokenstream::TokenTree;
+use syntax::sess::ParseSess;
+use syntax_pos::{Symbol, sym};
+
+pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
+    let attr_info =
+        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
+
+    // Check input tokens for built-in and key-value attributes.
+    match attr_info {
+        // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
+        Some((name, _, template, _)) if name != sym::rustc_dummy =>
+            check_builtin_attribute(sess, attr, name, template),
+        _ => if let Some(TokenTree::Token(token)) = attr.get_normal_item().tokens.trees().next() {
+            if token == token::Eq {
+                // All key-value attributes are restricted to meta-item syntax.
+                parse_meta(sess, attr).map_err(|mut err| err.emit()).ok();
+            }
+        }
+    }
+}
+
+pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, MetaItem> {
+    Ok(match attr.kind {
+        AttrKind::Normal(ref item) => MetaItem {
+            path: item.path.clone(),
+            kind: super::parse_in_attr(sess, attr, |p| p.parse_meta_item_kind())?,
+            span: attr.span,
+        },
+        AttrKind::DocComment(comment) => {
+            mk_name_value_item_str(Ident::new(sym::doc, attr.span), comment, attr.span)
+        }
+    })
+}
+
+pub fn check_builtin_attribute(
+    sess: &ParseSess,
+    attr: &Attribute,
+    name: Symbol,
+    template: AttributeTemplate,
+) {
+    // Some special attributes like `cfg` must be checked
+    // before the generic check, so we skip them here.
+    let should_skip = |name| name == sym::cfg;
+    // Some of previously accepted forms were used in practice,
+    // report them as warnings for now.
+    let should_warn = |name| name == sym::doc || name == sym::ignore ||
+                             name == sym::inline || name == sym::link ||
+                             name == sym::test || name == sym::bench;
+
+    match parse_meta(sess, attr) {
+        Ok(meta) => if !should_skip(name) && !template.compatible(&meta.kind) {
+            let error_msg = format!("malformed `{}` attribute input", name);
+            let mut msg = "attribute must be of the form ".to_owned();
+            let mut suggestions = vec![];
+            let mut first = true;
+            if template.word {
+                first = false;
+                let code = format!("#[{}]", name);
+                msg.push_str(&format!("`{}`", &code));
+                suggestions.push(code);
+            }
+            if let Some(descr) = template.list {
+                if !first {
+                    msg.push_str(" or ");
+                }
+                first = false;
+                let code = format!("#[{}({})]", name, descr);
+                msg.push_str(&format!("`{}`", &code));
+                suggestions.push(code);
+            }
+            if let Some(descr) = template.name_value_str {
+                if !first {
+                    msg.push_str(" or ");
+                }
+                let code = format!("#[{} = \"{}\"]", name, descr);
+                msg.push_str(&format!("`{}`", &code));
+                suggestions.push(code);
+            }
+            if should_warn(name) {
+                sess.buffer_lint(
+                    BufferedEarlyLintId::IllFormedAttributeInput,
+                    meta.span,
+                    ast::CRATE_NODE_ID,
+                    &msg,
+                );
+            } else {
+                sess.span_diagnostic.struct_span_err(meta.span, &error_msg)
+                    .span_suggestions(
+                        meta.span,
+                        if suggestions.len() == 1 {
+                            "must be of the form"
+                        } else {
+                            "the following are the possible correct uses"
+                        },
+                        suggestions.into_iter(),
+                        Applicability::HasPlaceholders,
+                    ).emit();
+            }
+        }
+        Err(mut err) => err.emit(),
+    }
+}
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index 9d29a230314..556189208f1 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -12,8 +12,9 @@ path = "lib.rs"
 log = "0.4"
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_index = { path = "../librustc_index" }
+rustc_parse = { path = "../librustc_parse" }
+rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
-rustc_target = { path = "../librustc_target" }
-rustc_index = { path = "../librustc_index" }
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index e625334040e..ec5572914d8 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -7,15 +7,15 @@
 // or type checking or some other kind of complex analysis.
 
 use std::mem;
-use syntax::print::pprust;
 use rustc::lint;
-use rustc::lint::builtin::{BuiltinLintDiagnostics, NESTED_IMPL_TRAIT};
 use rustc::session::Session;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_parse::validate_attr;
 use syntax::ast::*;
 use syntax::attr;
 use syntax::expand::is_proc_macro_attr;
 use syntax::feature_gate::is_builtin_attr;
+use syntax::print::pprust;
 use syntax::source_map::Spanned;
 use syntax::symbol::{kw, sym};
 use syntax::visit::{self, Visitor};
@@ -23,31 +23,6 @@ use syntax::{span_err, struct_span_err, walk_list};
 use syntax_pos::{Span, MultiSpan};
 use errors::{Applicability, FatalError};
 
-#[derive(Copy, Clone, Debug)]
-struct OuterImplTrait {
-    span: Span,
-
-    /// rust-lang/rust#57979: a bug in original implementation caused
-    /// us to fail sometimes to record an outer `impl Trait`.
-    /// Therefore, in order to reliably issue a warning (rather than
-    /// an error) in the *precise* places where we are newly injecting
-    /// the diagnostic, we have to distinguish between the places
-    /// where the outer `impl Trait` has always been recorded, versus
-    /// the places where it has only recently started being recorded.
-    only_recorded_since_pull_request_57730: bool,
-}
-
-impl OuterImplTrait {
-    /// This controls whether we should downgrade the nested impl
-    /// trait diagnostic to a warning rather than an error, based on
-    /// whether the outer impl trait had been improperly skipped in
-    /// earlier implementations of the analysis on the stable
-    /// compiler.
-    fn should_warn_instead_of_error(&self) -> bool {
-        self.only_recorded_since_pull_request_57730
-    }
-}
-
 struct AstValidator<'a> {
     session: &'a Session,
     has_proc_macro_decls: bool,
@@ -55,7 +30,7 @@ struct AstValidator<'a> {
     /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
     /// Nested `impl Trait` _is_ allowed in associated type position,
     /// e.g., `impl Iterator<Item = impl Debug>`.
-    outer_impl_trait: Option<OuterImplTrait>,
+    outer_impl_trait: Option<Span>,
 
     /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
     /// or `Foo::Bar<impl Trait>`
@@ -65,26 +40,10 @@ struct AstValidator<'a> {
     /// certain positions.
     is_assoc_ty_bound_banned: bool,
 
-    /// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
-    /// until PRs #57730 and #57981 landed: it would jump directly to
-    /// walk_ty rather than visit_ty (or skip recurring entirely for
-    /// impl trait in projections), and thus miss some cases. We track
-    /// whether we should downgrade to a warning for short-term via
-    /// these booleans.
-    warning_period_57979_didnt_record_next_impl_trait: bool,
-    warning_period_57979_impl_trait_in_proj: bool,
-
     lint_buffer: &'a mut lint::LintBuffer,
 }
 
 impl<'a> AstValidator<'a> {
-    fn with_impl_trait_in_proj_warning<T>(&mut self, v: bool, f: impl FnOnce(&mut Self) -> T) -> T {
-        let old = mem::replace(&mut self.warning_period_57979_impl_trait_in_proj, v);
-        let ret = f(self);
-        self.warning_period_57979_impl_trait_in_proj = old;
-        ret
-    }
-
     fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
         let old = mem::replace(&mut self.is_impl_trait_banned, true);
         f(self);
@@ -97,7 +56,7 @@ impl<'a> AstValidator<'a> {
         self.is_assoc_ty_bound_banned = old;
     }
 
-    fn with_impl_trait(&mut self, outer: Option<OuterImplTrait>, f: impl FnOnce(&mut Self)) {
+    fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
         let old = mem::replace(&mut self.outer_impl_trait, outer);
         f(self);
         self.outer_impl_trait = old;
@@ -105,14 +64,7 @@ impl<'a> AstValidator<'a> {
 
     fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) {
         match constraint.kind {
-            AssocTyConstraintKind::Equality { ref ty } => {
-                // rust-lang/rust#57979: bug in old `visit_generic_args` called
-                // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait`
-                // if it happened to occur at `ty`.
-                if let TyKind::ImplTrait(..) = ty.kind {
-                    self.warning_period_57979_didnt_record_next_impl_trait = true;
-                }
-            }
+            AssocTyConstraintKind::Equality { .. } => {}
             AssocTyConstraintKind::Bound { .. } => {
                 if self.is_assoc_ty_bound_banned {
                     self.err_handler().span_err(constraint.span,
@@ -124,37 +76,11 @@ impl<'a> AstValidator<'a> {
         self.visit_assoc_ty_constraint(constraint);
     }
 
-    fn visit_ty_from_generic_args(&mut self, ty: &'a Ty) {
-        // rust-lang/rust#57979: bug in old `visit_generic_args` called
-        // `walk_ty` rather than `visit_ty`, skippping outer `impl Trait`
-        // if it happened to occur at `ty`.
-        if let TyKind::ImplTrait(..) = ty.kind {
-            self.warning_period_57979_didnt_record_next_impl_trait = true;
-        }
-        self.visit_ty(ty);
-    }
-
-    fn outer_impl_trait(&mut self, span: Span) -> OuterImplTrait {
-        let only_recorded_since_pull_request_57730 =
-            self.warning_period_57979_didnt_record_next_impl_trait;
-
-        // (This flag is designed to be set to `true`, and then only
-        // reach the construction point for the outer impl trait once,
-        // so its safe and easiest to unconditionally reset it to
-        // false.)
-        self.warning_period_57979_didnt_record_next_impl_trait = false;
-
-        OuterImplTrait {
-            span, only_recorded_since_pull_request_57730,
-        }
-    }
-
     // Mirrors `visit::walk_ty`, but tracks relevant state.
     fn walk_ty(&mut self, t: &'a Ty) {
         match t.kind {
             TyKind::ImplTrait(..) => {
-                let outer_impl_trait = self.outer_impl_trait(t.span);
-                self.with_impl_trait(Some(outer_impl_trait), |this| visit::walk_ty(this, t))
+                self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
             }
             TyKind::Path(ref qself, ref path) => {
                 // We allow these:
@@ -328,7 +254,7 @@ impl<'a> AstValidator<'a> {
                 let arr = [sym::allow, sym::cfg, sym::cfg_attr, sym::deny, sym::forbid, sym::warn];
                 !arr.contains(&attr.name_or_empty()) && is_builtin_attr(attr)
             })
-            .for_each(|attr| if attr.is_sugared_doc {
+            .for_each(|attr| if attr.is_doc_comment() {
                 let mut err = self.err_handler().struct_span_err(
                     attr.span,
                     "documentation comments cannot be applied to function parameters"
@@ -444,6 +370,10 @@ fn validate_generics_order<'a>(
 }
 
 impl<'a> Visitor<'a> for AstValidator<'a> {
+    fn visit_attribute(&mut self, attr: &Attribute) {
+        validate_attr::check_meta(&self.session.parse_sess, attr);
+    }
+
     fn visit_expr(&mut self, expr: &'a Expr) {
         match &expr.kind {
             ExprKind::Closure(_, _, _, fn_decl, _, _) => {
@@ -484,32 +414,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             }
             TyKind::ImplTrait(_, ref bounds) => {
                 if self.is_impl_trait_banned {
-                    if self.warning_period_57979_impl_trait_in_proj {
-                        self.lint_buffer.buffer_lint(
-                            NESTED_IMPL_TRAIT, ty.id, ty.span,
-                            "`impl Trait` is not allowed in path parameters");
-                    } else {
-                        struct_span_err!(self.session, ty.span, E0667,
-                            "`impl Trait` is not allowed in path parameters").emit();
-                    }
+                    struct_span_err!(
+                        self.session, ty.span, E0667,
+                        "`impl Trait` is not allowed in path parameters"
+                    )
+                    .emit();
                 }
 
-                if let Some(outer_impl_trait) = self.outer_impl_trait {
-                    if outer_impl_trait.should_warn_instead_of_error() {
-                        self.lint_buffer.buffer_lint_with_diagnostic(
-                            NESTED_IMPL_TRAIT, ty.id, ty.span,
-                            "nested `impl Trait` is not allowed",
-                            BuiltinLintDiagnostics::NestedImplTrait {
-                                outer_impl_trait_span: outer_impl_trait.span,
-                                inner_impl_trait_span: ty.span,
-                            });
-                    } else {
-                        struct_span_err!(self.session, ty.span, E0666,
-                            "nested `impl Trait` is not allowed")
-                            .span_label(outer_impl_trait.span, "outer `impl Trait`")
-                            .span_label(ty.span, "nested `impl Trait` here")
-                            .emit();
-                    }
+                if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
+                    struct_span_err!(
+                        self.session, ty.span, E0666,
+                        "nested `impl Trait` is not allowed"
+                    )
+                    .span_label(outer_impl_trait_sp, "outer `impl Trait`")
+                    .span_label(ty.span, "nested `impl Trait` here")
+                    .emit();
                 }
 
                 if !bounds.iter()
@@ -517,7 +436,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     self.err_handler().span_err(ty.span, "at least one trait must be specified");
                 }
 
-                self.with_impl_trait_in_proj_warning(true, |this| this.walk_ty(ty));
+                self.walk_ty(ty);
                 return;
             }
             _ => {}
@@ -575,12 +494,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         .note("only trait implementations may be annotated with default").emit();
                 }
             }
-            ItemKind::Fn(ref decl, ref header, ref generics, _) => {
-                self.visit_fn_header(header);
-                self.check_fn_decl(decl);
+            ItemKind::Fn(ref sig, ref generics, _) => {
+                self.visit_fn_header(&sig.header);
+                self.check_fn_decl(&sig.decl);
                 // We currently do not permit const generics in `const fn`, as
                 // this is tantamount to allowing compile-time dependent typing.
-                if header.constness.node == Constness::Const {
+                if sig.header.constness.node == Constness::Const {
                     // Look for const generics and error if we find any.
                     for param in &generics.params {
                         match param.kind {
@@ -654,11 +573,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             ItemKind::Mod(_) => {
                 // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
                 attr::first_attr_value_str_by_name(&item.attrs, sym::path);
-                if attr::contains_name(&item.attrs, sym::warn_directory_ownership) {
-                    let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
-                    let msg = "cannot declare a new module at this location";
-                    self.lint_buffer.buffer_lint(lint, item.id, item.span, msg);
-                }
             }
             ItemKind::Union(ref vdata, _) => {
                 if let VariantData::Tuple(..) | VariantData::Unit(..) = vdata {
@@ -731,7 +645,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 if let Some(ref type_) = data.output {
                     // `-> Foo` syntax is essentially an associated type binding,
                     // so it is also allowed to contain nested `impl Trait`.
-                    self.with_impl_trait(None, |this| this.visit_ty_from_generic_args(type_));
+                    self.with_impl_trait(None, |this| this.visit_ty(type_));
                 }
             }
         }
@@ -849,8 +763,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe
         outer_impl_trait: None,
         is_impl_trait_banned: false,
         is_assoc_ty_bound_banned: false,
-        warning_period_57979_didnt_record_next_impl_trait: false,
-        warning_period_57979_impl_trait_in_proj: false,
         lint_buffer: lints,
     };
     visit::walk_crate(&mut validator, krate);
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index f2aef2c12c7..2aeec029cc3 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -569,8 +569,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         if self.should_warn_about_item(item) {
-            // For items that have a definition with a signature followed by a
-            // block, point only at the signature.
+            // For most items, we want to highlight its identifier
             let span = match item.kind {
                 hir::ItemKind::Fn(..) |
                 hir::ItemKind::Mod(..) |
@@ -578,7 +577,19 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
                 hir::ItemKind::Struct(..) |
                 hir::ItemKind::Union(..) |
                 hir::ItemKind::Trait(..) |
-                hir::ItemKind::Impl(..) => self.tcx.sess.source_map().def_span(item.span),
+                hir::ItemKind::Impl(..) => {
+                    // FIXME(66095): Because item.span is annotated with things
+                    // like expansion data, and ident.span isn't, we use the
+                    // def_span method if it's part of a macro invocation
+                    // (and thus has asource_callee set).
+                    // We should probably annotate ident.span with the macro
+                    // context, but that's a larger change.
+                    if item.span.source_callee().is_some() {
+                        self.tcx.sess.source_map().def_span(item.span)
+                    } else {
+                        item.ident.span
+                    }
+                },
                 _ => item.span,
             };
             let participle = match item.kind {
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 6c9e018fafc..60525ba6b39 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -7,7 +7,7 @@ use rustc::ty::TyCtxt;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::Map;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use rustc::hir::{self, Node, Destination, GeneratorMovability};
+use rustc::hir::{self, Node, Destination, Movability};
 use syntax::struct_span_err;
 use syntax_pos::Span;
 use errors::Applicability;
@@ -59,7 +59,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
                 self.with_context(Loop(source), |v| v.visit_block(&b));
             }
             hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => {
-                let cx = if let Some(GeneratorMovability::Static) = movability {
+                let cx = if let Some(Movability::Static) = movability {
                     AsyncClosure(span)
                 } else {
                     Closure(span)
diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs
index 2e23b8c870c..3f4b87a97c7 100644
--- a/src/librustc_plugin/registry.rs
+++ b/src/librustc_plugin/registry.rs
@@ -101,7 +101,6 @@ impl<'a> Registry<'a> {
 
     /// Register an attribute with an attribute type.
     ///
-    /// Registered attributes will bypass the `custom_attribute` feature gate.
     /// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
     /// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
     pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml
index 08ce7fd520e..33b2bd36b7d 100644
--- a/src/librustc_resolve/Cargo.toml
+++ b/src/librustc_resolve/Cargo.toml
@@ -21,4 +21,4 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_metadata = { path = "../librustc_metadata" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 648c5104b1a..0fcac5aab62 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -33,7 +33,7 @@ use syntax::attr;
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
 use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind};
 use syntax::feature_gate::is_builtin_attr;
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::print::pprust;
 use syntax::{span_err, struct_span_err};
 use syntax::source_map::{respan, Spanned};
@@ -141,8 +141,7 @@ impl<'a> Resolver<'a> {
     crate fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
         match res {
             Res::Def(DefKind::Macro(..), def_id) => self.get_macro_by_def_id(def_id),
-            Res::NonMacroAttr(attr_kind) =>
-                Some(self.non_macro_attr(attr_kind == NonMacroAttrKind::Tool)),
+            Res::NonMacroAttr(attr_kind) => Some(self.non_macro_attr(attr_kind.is_used())),
             _ => None,
         }
     }
@@ -449,7 +448,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                                     name: kw::PathRoot,
                                     span: source.ident.span,
                                 },
-                                id: Some(self.r.session.next_node_id()),
+                                id: Some(self.r.next_node_id()),
                             });
                             source.ident.name = crate_name;
                         }
@@ -1229,8 +1228,10 @@ 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.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope));
+        if !attr.is_doc_comment() && is_builtin_attr(attr) {
+            self.r.builtin_attrs.push(
+                (attr.get_normal_item().path.segments[0].ident, self.parent_scope)
+            );
         }
         visit::walk_attribute(self, attr);
     }
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 44b7a9fa047..0624b5eedfb 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -26,7 +26,7 @@
 use crate::Resolver;
 use crate::resolve_imports::ImportDirectiveSubclass;
 
-use errors::pluralise;
+use errors::pluralize;
 
 use rustc::util::nodemap::NodeMap;
 use rustc::{lint, ty};
@@ -297,7 +297,7 @@ impl Resolver<'_> {
                 }).collect::<Vec<String>>();
             span_snippets.sort();
             let msg = format!("unused import{}{}",
-                            pluralise!(len),
+                            pluralize!(len),
                             if !span_snippets.is_empty() {
                                 format!(": {}", span_snippets.join(", "))
                             } else {
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 3d68b72a655..771519b86c1 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -19,7 +19,7 @@ use syntax_pos::hygiene::MacroKind;
 use syntax_pos::{BytePos, Span, MultiSpan};
 
 use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver};
-use crate::{path_names_to_string, KNOWN_TOOLS};
+use crate::path_names_to_string;
 use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot};
 use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment};
 
@@ -400,6 +400,14 @@ impl<'a> Resolver<'a> {
                 Scope::Module(module) => {
                     this.add_module_candidates(module, &mut suggestions, filter_fn);
                 }
+                Scope::RegisteredAttrs => {
+                    let res = Res::NonMacroAttr(NonMacroAttrKind::Registered);
+                    if filter_fn(res) {
+                        suggestions.extend(this.registered_attrs.iter().map(|ident| {
+                            TypoSuggestion::from_res(ident.name, res)
+                        }));
+                    }
+                }
                 Scope::MacroUsePrelude => {
                     suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| {
                         let res = binding.res();
@@ -439,8 +447,8 @@ impl<'a> Resolver<'a> {
                 }
                 Scope::ToolPrelude => {
                     let res = Res::NonMacroAttr(NonMacroAttrKind::Tool);
-                    suggestions.extend(KNOWN_TOOLS.iter().map(|name| {
-                        TypoSuggestion::from_res(*name, res)
+                    suggestions.extend(this.registered_tools.iter().map(|ident| {
+                        TypoSuggestion::from_res(ident.name, res)
                     }));
                 }
                 Scope::StdLibPrelude => {
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 004d86cee8d..3340566a875 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -731,7 +731,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         match item.kind {
             ItemKind::TyAlias(_, ref generics) |
             ItemKind::OpaqueTy(_, ref generics) |
-            ItemKind::Fn(_, _, ref generics, _) => {
+            ItemKind::Fn(_, ref generics, _) => {
                 self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes),
                                             |this| visit::walk_item(this, item));
             }
@@ -1539,25 +1539,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 if is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err {
                     partial_res
                 } else {
-                    // Add a temporary hack to smooth the transition to new struct ctor
-                    // visibility rules. See #38932 for more details.
-                    let mut res = None;
-                    if let Res::Def(DefKind::Struct, def_id) = partial_res.base_res() {
-                        if let Some((ctor_res, ctor_vis))
-                                = self.r.struct_constructors.get(&def_id).cloned() {
-                            if is_expected(ctor_res) &&
-                               self.r.is_accessible_from(ctor_vis, self.parent_scope.module) {
-                                let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
-                                self.r.lint_buffer.buffer_lint(lint, id, span,
-                                    "private struct constructors are not usable through \
-                                     re-exports in outer modules",
-                                );
-                                res = Some(PartialRes::new(ctor_res));
-                            }
-                        }
-                    }
-
-                    res.unwrap_or_else(|| report_errors(self, Some(partial_res.base_res())))
+                    report_errors(self, Some(partial_res.base_res()))
                 }
             }
             Some(partial_res) if source.defer_to_typeck() => {
@@ -1876,7 +1858,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                     None
                                 }
                             });
-                            find_best_match_for_name(names, &*ident.as_str(), None)
+                            find_best_match_for_name(names, &ident.as_str(), None)
                         });
                         self.r.record_partial_res(expr.id, PartialRes::new(Res::Err));
                         self.r.report_error(
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index b45eb356bdb..88c675a6ce5 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -36,7 +36,6 @@ use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::CStore;
 
 use syntax::{struct_span_err, unwrap_or};
-use syntax::expand::SpecialDerives;
 use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
 use syntax::ast::{CRATE_NODE_ID, Crate};
 use syntax::ast::{ItemKind, Path};
@@ -75,8 +74,6 @@ mod check_unused;
 mod build_reduced_graph;
 mod resolve_imports;
 
-const KNOWN_TOOLS: &[Name] = &[sym::clippy, sym::rustfmt];
-
 enum Weak {
     Yes,
     No,
@@ -103,6 +100,7 @@ enum Scope<'a> {
     MacroRules(LegacyScope<'a>),
     CrateRoot,
     Module(Module<'a>),
+    RegisteredAttrs,
     MacroUsePrelude,
     BuiltinAttrs,
     LegacyPluginHelpers,
@@ -622,7 +620,6 @@ enum AmbiguityKind {
     Import,
     BuiltinAttr,
     DeriveHelper,
-    LegacyHelperVsPrelude,
     LegacyVsModern,
     GlobVsOuter,
     GlobVsGlob,
@@ -639,8 +636,6 @@ impl AmbiguityKind {
                 "built-in attribute vs any other name",
             AmbiguityKind::DeriveHelper =>
                 "derive helper attribute vs any other name",
-            AmbiguityKind::LegacyHelperVsPrelude =>
-                "legacy plugin helper attribute vs name from prelude",
             AmbiguityKind::LegacyVsModern =>
                 "`macro_rules` vs non-`macro_rules` from other module",
             AmbiguityKind::GlobVsOuter =>
@@ -917,6 +912,8 @@ pub struct Resolver<'a> {
     crate_loader: CrateLoader<'a>,
     macro_names: FxHashSet<Ident>,
     builtin_macros: FxHashMap<Name, SyntaxExtension>,
+    registered_attrs: FxHashSet<Ident>,
+    registered_tools: FxHashSet<Ident>,
     macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
     all_macros: FxHashMap<Name, Res>,
     macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
@@ -934,12 +931,10 @@ pub struct Resolver<'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(Copy)` marks 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>,
+    containers_deriving_copy: FxHashSet<ExpnId>,
     /// 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>>,
@@ -964,6 +959,8 @@ pub struct Resolver<'a> {
     variant_vis: DefIdMap<ty::Visibility>,
 
     lint_buffer: lint::LintBuffer,
+
+    next_node_id: NodeId,
 }
 
 /// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1078,15 +1075,13 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
         &mut self.definitions
     }
 
-    fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool {
-        let def_id = self.definitions.local_def_id(node_id);
-        let expn_id = self.definitions.expansion_that_defined(def_id.index);
-        self.has_derives(expn_id, derives)
-    }
-
     fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
         &mut self.lint_buffer
     }
+
+    fn next_node_id(&mut self) -> NodeId {
+        self.next_node_id()
+    }
 }
 
 impl<'a> Resolver<'a> {
@@ -1141,6 +1136,9 @@ impl<'a> Resolver<'a> {
             }
         }
 
+        let (registered_attrs, registered_tools) =
+            macros::registered_attrs_and_tools(session, &krate.attrs);
+
         let mut invocation_parent_scopes = FxHashMap::default();
         invocation_parent_scopes.insert(ExpnId::root(), ParentScope::module(graph_root));
 
@@ -1210,6 +1208,8 @@ impl<'a> Resolver<'a> {
             crate_loader: CrateLoader::new(session, metadata_loader, crate_name),
             macro_names: FxHashSet::default(),
             builtin_macros: Default::default(),
+            registered_attrs,
+            registered_tools,
             macro_use_prelude: FxHashMap::default(),
             all_macros: FxHashMap::default(),
             macro_map: FxHashMap::default(),
@@ -1228,16 +1228,25 @@ impl<'a> Resolver<'a> {
             single_segment_macro_resolutions: Default::default(),
             multi_segment_macro_resolutions: Default::default(),
             builtin_attrs: Default::default(),
-            special_derives: Default::default(),
+            containers_deriving_copy: Default::default(),
             active_features:
                 features.declared_lib_features.iter().map(|(feat, ..)| *feat)
                     .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
                     .collect(),
             variant_vis: Default::default(),
             lint_buffer: lint::LintBuffer::default(),
+            next_node_id: NodeId::from_u32(1),
         }
     }
 
+    pub fn next_node_id(&mut self) -> NodeId {
+        let next = self.next_node_id.as_usize()
+            .checked_add(1)
+            .expect("input too large; ran out of NodeIds");
+        self.next_node_id = ast::NodeId::from_usize(next);
+        self.next_node_id
+    }
+
     pub fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
         &mut self.lint_buffer
     }
@@ -1314,10 +1323,6 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn has_derives(&self, expn_id: ExpnId, markers: SpecialDerives) -> bool {
-        self.special_derives.get(&expn_id).map_or(false, |m| m.contains(markers))
-    }
-
     /// Entry point to crate resolution.
     pub fn resolve_crate(&mut self, krate: &Crate) {
         let _prof_timer =
@@ -1482,6 +1487,7 @@ impl<'a> Resolver<'a> {
                 Scope::MacroRules(..) => true,
                 Scope::CrateRoot => true,
                 Scope::Module(..) => true,
+                Scope::RegisteredAttrs => use_prelude,
                 Scope::MacroUsePrelude => use_prelude || rust_2015,
                 Scope::BuiltinAttrs => true,
                 Scope::LegacyPluginHelpers => use_prelude || rust_2015,
@@ -1526,11 +1532,12 @@ impl<'a> Resolver<'a> {
                             match ns {
                                 TypeNS => Scope::ExternPrelude,
                                 ValueNS => Scope::StdLibPrelude,
-                                MacroNS => Scope::MacroUsePrelude,
+                                MacroNS => Scope::RegisteredAttrs,
                             }
                         }
                     }
                 }
+                Scope::RegisteredAttrs => Scope::MacroUsePrelude,
                 Scope::MacroUsePrelude => Scope::StdLibPrelude,
                 Scope::BuiltinAttrs => Scope::LegacyPluginHelpers,
                 Scope::LegacyPluginHelpers => break, // nowhere else to search
@@ -1686,11 +1693,11 @@ impl<'a> Resolver<'a> {
                 if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
                     return Some(LexicalScopeBinding::Item(binding));
                 }
-            }
-            if ns == TypeNS && KNOWN_TOOLS.contains(&ident.name) {
-                let binding = (Res::ToolMod, ty::Visibility::Public,
-                               DUMMY_SP, ExpnId::root()).to_name_binding(self.arenas);
-                return Some(LexicalScopeBinding::Item(binding));
+                if let Some(ident) = self.registered_tools.get(&ident) {
+                    let binding = (Res::ToolMod, ty::Visibility::Public,
+                                   ident.span, ExpnId::root()).to_name_binding(self.arenas);
+                    return Some(LexicalScopeBinding::Item(binding));
+                }
             }
             if let Some(prelude) = self.prelude {
                 if let Ok(binding) = self.resolve_ident_in_module_unadjusted(
@@ -2840,9 +2847,9 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn new_ast_path_segment(&self, ident: Ident) -> ast::PathSegment {
+    fn new_ast_path_segment(&mut self, ident: Ident) -> ast::PathSegment {
         let mut seg = ast::PathSegment::from_ident(ident);
-        seg.id = self.session.next_node_id();
+        seg.id = self.next_node_id();
         seg
     }
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 84d3d3a48b0..2d125a459c8 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -3,18 +3,18 @@
 
 use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy};
 use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak};
-use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding};
-use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
+use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
 use crate::Namespace::*;
 use crate::resolve_imports::ImportResolver;
 use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
 use rustc::hir::def_id;
 use rustc::middle::stability;
+use rustc::session::Session;
+use rustc::util::nodemap::FxHashSet;
 use rustc::{ty, lint, span_bug};
 use syntax::ast::{self, NodeId, Ident};
-use syntax::attr::StabilityLevel;
+use syntax::attr::{self, StabilityLevel};
 use syntax::edition::Edition;
-use syntax::expand::SpecialDerives;
 use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
 use syntax::feature_gate::GateIssue;
 use syntax::print::pprust;
@@ -94,9 +94,49 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
     }
 }
 
+/// The code common between processing `#![register_tool]` and `#![register_attr]`.
+fn registered_idents(
+    sess: &Session,
+    attrs: &[ast::Attribute],
+    attr_name: Symbol,
+    descr: &str,
+) -> FxHashSet<Ident> {
+    let mut registered = FxHashSet::default();
+    for attr in attr::filter_by_name(attrs, attr_name) {
+        for nested_meta in attr.meta_item_list().unwrap_or_default() {
+            match nested_meta.ident() {
+                Some(ident) => if let Some(old_ident) = registered.replace(ident) {
+                    let msg = format!("{} `{}` was already registered", descr, ident);
+                    sess.struct_span_err(ident.span, &msg)
+                        .span_label(old_ident.span, "already registered here").emit();
+                }
+                None => {
+                    let msg = format!("`{}` only accepts identifiers", attr_name);
+                    let span = nested_meta.span();
+                    sess.struct_span_err(span, &msg).span_label(span, "not an identifier").emit();
+                }
+            }
+        }
+    }
+    registered
+}
+
+crate fn registered_attrs_and_tools(
+    sess: &Session,
+    attrs: &[ast::Attribute],
+) -> (FxHashSet<Ident>, FxHashSet<Ident>) {
+    let registered_attrs = registered_idents(sess, attrs, sym::register_attr, "attribute");
+    let mut registered_tools = registered_idents(sess, attrs, sym::register_tool, "tool");
+    // We implicitly add `rustfmt` and `clippy` to known tools,
+    // but it's not an error to register them explicitly.
+    let predefined_tools = [sym::clippy, sym::rustfmt];
+    registered_tools.extend(predefined_tools.iter().cloned().map(Ident::with_dummy_span));
+    (registered_attrs, registered_tools)
+}
+
 impl<'a> base::Resolver for Resolver<'a> {
     fn next_node_id(&mut self) -> NodeId {
-        self.session.next_node_id()
+        self.next_node_id()
     }
 
     fn resolve_dollar_crates(&mut self) {
@@ -180,7 +220,10 @@ impl<'a> base::Resolver for Resolver<'a> {
 
         let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
-                (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive),
+                (&attr.get_normal_item().path,
+                 MacroKind::Attr,
+                 self.arenas.alloc_ast_paths(derives),
+                 after_derive),
             InvocationKind::Bang { ref mac, .. } =>
                 (&mac.path, MacroKind::Bang, &[][..], false),
             InvocationKind::Derive { ref path, .. } =>
@@ -255,12 +298,12 @@ impl<'a> base::Resolver for Resolver<'a> {
         }
     }
 
-    fn has_derives(&self, expn_id: ExpnId, derives: SpecialDerives) -> bool {
-        self.has_derives(expn_id, derives)
+    fn has_derive_copy(&self, expn_id: ExpnId) -> bool {
+        self.containers_deriving_copy.contains(&expn_id)
     }
 
-    fn add_derives(&mut self, expn_id: ExpnId, derives: SpecialDerives) {
-        *self.special_derives.entry(expn_id).or_default() |= derives;
+    fn add_derive_copy(&mut self, expn_id: ExpnId) {
+        self.containers_deriving_copy.insert(expn_id);
     }
 }
 
@@ -414,10 +457,9 @@ impl<'a> Resolver<'a> {
             struct Flags: u8 {
                 const MACRO_RULES        = 1 << 0;
                 const MODULE             = 1 << 1;
-                const PRELUDE            = 1 << 2;
-                const MISC_SUGGEST_CRATE = 1 << 3;
-                const MISC_SUGGEST_SELF  = 1 << 4;
-                const MISC_FROM_PRELUDE  = 1 << 5;
+                const MISC_SUGGEST_CRATE = 1 << 2;
+                const MISC_SUGGEST_SELF  = 1 << 3;
+                const MISC_FROM_PRELUDE  = 1 << 4;
             }
         }
 
@@ -451,6 +493,10 @@ impl<'a> Resolver<'a> {
         // Go through all the scopes and try to resolve the name.
         let break_result = self.visit_scopes(scope_set, parent_scope, orig_ident,
                                              |this, scope, use_prelude, ident| {
+            let ok = |res, span, arenas| Ok((
+                (res, ty::Visibility::Public, span, ExpnId::root()).to_name_binding(arenas),
+                Flags::empty(),
+            ));
             let result = match scope {
                 Scope::DeriveHelpers => {
                     let mut result = Err(Determinacy::Determined);
@@ -459,10 +505,8 @@ impl<'a> Resolver<'a> {
                         match this.resolve_macro_path(derive, Some(MacroKind::Derive),
                                                       parent_scope, true, force) {
                             Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) {
-                                let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
-                                               ty::Visibility::Public, derive.span, ExpnId::root())
-                                               .to_name_binding(this.arenas);
-                                result = Ok((binding, Flags::empty()));
+                                let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
+                                result = ok(res, derive.span, this.arenas);
                                 break;
                             }
                             Ok(_) | Err(Determinacy::Determined) => {}
@@ -529,41 +573,39 @@ impl<'a> Resolver<'a> {
                         Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
                     }
                 }
+                Scope::RegisteredAttrs => match this.registered_attrs.get(&ident).cloned() {
+                    Some(ident) => ok(
+                        Res::NonMacroAttr(NonMacroAttrKind::Registered), ident.span, this.arenas
+                    ),
+                    None => Err(Determinacy::Determined)
+                }
                 Scope::MacroUsePrelude => match this.macro_use_prelude.get(&ident.name).cloned() {
-                    Some(binding) => Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)),
+                    Some(binding) => Ok((binding, Flags::MISC_FROM_PRELUDE)),
                     None => Err(Determinacy::determined(
                         this.graph_root.unexpanded_invocations.borrow().is_empty()
                     ))
                 }
                 Scope::BuiltinAttrs => if is_builtin_attr_name(ident.name) {
-                    let binding = (Res::NonMacroAttr(NonMacroAttrKind::Builtin),
-                                   ty::Visibility::Public, DUMMY_SP, ExpnId::root())
-                                   .to_name_binding(this.arenas);
-                    Ok((binding, Flags::PRELUDE))
+                    ok(Res::NonMacroAttr(NonMacroAttrKind::Builtin), DUMMY_SP, this.arenas)
                 } else {
                     Err(Determinacy::Determined)
                 }
                 Scope::LegacyPluginHelpers => if this.session.plugin_attributes.borrow().iter()
                                                      .any(|(name, _)| ident.name == *name) {
-                    let binding = (Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
-                                   ty::Visibility::Public, DUMMY_SP, ExpnId::root())
-                                   .to_name_binding(this.arenas);
-                    Ok((binding, Flags::PRELUDE))
+                    let res = Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
+                    ok(res, DUMMY_SP, this.arenas)
                 } else {
                     Err(Determinacy::Determined)
                 }
                 Scope::ExternPrelude => match this.extern_prelude_get(ident, !record_used) {
-                    Some(binding) => Ok((binding, Flags::PRELUDE)),
+                    Some(binding) => Ok((binding, Flags::empty())),
                     None => Err(Determinacy::determined(
                         this.graph_root.unexpanded_invocations.borrow().is_empty()
                     )),
                 }
-                Scope::ToolPrelude => if KNOWN_TOOLS.contains(&ident.name) {
-                    let binding = (Res::ToolMod, ty::Visibility::Public, DUMMY_SP, ExpnId::root())
-                                   .to_name_binding(this.arenas);
-                    Ok((binding, Flags::PRELUDE))
-                } else {
-                    Err(Determinacy::Determined)
+                Scope::ToolPrelude => match this.registered_tools.get(&ident).cloned() {
+                    Some(ident) => ok(Res::ToolMod, ident.span, this.arenas),
+                    None => Err(Determinacy::Determined)
                 }
                 Scope::StdLibPrelude => {
                     let mut result = Err(Determinacy::Determined);
@@ -577,7 +619,7 @@ impl<'a> Resolver<'a> {
                             path_span,
                         ) {
                             if use_prelude || this.is_builtin_macro(binding.res()) {
-                                result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
+                                result = Ok((binding, Flags::MISC_FROM_PRELUDE));
                             }
                         }
                     }
@@ -585,11 +627,7 @@ impl<'a> Resolver<'a> {
                 }
                 Scope::BuiltinTypes => match this.primitive_type_table.primitive_types
                                                  .get(&ident.name).cloned() {
-                    Some(prim_ty) => {
-                        let binding = (Res::PrimTy(prim_ty), ty::Visibility::Public,
-                                       DUMMY_SP, ExpnId::root()).to_name_binding(this.arenas);
-                        Ok((binding, Flags::PRELUDE))
-                    }
+                    Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas),
                     None => Err(Determinacy::Determined)
                 }
             };
@@ -606,8 +644,6 @@ impl<'a> Resolver<'a> {
                         if res != innermost_res {
                             let builtin = Res::NonMacroAttr(NonMacroAttrKind::Builtin);
                             let derive_helper = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
-                            let legacy_helper =
-                                Res::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
 
                             let ambiguity_error_kind = if is_import {
                                 Some(AmbiguityKind::Import)
@@ -615,11 +651,6 @@ impl<'a> Resolver<'a> {
                                 Some(AmbiguityKind::BuiltinAttr)
                             } else if innermost_res == derive_helper || res == derive_helper {
                                 Some(AmbiguityKind::DeriveHelper)
-                            } else if innermost_res == legacy_helper &&
-                                      flags.contains(Flags::PRELUDE) ||
-                                      res == legacy_helper &&
-                                      innermost_flags.contains(Flags::PRELUDE) {
-                                Some(AmbiguityKind::LegacyHelperVsPrelude)
                             } else if innermost_flags.contains(Flags::MACRO_RULES) &&
                                       flags.contains(Flags::MODULE) &&
                                       !this.disambiguate_legacy_vs_modern(innermost_binding,
@@ -679,20 +710,7 @@ impl<'a> Resolver<'a> {
             return Ok(binding);
         }
 
-        let determinacy = Determinacy::determined(determinacy == Determinacy::Determined || force);
-        if determinacy == Determinacy::Determined && macro_kind == Some(MacroKind::Attr) &&
-           self.session.features_untracked().custom_attribute {
-            // For single-segment attributes interpret determinate "no resolution" as a custom
-            // attribute. (Lexical resolution implies the first segment and attr kind should imply
-            // the last segment, so we are certainly working with a single-segment attribute here.)
-            assert!(ns == MacroNS);
-            let binding = (Res::NonMacroAttr(NonMacroAttrKind::Custom),
-                           ty::Visibility::Public, orig_ident.span, ExpnId::root())
-                           .to_name_binding(self.arenas);
-            Ok(binding)
-        } else {
-            Err(determinacy)
-        }
+        Err(Determinacy::determined(determinacy == Determinacy::Determined || force))
     }
 
     crate fn finalize_macro_resolutions(&mut self) {
@@ -703,16 +721,7 @@ impl<'a> Resolver<'a> {
                     // Make sure compilation does not succeed if preferred macro resolution
                     // has changed after the macro had been expanded. In theory all such
                     // situations should be reported as ambiguity errors, so this is a bug.
-                    if initial_res == Res::NonMacroAttr(NonMacroAttrKind::Custom) {
-                        // Yeah, legacy custom attributes are implemented using forced resolution
-                        // (which is a best effort error recovery tool, basically), so we can't
-                        // promise their resolution won't change later.
-                        let msg = format!("inconsistent resolution for a macro: first {}, then {}",
-                                          initial_res.descr(), res.descr());
-                        this.session.span_err(span, &msg);
-                    } else {
-                        span_bug!(span, "inconsistent resolution for a macro");
-                    }
+                    span_bug!(span, "inconsistent resolution for a macro");
                 }
             } else {
                 // It's possible that the macro was unresolved (indeterminate) and silently
@@ -824,7 +833,8 @@ impl<'a> Resolver<'a> {
                                          res: Option<Res>, span: Span) {
         if let Some(Res::NonMacroAttr(kind)) = res {
             if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
-                let msg = format!("cannot use a {} through an import", kind.descr());
+                let msg =
+                    format!("cannot use {} {} through an import", kind.article(), kind.descr());
                 let mut err = self.session.struct_span_err(span, &msg);
                 if let Some(binding) = binding {
                     err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index c39f0c90f98..083b11daaa1 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -11,23 +11,19 @@ use crate::{Resolver, ResolutionError, BindingKey, Segment, ModuleKind};
 use crate::{names_to_string, module_to_string};
 use crate::diagnostics::Suggestion;
 
-use errors::{Applicability, pluralise};
+use errors::{Applicability, pluralize};
 
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc::ty;
 use rustc::lint::builtin::BuiltinLintDiagnostics;
-use rustc::lint::builtin::{
-    DUPLICATE_MACRO_EXPORTS,
-    PUB_USE_OF_PRIVATE_EXTERN_CRATE,
-    UNUSED_IMPORTS,
-};
+use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
 use rustc::hir::def_id::DefId;
 use rustc::hir::def::{self, PartialRes, Export};
 use rustc::session::DiagnosticMessageId;
 use rustc::util::nodemap::FxHashSet;
 use rustc::{bug, span_bug};
 
-use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID};
+use syntax::ast::{Ident, Name, NodeId};
 use syntax::symbol::kw;
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::{struct_span_err, unwrap_or};
@@ -496,13 +492,13 @@ impl<'a> Resolver<'a> {
                         if let (&NameBindingKind::Res(_, true), &NameBindingKind::Res(_, true)) =
                                (&old_binding.kind, &binding.kind) {
 
-                            this.lint_buffer.buffer_lint_with_diagnostic(
-                                DUPLICATE_MACRO_EXPORTS,
-                                CRATE_NODE_ID,
+                            this.session.struct_span_err(
                                 binding.span,
                                 &format!("a macro named `{}` has already been exported", key.ident),
-                                BuiltinLintDiagnostics::DuplicatedMacroExports(
-                                    key.ident, old_binding.span, binding.span));
+                            )
+                            .span_label(binding.span, format!("`{}` already exported", key.ident))
+                            .span_note(old_binding.span, "previous macro export is now shadowed")
+                            .emit();
 
                             resolution.binding = Some(binding);
                         } else {
@@ -730,7 +726,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             let msg = format!(
                 "unresolved import{} {}",
-                pluralise!(paths.len()),
+                pluralize!(paths.len()),
                 paths.join(", "),
             );
 
diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml
index b89c83d630b..50b3be6dca1 100644
--- a/src/librustc_save_analysis/Cargo.toml
+++ b/src/librustc_save_analysis/Cargo.toml
@@ -13,7 +13,7 @@ log = "0.4"
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_codegen_utils = { path = "../librustc_codegen_utils" }
-rustc_target = { path = "../librustc_target" }
+rustc_parse = { path = "../librustc_parse" }
 serde_json = "1"
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index a372106d379..92c391fb4a3 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -24,7 +24,7 @@ use std::path::Path;
 use std::env;
 
 use syntax::ast::{self, Attribute, NodeId, PatKind};
-use syntax::parse::token;
+use syntax::token;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{
     bounds_to_string,
@@ -272,7 +272,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
 
     fn process_method(
         &mut self,
-        sig: &'l ast::MethodSig,
+        sig: &'l ast::FnSig,
         body: Option<&'l ast::Block>,
         id: ast::NodeId,
         ident: ast::Ident,
@@ -1334,8 +1334,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                     );
                 }
             }
-            Fn(ref decl, ref header, ref ty_params, ref body) => {
-                self.process_fn(item, &decl, &header, ty_params, &body)
+            Fn(ref sig, ref ty_params, ref body) => {
+                self.process_fn(item, &sig.decl, &sig.header, ty_params, &body)
             }
             Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
             Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 1cfb84bb511..424d57c8fe7 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -29,7 +29,7 @@ use std::path::{Path, PathBuf};
 
 use syntax::ast::{self, Attribute, DUMMY_NODE_ID, NodeId, PatKind};
 use syntax::source_map::Spanned;
-use syntax::parse::lexer::comments::strip_doc_comment_decoration;
+use syntax::util::comments::strip_doc_comment_decoration;
 use syntax::print::pprust;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{param_to_string, ty_to_string};
@@ -180,7 +180,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
 
     pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
         match item.kind {
-            ast::ItemKind::Fn(ref decl, .., ref generics, _) => {
+            ast::ItemKind::Fn(ref sig, .., ref generics, _) => {
                 let qualname = format!("::{}",
                     self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
                 filter!(self.span_utils, item.ident.span);
@@ -190,7 +190,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                     span: self.span_from_span(item.ident.span),
                     name: item.ident.to_string(),
                     qualname,
-                    value: make_signature(decl, generics),
+                    value: make_signature(&sig.decl, generics),
                     parent: None,
                     children: vec![],
                     decl_id: None,
@@ -885,7 +885,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
         for attr in attrs {
             if attr.check_name(sym::doc) {
                 if let Some(val) = attr.value_str() {
-                    if attr.is_sugared_doc {
+                    if attr.is_doc_comment() {
                         result.push_str(&strip_doc_comment_decoration(&val.as_str()));
                     } else {
                         result.push_str(&val.as_str());
@@ -1195,7 +1195,7 @@ fn null_id() -> rls_data::Id {
 fn lower_attributes(attrs: Vec<Attribute>, scx: &SaveContext<'_, '_>) -> Vec<rls_data::Attribute> {
     attrs.into_iter()
     // Only retain real attributes. Doc comments are lowered separately.
-    .filter(|attr| attr.path != sym::doc)
+    .filter(|attr| !attr.has_name(sym::doc))
     .map(|mut attr| {
         // Remove the surrounding '#[..]' or '#![..]' of the pretty printed
         // attribute. First normalize all inner attribute (#![..]) to outer
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 203bd4d4167..d1b9b8ff44d 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -32,7 +32,7 @@ use rls_data::{SigElement, Signature};
 use rustc::hir::def::{Res, DefKind};
 use syntax::ast::{self, NodeId};
 use syntax::print::pprust;
-
+use syntax_pos::sym;
 
 pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
     if !scx.config.signatures {
@@ -72,7 +72,7 @@ pub fn method_signature(
     id: NodeId,
     ident: ast::Ident,
     generics: &ast::Generics,
-    m: &ast::MethodSig,
+    m: &ast::FnSig,
     scx: &SaveContext<'_, '_>,
 ) -> Option<Signature> {
     if !scx.config.signatures {
@@ -157,6 +157,12 @@ fn text_sig(text: String) -> Signature {
     }
 }
 
+fn push_abi(text: &mut String, abi: ast::Abi) {
+    if abi.symbol != sym::Rust {
+        text.push_str(&format!("extern \"{}\" ", abi.symbol));
+    }
+}
+
 impl Sig for ast::Ty {
     fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
         let id = Some(self.id);
@@ -231,11 +237,7 @@ impl Sig for ast::Ty {
                 if f.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                if f.abi != rustc_target::spec::abi::Abi::Rust {
-                    text.push_str("extern");
-                    text.push_str(&f.abi.to_string());
-                    text.push(' ');
-                }
+                push_abi(&mut text, f.abi);
                 text.push_str("fn(");
 
                 let mut defs = vec![];
@@ -374,7 +376,7 @@ impl Sig for ast::Item {
 
                 Ok(extend_sig(ty, text, defs, vec![]))
             }
-            ast::ItemKind::Fn(ref decl, header, ref generics, _) => {
+            ast::ItemKind::Fn(ast::FnSig { ref decl, header }, ref generics, _) => {
                 let mut text = String::new();
                 if header.constness.node == ast::Constness::Const {
                     text.push_str("const ");
@@ -385,11 +387,7 @@ impl Sig for ast::Item {
                 if header.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                if header.abi != rustc_target::spec::abi::Abi::Rust {
-                    text.push_str("extern");
-                    text.push_str(&header.abi.to_string());
-                    text.push(' ');
-                }
+                push_abi(&mut text, header.abi);
                 text.push_str("fn ");
 
                 let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@@ -934,7 +932,7 @@ fn make_method_signature(
     id: NodeId,
     ident: ast::Ident,
     generics: &ast::Generics,
-    m: &ast::MethodSig,
+    m: &ast::FnSig,
     scx: &SaveContext<'_, '_>,
 ) -> Result {
     // FIXME code dup with function signature
@@ -948,11 +946,7 @@ fn make_method_signature(
     if m.header.unsafety == ast::Unsafety::Unsafe {
         text.push_str("unsafe ");
     }
-    if m.header.abi != rustc_target::spec::abi::Abi::Rust {
-        text.push_str("extern");
-        text.push_str(&m.header.abi.to_string());
-        text.push(' ');
-    }
+    push_abi(&mut text, m.header.abi);
     text.push_str("fn ");
 
     let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;
diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs
index fb9919d777d..f2f512bc8e5 100644
--- a/src/librustc_save_analysis/span_utils.rs
+++ b/src/librustc_save_analysis/span_utils.rs
@@ -1,9 +1,7 @@
-use rustc::session::Session;
-
 use crate::generated_code;
-
-use syntax::parse::lexer::{self, StringReader};
-use syntax::parse::token::{self, TokenKind};
+use rustc::session::Session;
+use rustc_parse::lexer::{self, StringReader};
+use syntax::token::{self, TokenKind};
 use syntax_pos::*;
 
 #[derive(Clone)]
diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs
index db34d366212..18b121f9c5b 100644
--- a/src/librustc_target/abi/call/mips64.rs
+++ b/src/librustc_target/abi/call/mips64.rs
@@ -23,8 +23,8 @@ fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
 {
     match ret.layout.field(cx, i).abi {
         abi::Abi::Scalar(ref scalar) => match scalar.value {
-            abi::Float(abi::FloatTy::F32) => Some(Reg::f32()),
-            abi::Float(abi::FloatTy::F64) => Some(Reg::f64()),
+            abi::F32 => Some(Reg::f32()),
+            abi::F64 => Some(Reg::f64()),
             _ => None
         },
         _ => None
@@ -107,7 +107,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 
                 // We only care about aligned doubles
                 if let abi::Abi::Scalar(ref scalar) = field.abi {
-                    if let abi::Float(abi::FloatTy::F64) = scalar.value {
+                    if let abi::F64 = scalar.value {
                         if offset.is_aligned(dl.f64_align.abi) {
                             // Insert enough integers to cover [last_offset, offset)
                             assert!(last_offset.is_aligned(dl.f64_align.abi));
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 396b9620038..aced12aa32a 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -287,7 +287,7 @@ impl<'a, Ty> TyLayout<'a, Ty> {
                 let kind = match scalar.value {
                     abi::Int(..) |
                     abi::Pointer => RegKind::Integer,
-                    abi::Float(_) => RegKind::Float,
+                    abi::F32 | abi::F64 => RegKind::Float,
                 };
                 HomogeneousAggregate::Homogeneous(Reg {
                     kind,
@@ -554,7 +554,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "arm" => arm::compute_abi_info(cx, self),
             "mips" => mips::compute_abi_info(cx, self),
             "mips64" => mips64::compute_abi_info(cx, self),
-            "powerpc" => powerpc::compute_abi_info(cx, self),
+            "powerpc" => powerpc::compute_abi_info(self),
             "powerpc64" => powerpc64::compute_abi_info(cx, self),
             "s390x" => s390x::compute_abi_info(cx, self),
             "msp430" => msp430::compute_abi_info(self),
diff --git a/src/librustc_target/abi/call/powerpc.rs b/src/librustc_target/abi/call/powerpc.rs
index b2c8d26ff1f..740bd7222f2 100644
--- a/src/librustc_target/abi/call/powerpc.rs
+++ b/src/librustc_target/abi/call/powerpc.rs
@@ -1,49 +1,28 @@
-use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
-use crate::abi::{HasDataLayout, LayoutOf, Size, TyLayoutMethods};
+use crate::abi::call::{ArgAbi, FnAbi};
 
-fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size)
-    where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
-{
-    if !ret.layout.is_aggregate() {
-        ret.extend_integer_width_to(32);
-    } else {
+fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
+    if ret.layout.is_aggregate() {
         ret.make_indirect();
-        *offset += cx.data_layout().pointer_size;
+    } else {
+        ret.extend_integer_width_to(32);
     }
 }
 
-fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size)
-    where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
-{
-    let dl = cx.data_layout();
-    let size = arg.layout.size;
-    let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi;
-
+fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
     if arg.layout.is_aggregate() {
-        arg.cast_to(Uniform {
-            unit: Reg::i32(),
-            total: size
-        });
-        if !offset.is_aligned(align) {
-            arg.pad_with(Reg::i32());
-        }
+        arg.make_indirect();
     } else {
         arg.extend_integer_width_to(32);
     }
-
-    *offset = offset.align_to(align) + size.align_to(align);
 }
 
-pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>)
-    where Ty: TyLayoutMethods<'a, C>, C: LayoutOf<Ty = Ty> + HasDataLayout
-{
-    let mut offset = Size::ZERO;
+pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
     if !fn_abi.ret.is_ignore() {
-        classify_ret(cx, &mut fn_abi.ret, &mut offset);
+        classify_ret(&mut fn_abi.ret);
     }
 
     for arg in &mut fn_abi.args {
         if arg.is_ignore() { continue; }
-        classify_arg(cx, arg, &mut offset);
+        classify_arg(arg);
     }
 }
diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs
index 96fd077ec00..452ca024e61 100644
--- a/src/librustc_target/abi/call/x86_64.rs
+++ b/src/librustc_target/abi/call/x86_64.rs
@@ -45,7 +45,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &ArgAbi<'a, Ty>)
                 match scalar.value {
                     abi::Int(..) |
                     abi::Pointer => Class::Int,
-                    abi::Float(_) => Class::Sse
+                    abi::F32 | abi::F64 => Class::Sse
                 }
             }
 
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index fde5c5bed4d..2d7e05037ba 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -3,11 +3,9 @@ pub use Primitive::*;
 
 use crate::spec::Target;
 
-use std::fmt;
 use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
 
 use rustc_index::vec::{Idx, IndexVec};
-use syntax_pos::symbol::{sym, Symbol};
 use syntax_pos::Span;
 
 pub mod call;
@@ -534,49 +532,6 @@ impl Integer {
     }
 }
 
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy,
-         PartialOrd, Ord)]
-pub enum FloatTy {
-    F32,
-    F64,
-}
-
-impl fmt::Debug for FloatTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Display for FloatTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ty_to_string())
-    }
-}
-
-impl FloatTy {
-    pub fn ty_to_string(self) -> &'static str {
-        match self {
-            FloatTy::F32 => "f32",
-            FloatTy::F64 => "f64",
-        }
-    }
-
-    pub fn to_symbol(self) -> Symbol {
-        match self {
-            FloatTy::F32 => sym::f32,
-            FloatTy::F64 => sym::f64,
-        }
-    }
-
-    pub fn bit_width(self) -> usize {
-        match self {
-            FloatTy::F32 => 32,
-            FloatTy::F64 => 64,
-        }
-    }
-}
-
 /// Fundamental unit of memory access and layout.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum Primitive {
@@ -588,7 +543,8 @@ pub enum Primitive {
     /// a negative integer passed by zero-extension will appear positive in
     /// the callee, and most operations on it will produce the wrong values.
     Int(Integer, bool),
-    Float(FloatTy),
+    F32,
+    F64,
     Pointer
 }
 
@@ -598,8 +554,8 @@ impl Primitive {
 
         match self {
             Int(i, _) => i.size(),
-            Float(FloatTy::F32) => Size::from_bits(32),
-            Float(FloatTy::F64) => Size::from_bits(64),
+            F32 => Size::from_bits(32),
+            F64 => Size::from_bits(64),
             Pointer => dl.pointer_size
         }
     }
@@ -609,15 +565,15 @@ impl Primitive {
 
         match self {
             Int(i, _) => i.align(dl),
-            Float(FloatTy::F32) => dl.f32_align,
-            Float(FloatTy::F64) => dl.f64_align,
+            F32 => dl.f32_align,
+            F64 => dl.f64_align,
             Pointer => dl.pointer_align
         }
     }
 
     pub fn is_float(self) -> bool {
         match self {
-            Float(_) => true,
+            F32 | F64 => true,
             _ => false
         }
     }
@@ -738,11 +694,7 @@ impl FieldPlacement {
 
     pub fn offset(&self, i: usize) -> Size {
         match *self {
-            FieldPlacement::Union(count) => {
-                assert!(i < count,
-                        "Tried to access field {} of union with {} fields", i, count);
-                Size::ZERO
-            },
+            FieldPlacement::Union(_) => Size::ZERO,
             FieldPlacement::Array { stride, count } => {
                 let i = i as u64;
                 assert!(i < count);
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 6033d52c441..4cd2f13d09c 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -362,6 +362,7 @@ supported_targets! {
     ("armv7-unknown-linux-gnueabi", armv7_unknown_linux_gnueabi),
     ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
     ("thumbv7neon-unknown-linux-gnueabihf", thumbv7neon_unknown_linux_gnueabihf),
+    ("thumbv7neon-unknown-linux-musleabihf", thumbv7neon_unknown_linux_musleabihf),
     ("armv7-unknown-linux-musleabi", armv7_unknown_linux_musleabi),
     ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
     ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
@@ -793,7 +794,10 @@ pub struct TargetOptions {
     pub merge_functions: MergeFunctions,
 
     /// Use platform dependent mcount function
-    pub target_mcount: String
+    pub target_mcount: String,
+
+    /// LLVM ABI name, corresponds to the '-mabi' parameter available in multilib C compilers
+    pub llvm_abiname: String,
 }
 
 impl Default for TargetOptions {
@@ -880,6 +884,7 @@ impl Default for TargetOptions {
             override_export_symbols: None,
             merge_functions: MergeFunctions::Aliases,
             target_mcount: "mcount".to_string(),
+            llvm_abiname: "".to_string(),
         }
     }
 }
@@ -1196,6 +1201,7 @@ impl Target {
         key!(override_export_symbols, opt_list);
         key!(merge_functions, MergeFunctions)?;
         key!(target_mcount);
+        key!(llvm_abiname);
 
         if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
             for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -1414,6 +1420,7 @@ impl ToJson for Target {
         target_option_val!(override_export_symbols);
         target_option_val!(merge_functions);
         target_option_val!(target_mcount);
+        target_option_val!(llvm_abiname);
 
         if default.abi_blacklist != self.options.abi_blacklist {
             d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
diff --git a/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs b/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
new file mode 100644
index 00000000000..1270f391731
--- /dev/null
+++ b/src/librustc_target/spec/thumbv7neon_unknown_linux_musleabihf.rs
@@ -0,0 +1,37 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+// This target is for musl Linux on ARMv7 with thumb mode enabled
+// (for consistency with Android and Debian-based distributions)
+// and with NEON unconditionally enabled and, therefore, with 32 FPU
+// registers enabled as well. See section A2.6.2 on page A2-56 in
+// https://static.docs.arm.com/ddi0406/cd/DDI0406C_d_armv7ar_arm.pdf
+
+pub fn target() -> TargetResult {
+    let base = super::linux_musl_base::opts();
+    Ok(Target {
+        // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
+        // uses it to determine the calling convention and float ABI, and LLVM
+        // doesn't support the "musleabihf" value.
+        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: "linux".to_string(),
+        target_env: "musl".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf
+        // target.
+        options: TargetOptions {
+            features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
+            cpu: "generic".to_string(),
+            max_atomic_width: Some(64),
+            abi_blacklist: super::arm_base::abi_blacklist(),
+            target_mcount: "\u{1}mcount".to_string(),
+            .. base
+        }
+    })
+}
diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs
index 38db9cd356c..ce7b338345c 100644
--- a/src/librustc_target/spec/windows_base.rs
+++ b/src/librustc_target/spec/windows_base.rs
@@ -4,33 +4,6 @@ use std::default::Default;
 pub fn opts() -> TargetOptions {
     let mut pre_link_args = LinkArgs::new();
     pre_link_args.insert(LinkerFlavor::Gcc, vec![
-            // And here, we see obscure linker flags #45. On windows, it has been
-            // found to be necessary to have this flag to compile liblibc.
-            //
-            // First a bit of background. On Windows, the file format is not ELF,
-            // but COFF (at least according to LLVM). COFF doesn't officially allow
-            // for section names over 8 characters, apparently. Our metadata
-            // section, ".note.rustc", you'll note is over 8 characters.
-            //
-            // On more recent versions of gcc on mingw, apparently the section name
-            // is *not* truncated, but rather stored elsewhere in a separate lookup
-            // table. On older versions of gcc, they apparently always truncated th
-            // section names (at least in some cases). Truncating the section name
-            // actually creates "invalid" objects [1] [2], but only for some
-            // introspection tools, not in terms of whether it can be loaded.
-            //
-            // Long story short, passing this flag forces the linker to *not*
-            // truncate section names (so we can find the metadata section after
-            // it's compiled). The real kicker is that rust compiled just fine on
-            // windows for quite a long time *without* this flag, so I have no idea
-            // why it suddenly started failing for liblibc. Regardless, we
-            // definitely don't want section name truncation, so we're keeping this
-            // flag for windows.
-            //
-            // [1] - https://sourceware.org/bugzilla/show_bug.cgi?id=13130
-            // [2] - https://code.google.com/p/go/issues/detail?id=2139
-            "-Wl,--enable-long-section-names".to_string(),
-
             // Tell GCC to avoid linker plugins, because we are not bundling
             // them with Windows installer, and Rust does its own LTO anyways.
             "-fno-use-linker-plugin".to_string(),
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index b86a3a5e963..a9b184a7b30 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -16,4 +16,4 @@ rustc_target = { path = "../librustc_target" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 chalk-engine = { version = "0.9.0", default-features=false }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/librustc_traits/chalk_context/program_clauses/builtin.rs b/src/librustc_traits/chalk_context/program_clauses/builtin.rs
index 13bbe021ccf..3ad68d4a9df 100644
--- a/src/librustc_traits/chalk_context/program_clauses/builtin.rs
+++ b/src/librustc_traits/chalk_context/program_clauses/builtin.rs
@@ -243,7 +243,7 @@ crate fn assemble_builtin_copy_clone_impls<'tcx>(
         ty::Float(..) |
         ty::RawPtr(..) |
         ty::Never |
-        ty::Ref(_, _, hir::MutImmutable) => (),
+        ty::Ref(_, _, hir::Mutability::Immutable) => (),
 
         // Non parametric primitive types.
         ty::Infer(ty::IntVar(_)) |
@@ -319,7 +319,7 @@ crate fn assemble_builtin_copy_clone_impls<'tcx>(
         ty::Generator(..) |
         ty::Str |
         ty::Slice(..) |
-        ty::Ref(_, _, hir::MutMutable) => (),
+        ty::Ref(_, _, hir::Mutability::Mutable) => (),
 
         ty::Bound(..) |
         ty::GeneratorWitness(..) |
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index c1316f415a5..d77ec3010f4 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -1,6 +1,7 @@
 use rustc::hir::def_id::DefId;
 use rustc::infer::canonical::{Canonical, QueryResponse};
 use rustc::traits::query::dropck_outlives::{DropckOutlivesResult, DtorckConstraint};
+use rustc::traits::query::dropck_outlives::trivial_dropck_outlives;
 use rustc::traits::query::{CanonicalTyGoal, NoSolution};
 use rustc::traits::{TraitEngine, Normalized, ObligationCause, TraitEngineExt};
 use rustc::ty::query::Providers;
@@ -172,7 +173,7 @@ fn dtorck_constraint_for_ty<'tcx>(
         return Ok(());
     }
 
-    if tcx.trivial_dropck_outlives(ty) {
+    if trivial_dropck_outlives(tcx, ty) {
         return Ok(());
     }
 
diff --git a/src/librustc_traits/generic_types.rs b/src/librustc_traits/generic_types.rs
index cc5348623fa..96ba4d497cb 100644
--- a/src/librustc_traits/generic_types.rs
+++ b/src/librustc_traits/generic_types.rs
@@ -76,6 +76,6 @@ crate fn generator(tcx: TyCtxt<'tcx>, def_id: DefId) -> Ty<'tcx> {
     tcx.mk_generator(
         def_id,
         InternalSubsts::bound_vars_for_item(tcx, def_id),
-        hir::GeneratorMovability::Movable
+        hir::Movability::Movable
     )
 }
diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml
index a6644258be2..60a7a2f4598 100644
--- a/src/librustc_typeck/Cargo.toml
+++ b/src/librustc_typeck/Cargo.toml
@@ -17,7 +17,7 @@ rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_index = { path = "../librustc_index" }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index b14121da79f..5c661513382 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -23,7 +23,7 @@ use rustc_target::spec::abi;
 use crate::require_c_abi_if_c_variadic;
 use smallvec::SmallVec;
 use syntax::ast;
-use syntax::errors::pluralise;
+use syntax::errors::pluralize;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::symbol::sym;
@@ -392,7 +392,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     quantifier,
                     bound,
                     kind,
-                    pluralise!(bound),
+                    pluralize!(bound),
                 ))
             };
 
@@ -1360,7 +1360,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 span,
                 E0191,
                 "the value of the associated type{} {} must be specified",
-                pluralise!(associated_types.len()),
+                pluralize!(associated_types.len()),
                 names,
             );
             let (suggest, potential_assoc_types_spans) =
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index a1daed005f3..6a35f9b8452 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -430,8 +430,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let contains_ref_bindings = arms.iter()
             .filter_map(|a| a.pat.contains_explicit_ref_binding())
             .max_by_key(|m| match *m {
-                hir::MutMutable => 1,
-                hir::MutImmutable => 0,
+                hir::Mutability::Mutable => 1,
+                hir::Mutability::Immutable => 0,
             });
 
         if let Some(m) = contains_ref_bindings {
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 300b730b5bb..c195e91a52b 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -215,8 +215,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if borrow {
                     if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind {
                         let mutbl = match mutbl {
-                            hir::MutImmutable => AutoBorrowMutability::Immutable,
-                            hir::MutMutable => AutoBorrowMutability::Mutable {
+                            hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                            hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                                 // For initial two-phase borrow
                                 // deployment, conservatively omit
                                 // overloaded function call ops.
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 9cbde276ae9..3245f2cca79 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -341,10 +341,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                                          tstr);
         match self.expr_ty.kind {
             ty::Ref(_, _, mt) => {
-                let mtstr = match mt {
-                    hir::MutMutable => "mut ",
-                    hir::MutImmutable => "",
-                };
+                let mtstr = mt.prefix_str();
                 if self.cast_ty.is_trait() {
                     match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
                         Ok(s) => {
@@ -630,7 +627,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     ) -> Result<CastKind, CastError> {
         // array-ptr-cast.
 
-        if m_expr.mutbl == hir::MutImmutable && m_cast.mutbl == hir::MutImmutable {
+        if m_expr.mutbl == hir::Mutability::Immutable &&
+            m_cast.mutbl == hir::Mutability::Immutable {
             if let ty::Array(ety, _) = m_expr.ty.kind {
                 // Due to the limitations of LLVM global constants,
                 // region pointers end up pointing at copies of
@@ -639,6 +637,15 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 // need to special-case obtaining a raw pointer
                 // from a region pointer to a vector.
 
+                // Coerce to a raw pointer so that we generate AddressOf in MIR.
+                let array_ptr_type = fcx.tcx.mk_ptr(m_expr);
+                fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No)
+                    .unwrap_or_else(|_| bug!(
+                        "could not cast from reference to array to pointer to array ({:?} to {:?})",
+                        self.expr_ty,
+                        array_ptr_type,
+                    ));
+
                 // this will report a type mismatch if needed
                 fcx.demand_eqtype(self.span, ety, m_cast.ty);
                 return Ok(CastKind::ArrayPtrCast);
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 4f4133954cf..30cb0d4f967 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -36,10 +36,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_expr_closure(
         &self,
         expr: &hir::Expr,
-        _capture: hir::CaptureClause,
+        _capture: hir::CaptureBy,
         decl: &'tcx hir::FnDecl,
         body_id: hir::BodyId,
-        gen: Option<hir::GeneratorMovability>,
+        gen: Option<hir::Movability>,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
         debug!(
@@ -64,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         opt_kind: Option<ty::ClosureKind>,
         decl: &'tcx hir::FnDecl,
         body: &'tcx hir::Body,
-        gen: Option<hir::GeneratorMovability>,
+        gen: Option<hir::Movability>,
         expected_sig: Option<ExpectedSig<'tcx>>,
     ) -> Ty<'tcx> {
         debug!(
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index f79351dc903..a105755ca9a 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -99,10 +99,10 @@ fn coerce_mutbls<'tcx>(from_mutbl: hir::Mutability,
                        to_mutbl: hir::Mutability)
                        -> RelateResult<'tcx, ()> {
     match (from_mutbl, to_mutbl) {
-        (hir::MutMutable, hir::MutMutable) |
-        (hir::MutImmutable, hir::MutImmutable) |
-        (hir::MutMutable, hir::MutImmutable) => Ok(()),
-        (hir::MutImmutable, hir::MutMutable) => Err(TypeError::Mutability),
+        (hir::Mutability::Mutable, hir::Mutability::Mutable) |
+        (hir::Mutability::Immutable, hir::Mutability::Immutable) |
+        (hir::Mutability::Mutable, hir::Mutability::Immutable) => Ok(()),
+        (hir::Mutability::Immutable, hir::Mutability::Mutable) => Err(TypeError::Mutability),
     }
 }
 
@@ -410,7 +410,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             }
         };
 
-        if ty == a && mt_a.mutbl == hir::MutImmutable && autoderef.step_count() == 1 {
+        if ty == a && mt_a.mutbl == hir::Mutability::Immutable && autoderef.step_count() == 1 {
             // As a special case, if we would produce `&'a *x`, that's
             // a total no-op. We end up with the type `&'a T` just as
             // we started with.  In that case, just skip it
@@ -422,7 +422,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             // `self.x` both have `&mut `type would be a move of
             // `self.x`, but we auto-coerce it to `foo(&mut *self.x)`,
             // which is a borrow.
-            assert_eq!(mt_b.mutbl, hir::MutImmutable); // can only coerce &T -> &U
+            assert_eq!(mt_b.mutbl, hir::Mutability::Immutable); // can only coerce &T -> &U
             return success(vec![], ty, obligations);
         }
 
@@ -439,8 +439,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             _ => span_bug!(span, "expected a ref type, got {:?}", ty),
         };
         let mutbl = match mt_b.mutbl {
-            hir::MutImmutable => AutoBorrowMutability::Immutable,
-            hir::MutMutable => AutoBorrowMutability::Mutable {
+            hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+            hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                 allow_two_phase_borrow: self.allow_two_phase,
             }
         };
@@ -485,8 +485,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 let coercion = Coercion(self.cause.span);
                 let r_borrow = self.next_region_var(coercion);
                 let mutbl = match mutbl_b {
-                    hir::MutImmutable => AutoBorrowMutability::Immutable,
-                    hir::MutMutable => AutoBorrowMutability::Mutable {
+                    hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                    hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                         // We don't allow two-phase borrows here, at least for initial
                         // implementation. If it happens that this coercion is a function argument,
                         // the reborrow in coerce_borrowed_ptr will pick it up.
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 6818d5f521d..2f0b1c358f0 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -10,7 +10,7 @@ use rustc::util::common::ErrorReported;
 use errors::{Applicability, DiagnosticId};
 
 use syntax_pos::Span;
-use syntax::errors::pluralise;
+use syntax::errors::pluralize;
 
 use super::{Inherited, FnCtxt, potentially_plural_count};
 
@@ -532,8 +532,8 @@ fn compare_self_type<'tcx>(
             let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
             match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
                 ExplicitSelf::ByValue => "self".to_owned(),
-                ExplicitSelf::ByReference(_, hir::MutImmutable) => "&self".to_owned(),
-                ExplicitSelf::ByReference(_, hir::MutMutable) => "&mut self".to_owned(),
+                ExplicitSelf::ByReference(_, hir::Mutability::Immutable) => "&self".to_owned(),
+                ExplicitSelf::ByReference(_, hir::Mutability::Mutable) => "&mut self".to_owned(),
                 _ => format!("self: {}", self_arg_ty)
             }
         })
@@ -649,9 +649,9 @@ fn compare_number_of_generics<'tcx>(
                      declaration has {} {kind} parameter{}",
                     trait_.ident,
                     impl_count,
-                    pluralise!(impl_count),
+                    pluralize!(impl_count),
                     trait_count,
-                    pluralise!(trait_count),
+                    pluralize!(trait_count),
                     kind = kind,
                 ),
                 DiagnosticId::Error("E0049".into()),
@@ -666,7 +666,7 @@ fn compare_number_of_generics<'tcx>(
                         "expected {} {} parameter{}",
                         trait_count,
                         kind,
-                        pluralise!(trait_count),
+                        pluralize!(trait_count),
                     ));
                 }
                 for span in spans {
@@ -681,7 +681,7 @@ fn compare_number_of_generics<'tcx>(
                     "found {} {} parameter{}{}",
                     impl_count,
                     kind,
-                    pluralise!(impl_count),
+                    pluralize!(impl_count),
                     suffix.unwrap_or_else(|| String::new()),
                 ));
             }
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index b4e07e4a0df..5d9b3a8fba4 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -308,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }) = parent {
                 if let Ok(src) = cm.span_to_snippet(sp) {
                     for field in fields {
-                        if field.ident.as_str() == src.as_str() && field.is_shorthand {
+                        if field.ident.as_str() == src && field.is_shorthand {
                             return true;
                         }
                     }
@@ -398,10 +398,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // bar(&x); // error, expected &mut
                 // ```
                 let ref_ty = match mutability {
-                    hir::Mutability::MutMutable => {
+                    hir::Mutability::Mutable => {
                         self.tcx.mk_mut_ref(self.tcx.mk_region(ty::ReStatic), checked_ty)
                     }
-                    hir::Mutability::MutImmutable => {
+                    hir::Mutability::Immutable => {
                         self.tcx.mk_imm_ref(self.tcx.mk_region(ty::ReStatic), checked_ty)
                     }
                 };
@@ -409,13 +409,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let mut sugg_sp = sp;
                     if let hir::ExprKind::MethodCall(segment, _sp, args) = &expr.kind {
                         let clone_trait = self.tcx.lang_items().clone_trait().unwrap();
-                        if let ([arg], Some(true), "clone") = (
+                        if let ([arg], Some(true), sym::clone) = (
                             &args[..],
                             self.tables.borrow().type_dependent_def_id(expr.hir_id).map(|did| {
                                 let ai = self.tcx.associated_item(did);
                                 ai.container == ty::TraitContainer(clone_trait)
                             }),
-                            &segment.ident.as_str()[..],
+                            segment.ident.name,
                         ) {
                             // If this expression had a clone call when suggesting borrowing
                             // we want to suggest removing it because it'd now be unecessary.
@@ -451,7 +451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         })) = self.tcx.hir().find(
                             self.tcx.hir().get_parent_node(expr.hir_id),
                         ) {
-                            if mutability == hir::Mutability::MutMutable {
+                            if mutability == hir::Mutability::Mutable {
                                 // Found the following case:
                                 // fn foo(opt: &mut Option<String>){ opt = None }
                                 //                                   ---   ^^^^
@@ -470,12 +470,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
 
                         return Some(match mutability {
-                            hir::Mutability::MutMutable => (
+                            hir::Mutability::Mutable => (
                                 sp,
                                 "consider mutably borrowing here",
                                 format!("{}&mut {}", field_name, sugg_expr),
                             ),
-                            hir::Mutability::MutImmutable => (
+                            hir::Mutability::Immutable => (
                                 sp,
                                 "consider borrowing here",
                                 format!("{}&{}", field_name, sugg_expr),
@@ -553,7 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn check_for_cast(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr,
         checked_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 8668dd99a8c..cfe36b57c2d 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -17,7 +17,7 @@ use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
 
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use syntax_pos::hygiene::DesugaringKind;
 use syntax::ast;
 use syntax::symbol::{Symbol, kw, sym};
@@ -363,8 +363,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let method = self.register_infer_ok_obligations(ok);
                         if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind {
                             let mutbl = match mutbl {
-                                hir::MutImmutable => AutoBorrowMutability::Immutable,
-                                hir::MutMutable => AutoBorrowMutability::Mutable {
+                                hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                                hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                                     // (It shouldn't actually matter for unary ops whether
                                     // we enable two-phase borrows or not, since a unary
                                     // op has no additional operands.)
@@ -583,21 +583,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 } else {
                     assert!(e_ty.is_unit());
                     let ty = coerce.expected_ty();
-                    coerce.coerce_forced_unit(self, &cause, &mut |err| {
-                        let val = match ty.kind {
-                            ty::Bool => "true",
-                            ty::Char => "'a'",
-                            ty::Int(_) | ty::Uint(_) => "42",
-                            ty::Float(_) => "3.14159",
-                            ty::Error | ty::Never => return,
-                            _ => "value",
-                        };
-                        let msg = "give it a value of the expected type";
-                        let label = destination.label
-                            .map(|l| format!(" {}", l.ident))
-                            .unwrap_or_else(String::new);
-                        let sugg = format!("break{} {}", label, val);
-                        err.span_suggestion(expr.span, msg, sugg, Applicability::HasPlaceholders);
+                    coerce.coerce_forced_unit(self, &cause, &mut |mut err| {
+                        self.suggest_mismatched_types_on_tail(
+                            &mut err,
+                            expr,
+                            ty,
+                            e_ty,
+                            cause.span,
+                            target_id,
+                        );
+                        if let Some(val) = ty_kind_suggestion(ty) {
+                            let label = destination.label
+                                .map(|l| format!(" {}", l.ident))
+                                .unwrap_or_else(String::new);
+                            err.span_suggestion(
+                                expr.span,
+                                "give it a value of the expected type",
+                                format!("break{} {}", label, val),
+                                Applicability::HasPlaceholders,
+                            );
+                        }
                     }, false);
                 }
             } else {
@@ -1210,7 +1215,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             struct_span_err!(tcx.sess, span, E0063,
                              "missing field{} {}{} in initializer of `{}`",
-                             pluralise!(remaining_fields.len()),
+                             pluralize!(remaining_fields.len()),
                              remaining_fields_names,
                              truncated_fields_error,
                              adt_ty)
@@ -1717,3 +1722,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.tcx.mk_unit()
     }
 }
+
+pub(super) fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
+    Some(match ty.kind {
+        ty::Bool => "true",
+        ty::Char => "'a'",
+        ty::Int(_) | ty::Uint(_) => "42",
+        ty::Float(_) => "3.14159",
+        ty::Error | ty::Never => return None,
+        _ => "value",
+    })
+}
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 33dc85fc68a..1a1b98f582f 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -67,11 +67,13 @@ fn equate_intrinsic_type<'tcx>(
 pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
     match intrinsic {
         "size_of" | "min_align_of" | "needs_drop" | "caller_location" |
+        "size_of_val" | "min_align_of_val" |
         "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
         "wrapping_add" | "wrapping_sub" | "wrapping_mul" |
         "saturating_add" | "saturating_sub" |
         "rotate_left" | "rotate_right" |
         "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" |
+        "discriminant_value" | "type_id" | "likely" | "unlikely" |
         "minnumf32" | "minnumf64" | "maxnumf32" | "maxnumf64" | "type_name"
         => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
@@ -170,7 +172,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
             "prefetch_read_instruction" | "prefetch_write_instruction" => {
                 (1, vec![tcx.mk_ptr(ty::TypeAndMut {
                           ty: param(0),
-                          mutbl: hir::MutImmutable
+                          mutbl: hir::Mutability::Immutable
                          }), tcx.types.i32],
                     tcx.mk_unit())
             }
@@ -186,13 +188,13 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
                vec![
                   tcx.mk_ptr(ty::TypeAndMut {
                       ty: param(0),
-                      mutbl: hir::MutImmutable
+                      mutbl: hir::Mutability::Immutable
                   }),
                   tcx.types.isize
                ],
                tcx.mk_ptr(ty::TypeAndMut {
                    ty: param(0),
-                   mutbl: hir::MutImmutable
+                   mutbl: hir::Mutability::Immutable
                }))
             }
             "copy" | "copy_nonoverlapping" => {
@@ -200,11 +202,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
                vec![
                   tcx.mk_ptr(ty::TypeAndMut {
                       ty: param(0),
-                      mutbl: hir::MutImmutable
+                      mutbl: hir::Mutability::Immutable
                   }),
                   tcx.mk_ptr(ty::TypeAndMut {
                       ty: param(0),
-                      mutbl: hir::MutMutable
+                      mutbl: hir::Mutability::Mutable
                   }),
                   tcx.types.usize,
                ],
@@ -215,11 +217,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
                vec![
                   tcx.mk_ptr(ty::TypeAndMut {
                       ty: param(0),
-                      mutbl: hir::MutMutable
+                      mutbl: hir::Mutability::Mutable
                   }),
                   tcx.mk_ptr(ty::TypeAndMut {
                       ty: param(0),
-                      mutbl: hir::MutImmutable
+                      mutbl: hir::Mutability::Immutable
                   }),
                   tcx.types.usize,
                ],
@@ -230,7 +232,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
                vec![
                   tcx.mk_ptr(ty::TypeAndMut {
                       ty: param(0),
-                      mutbl: hir::MutMutable
+                      mutbl: hir::Mutability::Mutable
                   }),
                   tcx.types.u8,
                   tcx.types.usize,
@@ -355,14 +357,14 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
             }
 
             "va_start" | "va_end" => {
-                match mk_va_list_ty(hir::MutMutable) {
+                match mk_va_list_ty(hir::Mutability::Mutable) {
                     Some((va_list_ref_ty, _)) => (0, vec![va_list_ref_ty], tcx.mk_unit()),
                     None => bug!("`va_list` language item needed for C-variadic intrinsics")
                 }
             }
 
             "va_copy" => {
-                match mk_va_list_ty(hir::MutImmutable) {
+                match mk_va_list_ty(hir::Mutability::Immutable) {
                     Some((va_list_ref_ty, va_list_ty)) => {
                         let va_list_ptr_ty = tcx.mk_mut_ptr(va_list_ty);
                         (0, vec![va_list_ptr_ty, va_list_ref_ty], tcx.mk_unit())
@@ -372,7 +374,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) {
             }
 
             "va_arg" => {
-                match mk_va_list_ty(hir::MutMutable) {
+                match mk_va_list_ty(hir::Mutability::Mutable) {
                     Some((va_list_ref_ty, _)) => (1, vec![va_list_ref_ty], param(0)),
                     None => bug!("`va_list` language item needed for C-variadic intrinsics")
                 }
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 59636d32bc0..4bdab84faf1 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -131,7 +131,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
             sig: method_sig,
         };
 
-        if let Some(hir::MutMutable) = pick.autoref {
+        if let Some(hir::Mutability::Mutable) = pick.autoref {
             self.convert_place_derefs_to_mutable();
         }
 
@@ -172,8 +172,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 ty: target
             });
             let mutbl = match mutbl {
-                hir::MutImmutable => AutoBorrowMutability::Immutable,
-                hir::MutMutable => AutoBorrowMutability::Mutable {
+                hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                     // Method call receivers are the primary use case
                     // for two-phase borrows.
                     allow_two_phase_borrow: AllowTwoPhase::Yes,
@@ -554,8 +554,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 if let Adjust::Borrow(AutoBorrow::Ref(..)) = adjustment.kind {
                     debug!("convert_place_op_to_mutable: converting autoref {:?}", adjustment);
                     let mutbl = match mutbl {
-                        hir::MutImmutable => AutoBorrowMutability::Immutable,
-                        hir::MutMutable => AutoBorrowMutability::Mutable {
+                        hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                        hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                             // For initial two-phase borrow
                             // deployment, conservatively omit
                             // overloaded operators.
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 593cf77a4a6..7ea7dba5a28 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -606,11 +606,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 let lang_def_id = lang_items.slice_u8_alloc_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
-            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
+            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Immutable }) => {
                 let lang_def_id = lang_items.const_ptr_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
-            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
+            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Mutable }) => {
                 let lang_def_id = lang_items.mut_ptr_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
             }
@@ -1045,8 +1045,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                         span_bug!(self.span, "{:?} was applicable but now isn't?", step.self_ty)
                     });
                 self.pick_by_value_method(step, self_ty).or_else(|| {
-                self.pick_autorefd_method(step, self_ty, hir::MutImmutable).or_else(|| {
-                self.pick_autorefd_method(step, self_ty, hir::MutMutable)
+                self.pick_autorefd_method(step, self_ty, hir::Mutability::Immutable).or_else(|| {
+                self.pick_autorefd_method(step, self_ty, hir::Mutability::Mutable)
             })})})
             .next()
     }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index d90ed2a790b..0b1657c4494 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -5,7 +5,7 @@ use crate::check::FnCtxt;
 use crate::middle::lang_items::FnOnceTraitLangItem;
 use crate::namespace::Namespace;
 use crate::util::nodemap::FxHashSet;
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use rustc::hir::{self, ExprKind, Node, QPath};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -601,7 +601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "{an}other candidate{s} {were} found in the following trait{s}, perhaps \
                          add a `use` for {one_of_them}:",
                         an = if candidates.len() == 1 {"an" } else { "" },
-                        s = pluralise!(candidates.len()),
+                        s = pluralize!(candidates.len()),
                         were = if candidates.len() == 1 { "was" } else { "were" },
                         one_of_them = if candidates.len() == 1 {
                             "it"
@@ -835,11 +835,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     sp,
                                     &message(format!(
                                         "restrict type parameter `{}` with",
-                                        param.name.ident().as_str(),
+                                        param.name.ident(),
                                     )),
                                     candidates.iter().map(|t| format!(
                                         "{}{} {}{}",
-                                        param.name.ident().as_str(),
+                                        param.name.ident(),
                                         if impl_trait { " +" } else { ":" },
                                         self.tcx.def_path_str(t.def_id),
                                         if has_bounds.is_some() { " + "} else { "" },
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a2af29aef09..72b5018589c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,7 +88,7 @@ pub mod intrinsic;
 mod op;
 
 use crate::astconv::{AstConv, PathSeg};
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralize};
 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
 use rustc::hir::def::{CtorOf, Res, DefKind};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -127,7 +127,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::source_map::{DUMMY_SP, original_sp};
-use syntax::symbol::{kw, sym};
+use syntax::symbol::{kw, sym, Ident};
 use syntax::util::parser::ExprPrecedence;
 
 use std::cell::{Cell, RefCell, Ref, RefMut};
@@ -387,8 +387,8 @@ pub enum Needs {
 impl Needs {
     fn maybe_mut_place(m: hir::Mutability) -> Self {
         match m {
-            hir::MutMutable => Needs::MutPlace,
-            hir::MutImmutable => Needs::None,
+            hir::Mutability::Mutable => Needs::MutPlace,
+            hir::Mutability::Immutable => Needs::None,
         }
     }
 }
@@ -815,8 +815,8 @@ fn primary_body_of(
                 hir::ItemKind::Const(ref ty, body) |
                 hir::ItemKind::Static(ref ty, _, body) =>
                     Some((body, Some(ty), None, None)),
-                hir::ItemKind::Fn(ref decl, ref header, .., body) =>
-                    Some((body, None, Some(header), Some(decl))),
+                hir::ItemKind::Fn(ref sig, .., body) =>
+                    Some((body, None, Some(&sig.header), Some(&sig.decl))),
                 _ =>
                     None,
             }
@@ -1090,7 +1090,7 @@ struct GeneratorTypes<'tcx> {
     interior: Ty<'tcx>,
 
     /// Indicates if the generator is movable or static (immovable).
-    movability: hir::GeneratorMovability,
+    movability: hir::Movability,
 }
 
 /// Helper used for fns and closures. Does the grungy work of checking a function
@@ -1106,7 +1106,7 @@ fn check_fn<'a, 'tcx>(
     decl: &'tcx hir::FnDecl,
     fn_id: hir::HirId,
     body: &'tcx hir::Body,
-    can_be_generator: Option<hir::GeneratorMovability>,
+    can_be_generator: Option<hir::Movability>,
 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
     let mut fn_sig = fn_sig.clone();
 
@@ -1267,11 +1267,6 @@ fn check_fn<'a, 'tcx>(
     if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
         if panic_impl_did == fcx.tcx.hir().local_def_id(fn_id) {
             if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
-                // at this point we don't care if there are duplicate handlers or if the handler has
-                // the wrong signature as this value we'll be used when writing metadata and that
-                // only happens if compilation succeeded
-                fcx.tcx.sess.has_panic_handler.try_set_same(true);
-
                 if declared_ret_ty.kind != ty::Never {
                     fcx.tcx.sess.span_err(
                         decl.output.span(),
@@ -1286,7 +1281,7 @@ fn check_fn<'a, 'tcx>(
                         ty::Ref(region, ty, mutbl) => match ty.kind {
                             ty::Adt(ref adt, _) => {
                                 adt.did == panic_info_did &&
-                                    mutbl == hir::Mutability::MutImmutable &&
+                                    mutbl == hir::Mutability::Immutable &&
                                     *region != RegionKind::ReStatic
                             },
                             _ => false,
@@ -1302,7 +1297,7 @@ fn check_fn<'a, 'tcx>(
                     }
 
                     if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
-                        if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
+                        if let ItemKind::Fn(_, ref generics, _) = item.kind {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
                                     span,
@@ -1350,7 +1345,7 @@ fn check_fn<'a, 'tcx>(
                     }
 
                     if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
-                        if let ItemKind::Fn(_, _, ref generics, _) = item.kind {
+                        if let ItemKind::Fn(_, ref generics, _) = item.kind {
                             if !generics.params.is_empty() {
                                 fcx.tcx.sess.span_err(
                                     span,
@@ -1805,12 +1800,12 @@ fn check_specialization_validity<'tcx>(
 
 fn check_impl_items_against_trait<'tcx>(
     tcx: TyCtxt<'tcx>,
-    impl_span: Span,
+    full_impl_span: Span,
     impl_id: DefId,
     impl_trait_ref: ty::TraitRef<'tcx>,
     impl_item_refs: &[hir::ImplItemRef],
 ) {
-    let impl_span = tcx.sess.source_map().def_span(impl_span);
+    let impl_span = tcx.sess.source_map().def_span(full_impl_span);
 
     // If the trait reference itself is erroneous (so the compilation is going
     // to fail), skip checking the items here -- the `impl_item` table in `tcx`
@@ -1930,35 +1925,132 @@ fn check_impl_items_against_trait<'tcx>(
     }
 
     if !missing_items.is_empty() {
-        let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
-            "not all trait items implemented, missing: `{}`",
-            missing_items.iter()
-                .map(|trait_item| trait_item.ident.to_string())
-                .collect::<Vec<_>>().join("`, `"));
-        err.span_label(impl_span, format!("missing `{}` in implementation",
-                missing_items.iter()
-                    .map(|trait_item| trait_item.ident.to_string())
-                    .collect::<Vec<_>>().join("`, `")));
-        for trait_item in missing_items {
-            if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
-                err.span_label(span, format!("`{}` from trait", trait_item.ident));
-            } else {
-                err.note_trait_signature(trait_item.ident.to_string(),
-                                         trait_item.signature(tcx));
-            }
-        }
-        err.emit();
+        missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
     }
 
     if !invalidated_items.is_empty() {
         let invalidator = overridden_associated_type.unwrap();
-        span_err!(tcx.sess, invalidator.span, E0399,
-                  "the following trait items need to be reimplemented \
-                   as `{}` was overridden: `{}`",
-                  invalidator.ident,
-                  invalidated_items.iter()
-                                   .map(|name| name.to_string())
-                                   .collect::<Vec<_>>().join("`, `"))
+        span_err!(
+            tcx.sess,
+            invalidator.span,
+            E0399,
+            "the following trait items need to be reimplemented as `{}` was overridden: `{}`",
+            invalidator.ident,
+            invalidated_items.iter()
+                .map(|name| name.to_string())
+                .collect::<Vec<_>>().join("`, `")
+        )
+    }
+}
+
+fn missing_items_err(
+    tcx: TyCtxt<'_>,
+    impl_span: Span,
+    missing_items: &[ty::AssocItem],
+    full_impl_span: Span,
+) {
+    let missing_items_msg = missing_items.iter()
+        .map(|trait_item| trait_item.ident.to_string())
+        .collect::<Vec<_>>().join("`, `");
+
+    let mut err = struct_span_err!(
+        tcx.sess,
+        impl_span,
+        E0046,
+        "not all trait items implemented, missing: `{}`",
+        missing_items_msg
+    );
+    err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
+
+    // `Span` before impl block closing brace.
+    let hi = full_impl_span.hi() - BytePos(1);
+    // Point at the place right before the closing brace of the relevant `impl` to suggest
+    // adding the associated item at the end of its body.
+    let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
+    // Obtain the level of indentation ending in `sugg_sp`.
+    let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
+    // Make the whitespace that will make the suggestion have the right indentation.
+    let padding: String = (0..indentation).map(|_| " ").collect();
+
+    for trait_item in missing_items {
+        let snippet = suggestion_signature(&trait_item, tcx);
+        let code = format!("{}{}\n{}", padding, snippet, padding);
+        let msg = format!("implement the missing item: `{}`", snippet);
+        let appl = Applicability::HasPlaceholders;
+        if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
+            err.span_label(span, format!("`{}` from trait", trait_item.ident));
+            err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
+        } else {
+            err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
+        }
+    }
+    err.emit();
+}
+
+/// Return placeholder code for the given function.
+fn fn_sig_suggestion(sig: &ty::FnSig<'_>, ident: Ident) -> String {
+    let args = sig.inputs()
+        .iter()
+        .map(|ty| Some(match ty.kind {
+            ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
+            ty::Ref(reg, ref_ty, mutability) => {
+                let reg = match &format!("{}", reg)[..] {
+                    "'_" | "" => String::new(),
+                    reg => format!("{} ", reg),
+                };
+                match ref_ty.kind {
+                    ty::Param(param) if param.name == kw::SelfUpper => {
+                        format!("&{}{}self", reg, mutability.prefix_str())
+                    }
+                    _ => format!("_: {:?}", ty),
+                }
+            }
+            _ => format!("_: {:?}", ty),
+        }))
+        .chain(std::iter::once(if sig.c_variadic {
+            Some("...".to_string())
+        } else {
+            None
+        }))
+        .filter_map(|arg| arg)
+        .collect::<Vec<String>>()
+        .join(", ");
+    let output = sig.output();
+    let output = if !output.is_unit() {
+        format!(" -> {:?}", output)
+    } else {
+        String::new()
+    };
+
+    let unsafety = sig.unsafety.prefix_str();
+    // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
+    // not be present in the `fn` definition, not will we account for renamed
+    // lifetimes between the `impl` and the `trait`, but this should be good enough to
+    // fill in a significant portion of the missing code, and other subsequent
+    // suggestions can help the user fix the code.
+    format!("{}fn {}({}){} {{ unimplemented!() }}", unsafety, ident, args, output)
+}
+
+/// Return placeholder code for the given associated item.
+/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
+/// structured suggestion.
+fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
+    match assoc.kind {
+        ty::AssocKind::Method => {
+            // We skip the binder here because the binder would deanonymize all
+            // late-bound regions, and we don't want method signatures to show up
+            // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
+            // regions just fine, showing `fn(&MyType)`.
+            fn_sig_suggestion(tcx.fn_sig(assoc.def_id).skip_binder(), assoc.ident)
+        }
+        ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
+        // FIXME(type_alias_impl_trait): we should print bounds here too.
+        ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
+        ty::AssocKind::Const => {
+            let ty = tcx.type_of(assoc.def_id);
+            let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
+            format!("const {}: {:?} = {};", assoc.ident, ty, val)
+        }
     }
 }
 
@@ -3105,8 +3197,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let mut adjustments = autoderef.adjust_steps(self, needs);
                 if let ty::Ref(region, _, r_mutbl) = method.sig.inputs()[0].kind {
                     let mutbl = match r_mutbl {
-                        hir::MutImmutable => AutoBorrowMutability::Immutable,
-                        hir::MutMutable => AutoBorrowMutability::Mutable {
+                        hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                        hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                             // Indexing can be desugared to a method call,
                             // so maybe we could use two-phase here.
                             // See the documentation of AllowTwoPhase for why that's
@@ -3665,8 +3757,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 });
                 opt_ty.unwrap_or_else(|| self.next_int_var())
             }
-            ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
-            ast::LitKind::FloatUnsuffixed(_) => {
+            ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
+            ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
                 let opt_ty = expected.to_option(self).and_then(|ty| {
                     match ty.kind {
                         ty::Float(_) => Some(ty),
@@ -4186,7 +4278,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
         match node {
             Node::Item(&hir::Item {
-                kind: hir::ItemKind::Fn(_, _, _, body_id), ..
+                kind: hir::ItemKind::Fn(_, _, body_id), ..
             }) |
             Node::ImplItem(&hir::ImplItem {
                 kind: hir::ImplItemKind::Method(_, body_id), ..
@@ -4211,23 +4303,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
         match node {
             Node::Item(&hir::Item {
-                ident, kind: hir::ItemKind::Fn(ref decl, ..), ..
+                ident, kind: hir::ItemKind::Fn(ref sig, ..), ..
             }) => {
                 // This is less than ideal, it will not suggest a return type span on any
                 // method called `main`, regardless of whether it is actually the entry point,
                 // but it will still present it as the reason for the expected type.
-                Some((decl, ident, ident.name != sym::main))
+                Some((&sig.decl, ident, ident.name != sym::main))
             }
             Node::TraitItem(&hir::TraitItem {
-                ident, kind: hir::TraitItemKind::Method(hir::MethodSig {
-                    ref decl, ..
-                }, ..), ..
-            }) => Some((decl, ident, true)),
+                ident, kind: hir::TraitItemKind::Method(ref sig, ..), ..
+            }) => Some((&sig.decl, ident, true)),
             Node::ImplItem(&hir::ImplItem {
-                ident, kind: hir::ImplItemKind::Method(hir::MethodSig {
-                    ref decl, ..
-                }, ..), ..
-            }) => Some((decl, ident, false)),
+                ident, kind: hir::ImplItemKind::Method(ref sig, ..), ..
+            }) => Some((&sig.decl, ident, false)),
             _ => None,
         }
     }
@@ -4250,7 +4338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// - Possible missing return type if the return type is the default, and not `fn main()`.
     pub fn suggest_mismatched_types_on_tail(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expr: &'tcx hir::Expr,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
@@ -4277,7 +4365,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// ```
     fn suggest_fn_call(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
@@ -4390,7 +4478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     pub fn suggest_ref_or_into(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
@@ -4458,7 +4546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// in the heap by calling `Box::new()`.
     fn suggest_boxing_when_appropriate(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
@@ -4502,7 +4590,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// it suggests adding a semicolon.
     fn suggest_missing_semicolon(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expression: &'tcx hir::Expr,
         expected: Ty<'tcx>,
         cause_span: Span,
@@ -4541,7 +4629,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// type.
     fn suggest_missing_return_type(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         fn_decl: &hir::FnDecl,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
@@ -4607,7 +4695,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// `.await` to the tail of the expression.
     fn suggest_missing_await(
         &self,
-        err: &mut DiagnosticBuilder<'tcx>,
+        err: &mut DiagnosticBuilder<'_>,
         expr: &hir::Expr,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
@@ -5167,5 +5255,5 @@ fn fatally_break_rust(sess: &Session) {
 }
 
 fn potentially_plural_count(count: usize, word: &str) -> String {
-    format!("{} {}{}", count, word, pluralise!(count))
+    format!("{} {}{}", count, word, pluralize!(count))
 }
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 819c347d3ae..81a31597905 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -204,8 +204,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if is_assign == IsAssign::Yes || by_ref_binop {
                     if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind {
                         let mutbl = match mutbl {
-                            hir::MutImmutable => AutoBorrowMutability::Immutable,
-                            hir::MutMutable => AutoBorrowMutability::Mutable {
+                            hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                            hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                                 // Allow two-phase borrows for binops in initial deployment
                                 // since they desugar to methods
                                 allow_two_phase_borrow: AllowTwoPhase::Yes,
@@ -221,8 +221,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if by_ref_binop {
                     if let ty::Ref(region, _, mutbl) = method.sig.inputs()[1].kind {
                         let mutbl = match mutbl {
-                            hir::MutImmutable => AutoBorrowMutability::Immutable,
-                            hir::MutMutable => AutoBorrowMutability::Mutable {
+                            hir::Mutability::Immutable => AutoBorrowMutability::Immutable,
+                            hir::Mutability::Mutable => AutoBorrowMutability::Mutable {
                                 // Allow two-phase borrows for binops in initial deployment
                                 // since they desugar to methods
                                 allow_two_phase_borrow: AllowTwoPhase::Yes,
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 950ae7c1d62..a4c9862bc74 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1,6 +1,6 @@
 use crate::check::FnCtxt;
 use crate::util::nodemap::FxHashMap;
-use errors::{Applicability, DiagnosticBuilder, pluralise};
+use errors::{Applicability, DiagnosticBuilder, pluralize};
 use rustc::hir::{self, PatKind, Pat, HirId};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -30,7 +30,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects";
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_pat_top(&self, pat: &'tcx Pat, expected: Ty<'tcx>, discrim_span: Option<Span>) {
-        let def_bm = BindingMode::BindByValue(hir::Mutability::MutImmutable);
+        let def_bm = BindingMode::BindByValue(hir::Mutability::Immutable);
         self.check_pat(pat, expected, def_bm, discrim_span);
     }
 
@@ -194,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             //
             // See issue #46688.
             let def_bm = match pat.kind {
-                PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
+                PatKind::Ref(..) => ty::BindByValue(hir::Mutability::Immutable),
                 _ => def_bm,
             };
             (expected, def_bm)
@@ -275,10 +275,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // (depending on whether we observe `&` or `&mut`).
                 ty::BindByValue(_) |
                 // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
-                ty::BindByReference(hir::Mutability::MutMutable) => inner_mutability,
+                ty::BindByReference(hir::Mutability::Mutable) => inner_mutability,
                 // Once a `ref`, always a `ref`.
                 // This is because a `& &mut` cannot mutate the underlying value.
-                ty::BindByReference(m @ hir::Mutability::MutImmutable) => m,
+                ty::BindByReference(m @ hir::Mutability::Immutable) => m,
             });
         }
 
@@ -703,8 +703,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fields: &[ty::FieldDef],
         expected: Ty<'tcx>
     ) {
-        let subpats_ending = pluralise!(subpats.len());
-        let fields_ending = pluralise!(fields.len());
+        let subpats_ending = pluralize!(subpats.len());
+        let fields_ending = pluralize!(fields.len());
         let res_span = self.tcx.def_span(res.def_id());
         let mut err = struct_span_err!(
             self.tcx.sess,
@@ -978,7 +978,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
 
                     // we don't want to throw `E0027` in case we have thrown `E0026` for them
-                    unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
+                    unmentioned_fields.retain(|&x| x.name != suggested_name);
                 }
             }
         }
@@ -1174,10 +1174,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0527,
             "pattern requires {} element{} but array has {}",
             min_len,
-            pluralise!(min_len),
+            pluralize!(min_len),
             size,
         )
-        .span_label(span, format!("expected {} element{}", size, pluralise!(size)))
+        .span_label(span, format!("expected {} element{}", size, pluralize!(size)))
         .emit();
     }
 
@@ -1188,14 +1188,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0528,
             "pattern requires at least {} element{} but array has {}",
             min_len,
-            pluralise!(min_len),
+            pluralize!(min_len),
             size,
         ).span_label(
             span,
             format!(
                 "pattern cannot match array of {} element{}",
                 size,
-                pluralise!(size),
+                pluralize!(size),
             ),
         ).emit();
     }
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index 97e59664df0..390ee0d0f83 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -81,7 +81,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         closure_hir_id: hir::HirId,
         span: Span,
         body: &hir::Body,
-        capture_clause: hir::CaptureClause,
+        capture_clause: hir::CaptureBy,
     ) {
         /*!
          * Analysis starting point.
@@ -141,8 +141,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 upvar_list.insert(var_hir_id, upvar_id);
 
                 let capture_kind = match capture_clause {
-                    hir::CaptureByValue => ty::UpvarCapture::ByValue,
-                    hir::CaptureByRef => {
+                    hir::CaptureBy::Value => ty::UpvarCapture::ByValue,
+                    hir::CaptureBy::Ref => {
                         let origin = UpvarRegion(upvar_id, span);
                         let upvar_region = self.next_region_var(origin);
                         let upvar_borrow = ty::UpvarBorrow {
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 49b33ad4668..5b25d8f25a9 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -190,7 +190,7 @@ fn check_associated_item(
     tcx: TyCtxt<'_>,
     item_id: hir::HirId,
     span: Span,
-    sig_if_method: Option<&hir::MethodSig>,
+    sig_if_method: Option<&hir::FnSig>,
 ) {
     debug!("check_associated_item: {:?}", item_id);
 
@@ -783,7 +783,7 @@ const HELP_FOR_SELF_TYPE: &str =
 
 fn check_method_receiver<'fcx, 'tcx>(
     fcx: &FnCtxt<'fcx, 'tcx>,
-    method_sig: &hir::MethodSig,
+    fn_sig: &hir::FnSig,
     method: &ty::AssocItem,
     self_ty: Ty<'tcx>,
 ) {
@@ -794,7 +794,7 @@ fn check_method_receiver<'fcx, 'tcx>(
         return;
     }
 
-    let span = method_sig.decl.inputs[0].span;
+    let span = fn_sig.decl.inputs[0].span;
 
     let sig = fcx.tcx.fn_sig(method.def_id);
     let sig = fcx.normalize_associated_types_in(span, &sig);
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 1e3939cbfcd..d613abc4352 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -358,7 +358,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
         let check_mutbl = |mt_a: ty::TypeAndMut<'tcx>,
                            mt_b: ty::TypeAndMut<'tcx>,
                            mk_ptr: &dyn Fn(Ty<'tcx>) -> Ty<'tcx>| {
-            if (mt_a.mutbl, mt_b.mutbl) == (hir::MutImmutable, hir::MutMutable) {
+            if (mt_a.mutbl, mt_b.mutbl) == (hir::Mutability::Immutable, hir::Mutability::Mutable) {
                 infcx.report_mismatched_types(&cause,
                                               mk_ptr(mt_b.ty),
                                               target,
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index 90cedb455e3..5daa8f5d319 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -107,7 +107,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
                                           "[T]",
                                           item.span);
             }
-            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
+            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Immutable }) => {
                 self.check_primitive_impl(def_id,
                                           lang_items.const_ptr_impl(),
                                           None,
@@ -115,7 +115,7 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
                                           "*const T",
                                           item.span);
             }
-            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
+            ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Mutable }) => {
                 self.check_primitive_impl(def_id,
                                           lang_items.mut_ptr_impl(),
                                           None,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 7ef842cb757..9c1da65c846 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -885,8 +885,8 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
             _ => None,
         },
         Node::Item(item) => match item.kind {
-            hir::ItemKind::Fn(ref fn_decl, .., ref generics, _) => {
-                has_late_bound_regions(tcx, generics, fn_decl)
+            hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
+                has_late_bound_regions(tcx, generics, &sig.decl)
             }
             _ => None,
         },
@@ -1146,10 +1146,6 @@ fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) {
     );
 }
 
-fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
-    checked_type_of(tcx, def_id, true).unwrap()
-}
-
 fn infer_placeholder_type(
     tcx: TyCtxt<'_>,
     def_id: DefId,
@@ -1193,26 +1189,14 @@ fn infer_placeholder_type(
     ty
 }
 
-/// Same as [`type_of`] but returns [`Option`] instead of failing.
-///
-/// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
-/// you'd better just call [`type_of`] directly.
-pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<'_>> {
+fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     use rustc::hir::*;
 
-    let hir_id = match tcx.hir().as_local_hir_id(def_id) {
-        Some(hir_id) => hir_id,
-        None => {
-            if !fail {
-                return None;
-            }
-            bug!("invalid node");
-        }
-    };
+    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
 
     let icx = ItemCtxt::new(tcx, def_id);
 
-    Some(match tcx.hir().get(hir_id) {
+    match tcx.hir().get(hir_id) {
         Node::TraitItem(item) => match item.kind {
             TraitItemKind::Method(..) => {
                 let substs = InternalSubsts::identity_for_item(tcx, def_id);
@@ -1229,9 +1213,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
             },
             TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
             TraitItemKind::Type(_, None) => {
-                if !fail {
-                    return None;
-                }
                 span_bug!(item.span, "associated type missing default");
             }
         },
@@ -1325,9 +1306,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                 | ItemKind::GlobalAsm(..)
                 | ItemKind::ExternCrate(..)
                 | ItemKind::Use(..) => {
-                    if !fail {
-                        return None;
-                    }
                     span_bug!(
                         item.span,
                         "compute_type_of_item: unexpected item type: {:?}",
@@ -1365,7 +1343,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
             ..
         }) => {
             if gen.is_some() {
-                return Some(tcx.typeck_tables_of(def_id).node_type(hir_id));
+                return tcx.typeck_tables_of(def_id).node_type(hir_id);
             }
 
             let substs = InternalSubsts::identity_for_item(tcx, def_id);
@@ -1440,13 +1418,9 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                     .map(|(index, _)| index)
                                     .next()
                             })
-                            .or_else(|| {
-                                if !fail {
-                                    None
-                                } else {
-                                    bug!("no arg matching AnonConst in path")
-                                }
-                            })?;
+                            .unwrap_or_else(|| {
+                                bug!("no arg matching AnonConst in path");
+                            });
 
                         // We've encountered an `AnonConst` in some path, so we need to
                         // figure out which generic parameter it corresponds to and return
@@ -1456,8 +1430,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                 tcx.generics_of(tcx.parent(def_id).unwrap())
                             }
                             Res::Def(_, def_id) => tcx.generics_of(def_id),
-                            Res::Err => return Some(tcx.types.err),
-                            _ if !fail => return None,
+                            Res::Err => return tcx.types.err,
                             res => {
                                 tcx.sess.delay_span_bug(
                                     DUMMY_SP,
@@ -1466,7 +1439,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                         res,
                                     ),
                                 );
-                                return Some(tcx.types.err);
+                                return tcx.types.err;
                             }
                         };
 
@@ -1484,9 +1457,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                             // probably from an extra arg where one is not needed.
                             .unwrap_or(tcx.types.err)
                     } else {
-                        if !fail {
-                            return None;
-                        }
                         tcx.sess.delay_span_bug(
                             DUMMY_SP,
                             &format!(
@@ -1494,14 +1464,11 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                 parent_node,
                             ),
                         );
-                        return Some(tcx.types.err);
+                        return tcx.types.err;
                     }
                 }
 
                 x => {
-                    if !fail {
-                        return None;
-                    }
                     tcx.sess.delay_span_bug(
                         DUMMY_SP,
                         &format!(
@@ -1551,21 +1518,13 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                 }
                 ty
             }
-            x => {
-                if !fail {
-                    return None;
-                }
-                bug!("unexpected non-type Node::GenericParam: {:?}", x)
-            },
+            x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
         },
 
         x => {
-            if !fail {
-                return None;
-            }
             bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
         }
-    })
+    }
 }
 
 fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
@@ -1820,17 +1779,17 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
 
     match tcx.hir().get(hir_id) {
         TraitItem(hir::TraitItem {
-            kind: TraitItemKind::Method(MethodSig { header, decl }, TraitMethod::Provided(_)),
+            kind: TraitItemKind::Method(sig, TraitMethod::Provided(_)),
             ..
         })
         | ImplItem(hir::ImplItem {
-            kind: ImplItemKind::Method(MethodSig { header, decl }, _),
+            kind: ImplItemKind::Method(sig, _),
             ..
         })
         | Item(hir::Item {
-            kind: ItemKind::Fn(decl, header, _, _),
+            kind: ItemKind::Fn(sig, _, _),
             ..
-        }) => match get_infer_ret_ty(&decl.output) {
+        }) => match get_infer_ret_ty(&sig.decl.output) {
             Some(ty) => {
                 let fn_sig = tcx.typeck_tables_of(def_id).liberated_fn_sigs()[hir_id];
                 let mut diag = bad_placeholder_type(tcx, ty.span);
@@ -1846,11 +1805,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
                 diag.emit();
                 ty::Binder::bind(fn_sig)
             },
-            None => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl)
+            None => AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl)
         },
 
         TraitItem(hir::TraitItem {
-            kind: TraitItemKind::Method(MethodSig { header, decl }, _),
+            kind: TraitItemKind::Method(FnSig { header, decl }, _),
             ..
         }) => {
             AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl)
@@ -2075,10 +2034,7 @@ fn explicit_predicates_of(
         }
     }
 
-    let hir_id = match tcx.hir().as_local_hir_id(def_id) {
-        Some(hir_id) => hir_id,
-        None => return tcx.predicates_of(def_id),
-    };
+    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let node = tcx.hir().get(hir_id);
 
     let mut is_trait = None;
@@ -2408,7 +2364,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        intrinsic_operation_unsafety(&*tcx.item_name(def_id).as_str())
+        intrinsic_operation_unsafety(&tcx.item_name(def_id).as_str())
     } else {
         hir::Unsafety::Unsafe
     };
@@ -2706,7 +2662,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
     }
 
     codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
-        if attr.path != sym::inline {
+        if !attr.has_name(sym::inline) {
             return ia;
         }
         match attr.meta().map(|i| i.kind) {
@@ -2746,7 +2702,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
     });
 
     codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
-        if attr.path != sym::optimize {
+        if !attr.has_name(sym::optimize) {
             return ia;
         }
         let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s);
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index f21fc2df8b9..560abeb7057 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -3,9 +3,9 @@
 syntax::register_diagnostics! {
 
 E0023: r##"
-A pattern used to match against an enum variant must provide a sub-pattern for
-each field of the enum variant. This error indicates that a pattern attempted to
-extract an incorrect number of fields from a variant.
+A pattern attempted to extract an incorrect number of fields from a variant.
+
+Erroneous code example:
 
 ```
 enum Fruit {
@@ -14,6 +14,9 @@ enum Fruit {
 }
 ```
 
+A pattern used to match against an enum variant must provide a sub-pattern for
+each field of the enum variant.
+
 Here the `Apple` variant has two fields, and should be matched against like so:
 
 ```
@@ -53,8 +56,9 @@ uses the same number.
 "##,
 
 E0025: r##"
-Each field of a struct can only be bound once in a pattern. Erroneous code
-example:
+Each field of a struct can only be bound once in a pattern.
+
+Erroneous code example:
 
 ```compile_fail,E0025
 struct Foo {
@@ -89,65 +93,47 @@ fn main(){
 "##,
 
 E0026: r##"
-This error indicates that a struct pattern attempted to extract a non-existent
-field from a struct. Struct fields are identified by the name used before the
-colon `:` so struct patterns should resemble the declaration of the struct type
-being matched.
-
-```
-// Correct matching.
-struct Thing {
-    x: u32,
-    y: u32
-}
-
-let thing = Thing { x: 1, y: 2 };
+A struct pattern attempted to extract a non-existent field from a struct.
 
-match thing {
-    Thing { x: xfield, y: yfield } => {}
-}
-```
-
-If you are using shorthand field patterns but want to refer to the struct field
-by a different name, you should rename it explicitly.
-
-Change this:
+Erroneous code example:
 
 ```compile_fail,E0026
 struct Thing {
     x: u32,
-    y: u32
+    y: u32,
 }
 
 let thing = Thing { x: 0, y: 0 };
 
 match thing {
-    Thing { x, z } => {}
+    Thing { x, z } => {} // error: `Thing::z` field doesn't exist
 }
 ```
 
-To this:
+If you are using shorthand field patterns but want to refer to the struct field
+by a different name, you should rename it explicitly. Struct fields are
+identified by the name used before the colon `:` so struct patterns should
+resemble the declaration of the struct type being matched.
 
 ```
 struct Thing {
     x: u32,
-    y: u32
+    y: u32,
 }
 
 let thing = Thing { x: 0, y: 0 };
 
 match thing {
-    Thing { x, y: z } => {}
+    Thing { x, y: z } => {} // we renamed `y` to `z`
 }
 ```
 "##,
 
 E0027: r##"
-This error indicates that a pattern for a struct fails to specify a sub-pattern
-for every one of the struct's fields. Ensure that each field from the struct's
-definition is mentioned in the pattern, or use `..` to ignore unwanted fields.
+A pattern for a struct fails to specify a sub-pattern for every one of the
+struct's fields.
 
-For example:
+Erroneous code example:
 
 ```compile_fail,E0027
 struct Dog {
@@ -163,7 +149,8 @@ match d {
 }
 ```
 
-This is correct (explicit):
+To fix this error, ensure that each field from the struct's definition is
+mentioned in the pattern, or use `..` to ignore unwanted fields. Example:
 
 ```
 struct Dog {
@@ -185,11 +172,9 @@ match d {
 "##,
 
 E0029: r##"
-In a match expression, only numbers and characters can be matched against a
-range. This is because the compiler checks that the range is non-empty at
-compile-time, and is unable to evaluate arbitrary comparison functions. If you
-want to capture values of an orderable type between two end-points, you can use
-a guard.
+Something other than numbers and characters has been used for a range.
+
+Erroneous code example:
 
 ```compile_fail,E0029
 let string = "salutations !";
@@ -207,14 +192,18 @@ match string {
     _ => {}
 }
 ```
+
+In a match expression, only numbers and characters can be matched against a
+range. This is because the compiler checks that the range is non-empty at
+compile-time, and is unable to evaluate arbitrary comparison functions. If you
+want to capture values of an orderable type between two end-points, you can use
+a guard.
 "##,
 
 E0033: r##"
-This error indicates that a pointer to a trait type cannot be implicitly
-dereferenced by a pattern. Every trait defines a type, but because the
-size of trait implementers isn't fixed, this type has no compile-time size.
-Therefore, all accesses to trait types must be through pointers. If you
-encounter this error you should try to avoid dereferencing the pointer.
+A trait type has been dereferenced.
+
+Erroneous code example:
 
 ```compile_fail,E0033
 # trait SomeTrait { fn method_one(&self){} fn method_two(&self){} }
@@ -229,6 +218,12 @@ trait_obj.method_one();
 trait_obj.method_two();
 ```
 
+A pointer to a trait type cannot be implicitly dereferenced by a pattern. Every
+trait defines a type, but because the size of trait implementers isn't fixed,
+this type has no compile-time size. Therefore, all accesses to trait types must
+be through pointers. If you encounter this error you should try to avoid
+dereferencing the pointer.
+
 You can read more about trait objects in the [Trait Objects] section of the
 Reference.
 
@@ -237,7 +232,9 @@ Reference.
 
 E0034: r##"
 The compiler doesn't know what method to call because more than one method
-has the same prototype. Erroneous code example:
+has the same prototype.
+
+Erroneous code example:
 
 ```compile_fail,E0034
 struct Test;
@@ -323,11 +320,9 @@ fn main() {
 "##,
 
 E0040: r##"
-It is not allowed to manually call destructors in Rust. It is also not
-necessary to do this since `drop` is called automatically whenever a value goes
-out of scope.
+It is not allowed to manually call destructors in Rust.
 
-Here's an example of this error:
+Erroneous code example:
 
 ```compile_fail,E0040
 struct Foo {
@@ -345,11 +340,33 @@ fn main() {
     x.drop(); // error: explicit use of destructor method
 }
 ```
+
+It is unnecessary to do this since `drop` is called automatically whenever a
+value goes out of scope. However, if you really need to drop a value by hand,
+you can use the `std::mem::drop` function:
+
+```
+struct Foo {
+    x: i32,
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        println!("kaboom");
+    }
+}
+
+fn main() {
+    let mut x = Foo { x: -7 };
+    drop(x); // ok!
+}
+```
 "##,
 
 E0044: r##"
 You cannot use type or const parameters on foreign items.
-Example of erroneous code:
+
+Erroneous code example:
 
 ```compile_fail,E0044
 extern { fn some_func<T>(x: T); }
@@ -365,21 +382,21 @@ extern { fn some_func_i64(x: i64); }
 "##,
 
 E0045: r##"
-Rust only supports variadic parameters for interoperability with C code in its
-FFI. As such, variadic parameters can only be used with functions which are
-using the C ABI. Examples of erroneous code:
+Variadic parameters have been used on a non-C ABI function.
 
-```compile_fail
-#![feature(unboxed_closures)]
-
-extern "rust-call" { fn foo(x: u8, ...); }
+Erroneous code example:
 
-// or
+```compile_fail,E0045
+#![feature(unboxed_closures)]
 
-fn foo(x: u8, ...) {}
+extern "rust-call" {
+    fn foo(x: u8, ...); // error!
+}
 ```
 
-To fix such code, put them in an extern "C" block:
+Rust only supports variadic parameters for interoperability with C code in its
+FFI. As such, variadic parameters can only be used with functions which are
+using the C ABI. To fix such code, put them in an extern "C" block:
 
 ```
 extern "C" {
@@ -389,7 +406,9 @@ extern "C" {
 "##,
 
 E0046: r##"
-Items are missing in a trait implementation. Erroneous code example:
+Items are missing in a trait implementation.
+
+Erroneous code example:
 
 ```compile_fail,E0046
 trait Foo {
@@ -421,11 +440,10 @@ impl Foo for Bar {
 "##,
 
 E0049: r##"
-This error indicates that an attempted implementation of a trait method
-has the wrong number of type or const parameters.
+An attempted implementation of a trait method has the wrong number of type or
+const parameters.
 
-For example, the trait below has a method `foo` with a type parameter `T`,
-but the implementation of `foo` for the type `Bar` is missing this parameter:
+Erroneous code example:
 
 ```compile_fail,E0049
 trait Foo {
@@ -440,15 +458,31 @@ impl Foo for Bar {
     fn foo(x: bool) -> Self { Bar }
 }
 ```
+
+For example, the `Foo` trait has a method `foo` with a type parameter `T`,
+but the implementation of `foo` for the type `Bar` is missing this parameter.
+To fix this error, they must have the same type parameters:
+
+```
+trait Foo {
+    fn foo<T: Default>(x: T) -> Self;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn foo<T: Default>(x: T) -> Self { // ok!
+        Bar
+    }
+}
+```
 "##,
 
 E0050: r##"
-This error indicates that an attempted implementation of a trait method
-has the wrong number of function parameters.
+An attempted implementation of a trait method has the wrong number of function
+parameters.
 
-For example, the trait below has a method `foo` with two function parameters
-(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits
-the `u8` parameter:
+Erroneous code example:
 
 ```compile_fail,E0050
 trait Foo {
@@ -463,13 +497,31 @@ impl Foo for Bar {
     fn foo(&self) -> bool { true }
 }
 ```
+
+For example, the `Foo` trait has a method `foo` with two function parameters
+(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits
+the `u8` parameter. To fix this error, they must have the same parameters:
+
+```
+trait Foo {
+    fn foo(&self, x: u8) -> bool;
+}
+
+struct Bar;
+
+impl Foo for Bar {
+    fn foo(&self, x: u8) -> bool { // ok!
+        true
+    }
+}
+```
 "##,
 
 E0053: r##"
 The parameters of any trait method must match between a trait implementation
 and the trait definition.
 
-Here are a couple examples of this error:
+Erroneous code example:
 
 ```compile_fail,E0053
 trait Foo {
@@ -490,8 +542,9 @@ impl Foo for Bar {
 "##,
 
 E0054: r##"
-It is not allowed to cast to a bool. If you are trying to cast a numeric type
-to a bool, you can compare it with zero instead:
+It is not allowed to cast to a bool.
+
+Erroneous code example:
 
 ```compile_fail,E0054
 let x = 5;
@@ -500,6 +553,9 @@ let x = 5;
 let x_is_nonzero = x as bool;
 ```
 
+If you are trying to cast a numeric type to a bool, you can compare it with
+zero instead:
+
 ```
 let x = 5;
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9374113e1c9..a5a4cfa2bab 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -109,8 +109,6 @@ use util::common::time;
 use std::iter;
 
 use astconv::{AstConv, Bounds};
-pub use collect::checked_type_of;
-
 pub struct TypeAndSubsts<'tcx> {
     substs: SubstsRef<'tcx>,
     ty: Ty<'tcx>,
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 4431abdaf50..1e1be72221f 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -454,12 +454,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                                mt: &ty::TypeAndMut<'tcx>,
                                variance: VarianceTermPtr<'a>) {
         match mt.mutbl {
-            hir::MutMutable => {
+            hir::Mutability::Mutable => {
                 let invar = self.invariant(variance);
                 self.add_constraints_from_ty(current, mt.ty, invar);
             }
 
-            hir::MutImmutable => {
+            hir::Mutability::Immutable => {
                 self.add_constraints_from_ty(current, mt.ty, variance);
             }
         }
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 11f45c5f6d0..09f4873967e 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -404,7 +404,7 @@ impl<'a> fmt::Display for Html<'a> {
                 if !human_readable.is_empty() {
                     fmt.write_str(human_readable)
                 } else if let Some(v) = value {
-                    write!(fmt, "<code>{}=\"{}\"</code>", Escape(n), Escape(&*v.as_str()))
+                    write!(fmt, "<code>{}=\"{}\"</code>", Escape(n), Escape(&v.as_str()))
                 } else {
                     write!(fmt, "<code>{}</code>", Escape(n))
                 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bdc02062230..3d42d5bb0ca 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -26,9 +26,9 @@ use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
 use rustc::ty::fold::TypeFolder;
 use rustc::ty::layout::VariantIdx;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use syntax::ast::{self, Attribute, AttrStyle, AttrItem, Ident};
+use syntax::ast::{self, Attribute, AttrStyle, AttrKind, Ident};
 use syntax::attr;
-use syntax::parse::lexer::comments;
+use syntax::util::comments;
 use syntax::source_map::DUMMY_SP;
 use syntax_pos::symbol::{Symbol, kw, sym};
 use syntax_pos::hygiene::MacroKind;
@@ -39,6 +39,7 @@ use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::default::Default;
 use std::{mem, slice, vec};
+use std::num::NonZeroU32;
 use std::iter::FromIterator;
 use std::rc::Rc;
 use std::cell::RefCell;
@@ -859,31 +860,32 @@ impl Attributes {
         let mut cfg = Cfg::True;
         let mut doc_line = 0;
 
-        /// Converts `attr` to a normal `#[doc="foo"]` comment, if it is a
-        /// comment like `///` or `/** */`. (Returns `attr` unchanged for
-        /// non-sugared doc attributes.)
-        pub fn with_desugared_doc<T>(attr: &Attribute, f: impl FnOnce(&Attribute) -> T) -> T {
-            if attr.is_sugared_doc {
-                let comment = attr.value_str().unwrap();
-                let meta = attr::mk_name_value_item_str(
-                    Ident::with_dummy_span(sym::doc),
-                    Symbol::intern(&comments::strip_doc_comment_decoration(&comment.as_str())),
-                    DUMMY_SP,
-                );
-                f(&Attribute {
-                    item: AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) },
-                    id: attr.id,
-                    style: attr.style,
-                    is_sugared_doc: true,
-                    span: attr.span,
-                })
-            } else {
-                f(attr)
+        /// If `attr` is a doc comment, strips the leading and (if present)
+        /// trailing comments symbols, e.g. `///`, `/**`, and `*/`. Otherwise,
+        /// returns `attr` unchanged.
+        pub fn with_doc_comment_markers_stripped<T>(
+            attr: &Attribute,
+            f: impl FnOnce(&Attribute) -> T
+        ) -> T {
+            match attr.kind {
+                AttrKind::Normal(_) => {
+                    f(attr)
+                }
+                AttrKind::DocComment(comment) => {
+                    let comment =
+                        Symbol::intern(&comments::strip_doc_comment_decoration(&comment.as_str()));
+                    f(&Attribute {
+                        kind: AttrKind::DocComment(comment),
+                        id: attr.id,
+                        style: attr.style,
+                        span: attr.span,
+                    })
+                }
             }
         }
 
         let other_attrs = attrs.iter().filter_map(|attr| {
-            with_desugared_doc(attr, |attr| {
+            with_doc_comment_markers_stripped(attr, |attr| {
                 if attr.check_name(sym::doc) {
                     if let Some(mi) = attr.meta() {
                         if let Some(value) = mi.value_str() {
@@ -892,7 +894,7 @@ impl Attributes {
                             let line = doc_line;
                             doc_line += value.lines().count();
 
-                            if attr.is_sugared_doc {
+                            if attr.is_doc_comment() {
                                 doc_strings.push(DocFragment::SugaredDoc(line, attr.span, value));
                             } else {
                                 doc_strings.push(DocFragment::RawDoc(line, attr.span, value));
@@ -1167,7 +1169,7 @@ fn external_path(cx: &DocContext<'_>, name: Symbol, trait_did: Option<DefId>, ha
         global: false,
         res: Res::Err,
         segments: vec![PathSegment {
-            name: name.as_str().to_string(),
+            name: name.to_string(),
             args: external_generic_args(cx, trait_did, has_self, bindings, substs)
         }],
     }
@@ -1491,12 +1493,13 @@ impl GenericParamDefKind {
         }
     }
 
-    pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> {
-        match *self {
-            GenericParamDefKind::Type { did, .. } => {
-                rustc_typeck::checked_type_of(cx.tcx, did, false).map(|t| t.clean(cx))
-            }
-            GenericParamDefKind::Const { ref ty, .. } => Some(ty.clone()),
+    // FIXME(eddyb) this either returns the default of a type parameter, or the
+    // type of a `const` parameter. It seems that the intention is to *visit*
+    // any embedded types, but `get_type` seems to be the wrong name for that.
+    pub fn get_type(&self) -> Option<Type> {
+        match self {
+            GenericParamDefKind::Type { default, .. } => default.clone(),
+            GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
             GenericParamDefKind::Lifetime => None,
         }
     }
@@ -1522,8 +1525,8 @@ impl GenericParamDef {
         self.kind.is_type()
     }
 
-    pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> {
-        self.kind.get_type(cx)
+    pub fn get_type(&self) -> Option<Type> {
+        self.kind.get_type()
     }
 
     pub fn get_bounds(&self) -> Option<&[GenericBound]> {
@@ -1891,7 +1894,7 @@ fn get_real_types(
                             if !x.is_type() {
                                 continue
                             }
-                            if let Some(ty) = x.get_type(cx) {
+                            if let Some(ty) = x.get_type() {
                                 let adds = get_real_types(generics, &ty, cx, recurse + 1);
                                 if !adds.is_empty() {
                                     res.extend(adds);
@@ -1982,7 +1985,7 @@ pub struct Method {
     pub ret_types: Vec<Type>,
 }
 
-impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId,
+impl<'a> Clean<Method> for (&'a hir::FnSig, &'a hir::Generics, hir::BodyId,
                             Option<hir::Defaultness>) {
     fn clean(&self, cx: &DocContext<'_>) -> Method {
         let (generics, decl) = enter_impl_trait(cx, || {
@@ -3704,7 +3707,7 @@ fn qpath_to_string(p: &hir::QPath) -> String {
             s.push_str("::");
         }
         if seg.ident.name != kw::PathRoot {
-            s.push_str(&*seg.ident.as_str());
+            s.push_str(&seg.ident.as_str());
         }
     }
     s
@@ -3857,8 +3860,8 @@ pub enum Mutability {
 impl Clean<Mutability> for hir::Mutability {
     fn clean(&self, _: &DocContext<'_>) -> Mutability {
         match self {
-            &hir::MutMutable => Mutable,
-            &hir::MutImmutable => Immutable,
+            &hir::Mutability::Mutable => Mutable,
+            &hir::Mutability::Immutable => Immutable,
         }
     }
 }
@@ -4397,7 +4400,7 @@ pub struct Stability {
     pub since: String,
     pub deprecation: Option<Deprecation>,
     pub unstable_reason: Option<String>,
-    pub issue: Option<u32>,
+    pub issue: Option<NonZeroU32>,
 }
 
 #[derive(Clone, Debug)]
@@ -4426,7 +4429,7 @@ impl Clean<Stability> for attr::Stability {
                 _ => None,
             },
             issue: match self.level {
-                attr::Unstable {issue, ..} => Some(issue),
+                attr::Unstable {issue, ..} => issue,
                 _ => None,
             }
         }
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 0b8d4d6c302..255d5f9f35d 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -615,10 +615,6 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
         let mut parts = arg.splitn(2, '=');
         let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
         let location = parts.next().map(|s| s.to_string());
-        if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
-            return Err("the `-Z unstable-options` flag must also be passed to \
-                        enable `--extern crate_name` without `=path`".to_string());
-        }
         let name = name.to_string();
         // For Rustdoc purposes, we can treat all externs as public
         externs.entry(name)
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 30c9453a643..bf4a1440e1b 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -11,11 +11,12 @@ use std::fmt::Display;
 use std::io;
 use std::io::prelude::*;
 
-use syntax::source_map::{SourceMap, FilePathMapping};
-use syntax::parse::lexer;
-use syntax::parse::token::{self, Token};
+use rustc_parse::lexer;
+use syntax::token::{self, Token};
 use syntax::sess::ParseSess;
+use syntax::source_map::SourceMap;
 use syntax::symbol::{kw, sym};
+use syntax_expand::config::process_configure_mod;
 use syntax_pos::{Span, FileName};
 
 /// Highlights `src`, returning the HTML output.
@@ -33,7 +34,7 @@ pub fn render_with_highlighting(
                class, tooltip).unwrap();
     }
 
-    let sess = ParseSess::new(FilePathMapping::empty());
+    let sess = ParseSess::with_silent_emitter(process_configure_mod);
     let fm = sess.source_map().new_source_file(
         FileName::Custom(String::from("rustdoc-highlighting")),
         src.to_owned(),
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c4ee84d33f3..9a87bcc10db 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1230,18 +1230,87 @@ impl AllTypes {
     }
 }
 
+#[derive(Debug)]
+enum Setting {
+    Section {
+        description: &'static str,
+        sub_settings: Vec<Setting>,
+    },
+    Entry {
+        js_data_name: &'static str,
+        description: &'static str,
+        default_value: bool,
+    }
+}
+
+impl Setting {
+    fn display(&self) -> String {
+        match *self {
+            Setting::Section { ref description, ref sub_settings } => {
+                format!(
+                    "<div class='setting-line'>\
+                        <div class='title'>{}</div>\
+                        <div class='sub-settings'>{}</div>
+                    </div>",
+                    description,
+                    sub_settings.iter().map(|s| s.display()).collect::<String>()
+                )
+            }
+            Setting::Entry { ref js_data_name, ref description, ref default_value } => {
+                format!(
+                    "<div class='setting-line'>\
+                        <label class='toggle'>\
+                        <input type='checkbox' id='{}' {}>\
+                        <span class='slider'></span>\
+                        </label>\
+                        <div>{}</div>\
+                    </div>",
+                    js_data_name,
+                    if *default_value { " checked" } else { "" },
+                    description,
+                )
+            }
+        }
+    }
+}
+
+impl From<(&'static str, &'static str, bool)> for Setting {
+    fn from(values: (&'static str, &'static str, bool)) -> Setting {
+        Setting::Entry {
+            js_data_name: values.0,
+            description: values.1,
+            default_value: values.2,
+        }
+    }
+}
+
+impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
+    fn from(values: (&'static str, Vec<T>)) -> Setting {
+        Setting::Section {
+            description: values.0,
+            sub_settings: values.1.into_iter().map(|v| v.into()).collect::<Vec<_>>(),
+        }
+    }
+}
+
 fn settings(root_path: &str, suffix: &str) -> String {
     // (id, explanation, default value)
-    let settings = [
-        ("item-declarations", "Auto-hide item declarations.", true),
-        ("item-attributes", "Auto-hide item attributes.", true),
-        ("trait-implementations", "Auto-hide trait implementations documentation",
-            true),
-        ("method-docs", "Auto-hide item methods' documentation", false),
+    let settings: &[Setting] = &[
+        ("Auto-hide item declarations", vec![
+            ("auto-hide-struct", "Auto-hide structs declaration", true),
+            ("auto-hide-enum", "Auto-hide enums declaration", false),
+            ("auto-hide-union", "Auto-hide unions declaration", true),
+            ("auto-hide-trait", "Auto-hide traits declaration", true),
+            ("auto-hide-macro", "Auto-hide macros declaration", false),
+        ]).into(),
+        ("auto-hide-attributes", "Auto-hide item attributes.", true).into(),
+        ("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
+        ("auto-hide-trait-implementations", "Auto-hide trait implementations documentation",
+            true).into(),
         ("go-to-only-result", "Directly go to item in search if there is only one result",
-            false),
-        ("line-numbers", "Show line numbers on code examples", false),
-        ("disable-shortcuts", "Disable keyboard shortcuts", false),
+            false).into(),
+        ("line-numbers", "Show line numbers on code examples", false).into(),
+        ("disable-shortcuts", "Disable keyboard shortcuts", false).into(),
     ];
     format!(
 "<h1 class='fqn'>\
@@ -1249,17 +1318,7 @@ fn settings(root_path: &str, suffix: &str) -> String {
 </h1>\
 <div class='settings'>{}</div>\
 <script src='{}settings{}.js'></script>",
-            settings.iter()
-                        .map(|(id, text, enabled)| {
-                            format!("<div class='setting-line'>\
-                                            <label class='toggle'>\
-                                            <input type='checkbox' id='{}' {}>\
-                                            <span class='slider'></span>\
-                                            </label>\
-                                            <div>{}</div>\
-                                        </div>", id, if *enabled { " checked" } else { "" }, text)
-                        })
-                        .collect::<String>(),
+            settings.iter().map(|s| s.display()).collect::<String>(),
             root_path,
             suffix)
 }
@@ -2964,7 +3023,7 @@ fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
     if attr.is_word() {
         Some(path)
     } else if let Some(v) = attr.value_str() {
-        Some(format!("{} = {:?}", path, v.as_str()))
+        Some(format!("{} = {:?}", path, v))
     } else if let Some(values) = attr.meta_item_list() {
         let display: Vec<_> = values.iter().filter_map(|attr| {
             attr.meta_item().and_then(|mi| render_attribute(mi))
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index de19ca3ed33..04c0a0f005b 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -3,7 +3,7 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass */
-/* global isHidden, onEach, removeClass, updateLocalStorage */
+/* global onEach, removeClass, updateLocalStorage */
 
 if (!String.prototype.startsWith) {
     String.prototype.startsWith = function(searchString, position) {
@@ -161,61 +161,113 @@ function getSearchElement() {
         return window.history && typeof window.history.pushState === "function";
     }
 
+    function isHidden(elem) {
+        return elem.offsetHeight === 0;
+    }
+
     var main = document.getElementById("main");
+    var savedHash = "";
 
-    function highlightSourceLines(ev) {
-        // If we're in mobile mode, we should add the sidebar in any case.
-        hideSidebar();
-        var elem;
+    function handleHashes(ev) {
         var search = getSearchElement();
-        var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
-        if (match) {
-            from = parseInt(match[1], 10);
-            to = from;
-            if (typeof match[2] !== "undefined") {
-                to = parseInt(match[2], 10);
+        if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
+            // This block occurs when clicking on an element in the navbar while
+            // in a search.
+            addClass(search, "hidden");
+            removeClass(main, "hidden");
+            var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
+            if (browserSupportsHistoryApi()) {
+                history.replaceState(hash, "", "?search=#" + hash);
             }
-            if (to < from) {
-                var tmp = to;
-                to = from;
-                from = tmp;
+            var elem = document.getElementById(hash);
+            if (elem) {
+                elem.scrollIntoView();
             }
-            elem = document.getElementById(from);
-            if (!elem) {
+        }
+        // This part is used in case an element is not visible.
+        if (savedHash !== window.location.hash) {
+            savedHash = window.location.hash;
+            if (savedHash.length === 0) {
                 return;
             }
-            if (ev === null) {
-                var x = document.getElementById(from);
-                if (x) {
-                    x.scrollIntoView();
-                }
+            var elem = document.getElementById(savedHash.slice(1)); // we remove the '#'
+            if (!elem || !isHidden(elem)) {
+                return;
             }
-            onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
-                onEachLazy(e.getElementsByTagName("span"), function(i_e) {
-                    removeClass(i_e, "line-highlighted");
+            var parent = elem.parentNode;
+            if (parent && hasClass(parent, "impl-items")) {
+                // In case this is a trait implementation item, we first need to toggle
+                // the "Show hidden undocumented items".
+                onEachLazy(parent.getElementsByClassName("collapsed"), function(e) {
+                    if (e.parentNode === parent) {
+                        // Only click on the toggle we're looking for.
+                        e.click();
+                        return true;
+                    }
                 });
-            });
-            for (i = from; i <= to; ++i) {
-                elem = document.getElementById(i);
-                if (!elem) {
-                    break;
+                if (isHidden(elem)) {
+                    // The whole parent is collapsed. We need to click on its toggle as well!
+                    if (hasClass(parent.lastElementChild, "collapse-toggle")) {
+                        parent.lastElementChild.click();
+                    }
                 }
-                addClass(elem, "line-highlighted");
             }
-        } else if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
-            addClass(search, "hidden");
-            removeClass(main, "hidden");
-            var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
-            if (browserSupportsHistoryApi()) {
-                history.replaceState(hash, "", "?search=#" + hash);
+        }
+    }
+
+    function highlightSourceLines(match, ev) {
+        if (typeof match === "undefined") {
+            // If we're in mobile mode, we should hide the sidebar in any case.
+            hideSidebar();
+            match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
+        }
+        if (!match) {
+            return;
+        }
+        var from = parseInt(match[1], 10);
+        var to = from;
+        if (typeof match[2] !== "undefined") {
+            to = parseInt(match[2], 10);
+        }
+        if (to < from) {
+            var tmp = to;
+            to = from;
+            from = tmp;
+        }
+        var elem = document.getElementById(from);
+        if (!elem) {
+            return;
+        }
+        if (!ev) {
+            var x = document.getElementById(from);
+            if (x) {
+                x.scrollIntoView();
             }
-            elem = document.getElementById(hash);
-            if (elem) {
-                elem.scrollIntoView();
+        }
+        onEachLazy(document.getElementsByClassName("line-numbers"), function(e) {
+            onEachLazy(e.getElementsByTagName("span"), function(i_e) {
+                removeClass(i_e, "line-highlighted");
+            });
+        });
+        for (var i = from; i <= to; ++i) {
+            elem = document.getElementById(i);
+            if (!elem) {
+                break;
             }
+            addClass(elem, "line-highlighted");
         }
     }
 
+    function onHashChange(ev) {
+        // If we're in mobile mode, we should hide the sidebar in any case.
+        hideSidebar();
+        var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
+        if (match) {
+            return highlightSourceLines(match, ev);
+        }
+        handleHashes(ev);
+    }
+
     function expandSection(id) {
         var elem = document.getElementById(id);
         if (elem && isHidden(elem)) {
@@ -234,9 +286,6 @@ function getSearchElement() {
         }
     }
 
-    highlightSourceLines(null);
-    window.onhashchange = highlightSourceLines;
-
     // Gets the human-readable string for the virtual-key code of the
     // given KeyboardEvent, ev.
     //
@@ -358,7 +407,7 @@ function getSearchElement() {
             var set_fragment = function(name) {
                 if (browserSupportsHistoryApi()) {
                     history.replaceState(null, null, "#" + name);
-                    highlightSourceLines(null);
+                    highlightSourceLines();
                 } else {
                     location.replace("#" + name);
                 }
@@ -2106,7 +2155,7 @@ function getSearchElement() {
     function autoCollapse(pageId, collapse) {
         if (collapse) {
             toggleAllDocs(pageId, true);
-        } else if (getCurrentValue("rustdoc-trait-implementations") !== "false") {
+        } else if (getCurrentValue("rustdoc-auto-hide-trait-implementations") !== "false") {
             var impl_list = document.getElementById("implementations-list");
 
             if (impl_list !== null) {
@@ -2144,7 +2193,7 @@ function getSearchElement() {
     }
 
     var toggle = createSimpleToggle(false);
-    var hideMethodDocs = getCurrentValue("rustdoc-method-docs") === "true";
+    var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
     var pageId = getPageId();
 
     var func = function(e) {
@@ -2274,7 +2323,31 @@ function getSearchElement() {
         return wrapper;
     }
 
-    var showItemDeclarations = getCurrentValue("rustdoc-item-declarations") === "false";
+    var currentType = document.getElementsByClassName("type-decl")[0];
+    var className = null;
+    if (currentType) {
+        currentType = currentType.getElementsByClassName("rust")[0];
+        if (currentType) {
+            currentType.classList.forEach(function(item) {
+                if (item !== "main") {
+                    className = item;
+                    return true;
+                }
+            });
+        }
+    }
+    var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
+    if (showItemDeclarations === null) {
+        if (className === "enum" || className === "macro") {
+            showItemDeclarations = "false";
+        } else if (className === "struct" || className === "union" || className === "trait") {
+            showItemDeclarations = "true";
+        } else {
+            // In case we found an unknown type, we just use the "parent" value.
+            showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
+        }
+    }
+    showItemDeclarations = showItemDeclarations === "false";
     function buildToggleWrapper(e) {
         if (hasClass(e, "autohide")) {
             var wrap = e.previousElementSibling;
@@ -2357,7 +2430,7 @@ function getSearchElement() {
 
     // To avoid checking on "rustdoc-item-attributes" value on every loop...
     var itemAttributesFunc = function() {};
-    if (getCurrentValue("rustdoc-item-attributes") !== "false") {
+    if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
         itemAttributesFunc = function(x) {
             collapseDocs(x.previousSibling.childNodes[0], "toggle");
         };
@@ -2603,6 +2676,9 @@ function getSearchElement() {
         insertAfter(popup, getSearchElement());
     }
 
+    onHashChange();
+    window.onhashchange = onHashChange;
+
     buildHelperPopup();
 }());
 
diff --git a/src/librustdoc/html/static/settings.css b/src/librustdoc/html/static/settings.css
index b31ad96fa54..d03cf7fcc45 100644
--- a/src/librustdoc/html/static/settings.css
+++ b/src/librustdoc/html/static/settings.css
@@ -1,5 +1,6 @@
 .setting-line {
 	padding: 5px;
+	position: relative;
 }
 
 .setting-line > div {
@@ -10,6 +11,13 @@
 	padding-top: 2px;
 }
 
+.setting-line > .title {
+	font-size: 19px;
+	width: 100%;
+	max-width: none;
+	border-bottom: 1px solid;
+}
+
 .toggle {
 	position: relative;
 	display: inline-block;
@@ -59,3 +67,9 @@ input:checked + .slider:before {
 	-ms-transform: translateX(19px);
 	transform: translateX(19px);
 }
+
+.setting-line > .sub-settings {
+	padding-left: 42px;
+	width: 100%;
+	display: block;
+}
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index eae998ca3ec..d142d99ac70 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -24,10 +24,6 @@ function removeClass(elem, className) {
     elem.classList.remove(className);
 }
 
-function isHidden(elem) {
-    return elem.offsetParent === null;
-}
-
 function onEach(arr, func, reversed) {
     if (arr && arr.length > 0 && func) {
         var length = arr.length;
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index c3116dbe7a2..a60d543a539 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -425,3 +425,6 @@ div.files > a:hover, div.name:hover {
 div.files > .selected {
 	background-color: #333;
 }
+.setting-line > .title {
+	border-bottom-color: #ddd;
+}
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index e2bf9f9d2f2..351f027b942 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -419,3 +419,6 @@ div.files > a:hover, div.name:hover {
 div.files > .selected {
 	background-color: #fff;
 }
+.setting-line > .title {
+	border-bottom-color: #D5D5D5;
+}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8cd32a3d1b5..86e0f22db50 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -29,6 +29,7 @@ extern crate rustc_resolve;
 extern crate rustc_lint;
 extern crate rustc_interface;
 extern crate rustc_metadata;
+extern crate rustc_parse;
 extern crate rustc_target;
 extern crate rustc_typeck;
 extern crate rustc_lexer;
@@ -140,7 +141,7 @@ fn opts() -> Vec<RustcOptGroup> {
         }),
         stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")),
         stable("extern", |o| {
-            o.optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH")
+            o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")
         }),
         unstable("extern-html-root-url", |o| {
             o.optmulti("", "extern-html-root-url",
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 10e15ab8881..5c4c975cec0 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,8 +1,9 @@
 use errors::Applicability;
-use syntax::parse::lexer::{StringReader as Lexer};
-use syntax::parse::token;
+use rustc_parse::lexer::{StringReader as Lexer};
+use syntax::token;
 use syntax::sess::ParseSess;
 use syntax::source_map::FilePathMapping;
+use syntax_expand::config::process_configure_mod;
 use syntax_pos::{InnerSpan, FileName};
 
 use crate::clean;
@@ -27,7 +28,7 @@ struct SyntaxChecker<'a, 'tcx> {
 
 impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
     fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeBlock) {
-        let sess = ParseSess::new(FilePathMapping::empty());
+        let sess = ParseSess::new(FilePathMapping::empty(), process_configure_mod);
         let source_file = sess.source_map().new_source_file(
             FileName::Custom(String::from("doctest")),
             dox[code_block.code].to_owned(),
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 07dc1e4e915..553ef6a9c47 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -17,6 +17,7 @@ use std::path::PathBuf;
 use std::process::{self, Command, Stdio};
 use std::str;
 use syntax::symbol::sym;
+use syntax_expand::config::process_configure_mod;
 use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
 use tempfile::Builder as TempFileBuilder;
 use testing;
@@ -398,7 +399,8 @@ pub fn make_test(s: &str,
     // Uses libsyntax to parse the doctest and find if there's a main fn and the extern
     // crate already is included.
     let (already_has_main, already_has_extern_crate, found_macro) = with_globals(edition, || {
-        use crate::syntax::{parse, sess::ParseSess, source_map::FilePathMapping};
+        use crate::syntax::{sess::ParseSess, source_map::FilePathMapping};
+        use rustc_parse::maybe_new_parser_from_source_str;
         use errors::emitter::EmitterWriter;
         use errors::Handler;
 
@@ -411,13 +413,13 @@ pub fn make_test(s: &str,
         let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
         // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
         let handler = Handler::with_emitter(false, None, box emitter);
-        let sess = ParseSess::with_span_handler(handler, cm);
+        let sess = ParseSess::with_span_handler(handler, cm, process_configure_mod);
 
         let mut found_main = false;
         let mut found_extern_crate = cratename.is_none();
         let mut found_macro = false;
 
-        let mut parser = match parse::maybe_new_parser_from_source_str(&sess, filename, source) {
+        let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) {
             Ok(p) => p,
             Err(errs) => {
                 for mut err in errs {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5a83569f02a..aea9b7c38ef 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -438,8 +438,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 om.structs.push(self.visit_variant_data(item, ident.name, sd, gen)),
             hir::ItemKind::Union(ref sd, ref gen) =>
                 om.unions.push(self.visit_union_data(item, ident.name, sd, gen)),
-            hir::ItemKind::Fn(ref fd, header, ref gen, body) =>
-                self.visit_fn(om, item, ident.name, &**fd, header, gen, body),
+            hir::ItemKind::Fn(ref sig, ref gen, body) =>
+                self.visit_fn(om, item, ident.name, &sig.decl, sig.header, gen, body),
             hir::ItemKind::TyAlias(ref ty, ref gen) => {
                 let t = Typedef {
                     ty,
diff --git a/src/libserialize/Cargo.toml b/src/libserialize/Cargo.toml
index c302bcf95dc..96a0d51bc71 100644
--- a/src/libserialize/Cargo.toml
+++ b/src/libserialize/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 indexmap = "1"
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 092fb443468..a038ee80210 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -551,7 +551,7 @@ impl<T, S> HashSet<T, S>
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
-        if self.len() <= other.len() {
+        if self.len() >= other.len() {
             Union {
                 iter: self.iter().chain(other.difference(self)),
             }
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 795830a52c5..4b672a4c788 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -40,6 +40,7 @@ impl f32 {
     /// assert_eq!(g.floor(), 3.0);
     /// assert_eq!(h.floor(), -4.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn floor(self) -> f32 {
@@ -73,6 +74,7 @@ impl f32 {
     /// assert_eq!(f.ceil(), 4.0);
     /// assert_eq!(g.ceil(), 4.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ceil(self) -> f32 {
@@ -95,6 +97,7 @@ impl f32 {
     /// assert_eq!(f.round(), 3.0);
     /// assert_eq!(g.round(), -3.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn round(self) -> f32 {
@@ -114,6 +117,7 @@ impl f32 {
     /// assert_eq!(g.trunc(), 3.0);
     /// assert_eq!(h.trunc(), -3.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn trunc(self) -> f32 {
@@ -135,6 +139,7 @@ impl f32 {
     /// assert!(abs_difference_x <= f32::EPSILON);
     /// assert!(abs_difference_y <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn fract(self) -> f32 { self - self.trunc() }
@@ -158,6 +163,7 @@ impl f32 {
     ///
     /// assert!(f32::NAN.abs().is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn abs(self) -> f32 {
@@ -182,6 +188,7 @@ impl f32 {
     ///
     /// assert!(f32::NAN.signum().is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn signum(self) -> f32 {
@@ -213,8 +220,8 @@ impl f32 {
     ///
     /// assert!(f32::NAN.copysign(1.0).is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
-    #[must_use]
     #[stable(feature = "copysign", since = "1.35.0")]
     pub fn copysign(self, sign: f32) -> f32 {
         unsafe { intrinsics::copysignf32(self, sign) }
@@ -240,6 +247,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn mul_add(self, a: f32, b: f32) -> f32 {
@@ -263,6 +271,7 @@ impl f32 {
     /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
     /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn div_euclid(self, rhs: f32) -> f32 {
@@ -296,6 +305,7 @@ impl f32 {
     /// // limitation due to round-off error
     /// assert!((-std::f32::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn rem_euclid(self, rhs: f32) -> f32 {
@@ -322,6 +332,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powi(self, n: i32) -> f32 {
@@ -340,6 +351,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powf(self, n: f32) -> f32 {
@@ -367,6 +379,7 @@ impl f32 {
     /// assert!(abs_difference <= f32::EPSILON);
     /// assert!(negative.sqrt().is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sqrt(self) -> f32 {
@@ -393,6 +406,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp(self) -> f32 {
@@ -417,6 +431,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp2(self) -> f32 {
@@ -439,6 +454,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f32 {
@@ -467,6 +483,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log(self, base: f32) -> f32 { self.ln() / base.ln() }
@@ -485,6 +502,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f32 {
@@ -508,6 +526,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f32 {
@@ -537,6 +556,7 @@ impl f32 {
     /// assert!(abs_difference_x <= f32::EPSILON);
     /// assert!(abs_difference_y <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     #[rustc_deprecated(since = "1.10.0",
@@ -565,6 +585,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cbrt(self) -> f32 {
@@ -587,6 +608,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn hypot(self, other: f32) -> f32 {
@@ -606,6 +628,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin(self) -> f32 {
@@ -629,6 +652,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cos(self) -> f32 {
@@ -651,6 +675,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn tan(self) -> f32 {
@@ -673,6 +698,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asin(self) -> f32 {
@@ -695,6 +721,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acos(self) -> f32 {
@@ -716,6 +743,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn atan(self) -> f32 {
@@ -750,6 +778,7 @@ impl f32 {
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// assert!(abs_difference_2 <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn atan2(self, other: f32) -> f32 {
@@ -794,6 +823,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp_m1(self) -> f32 {
@@ -815,6 +845,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln_1p(self) -> f32 {
@@ -838,6 +869,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sinh(self) -> f32 {
@@ -861,6 +893,7 @@ impl f32 {
     /// // Same result
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cosh(self) -> f32 {
@@ -884,6 +917,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn tanh(self) -> f32 {
@@ -904,6 +938,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f32 {
@@ -928,6 +963,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f32 {
@@ -952,6 +988,7 @@ impl f32 {
     ///
     /// assert!(abs_difference <= 1e-5);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn atanh(self) -> f32 {
@@ -979,6 +1016,7 @@ impl f32 {
     /// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0);
     /// assert!((std::f32::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "clamp", issue = "44095")]
     #[inline]
     pub fn clamp(self, min: f32, max: f32) -> f32 {
@@ -1594,18 +1632,18 @@ mod tests {
     #[test]
     #[should_panic]
     fn test_clamp_min_greater_than_max() {
-        1.0f32.clamp(3.0, 1.0);
+        let _ = 1.0f32.clamp(3.0, 1.0);
     }
 
     #[test]
     #[should_panic]
     fn test_clamp_min_is_nan() {
-        1.0f32.clamp(NAN, 1.0);
+        let _ = 1.0f32.clamp(NAN, 1.0);
     }
 
     #[test]
     #[should_panic]
     fn test_clamp_max_is_nan() {
-        1.0f32.clamp(3.0, NAN);
+        let _ = 1.0f32.clamp(3.0, NAN);
     }
 }
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 44d25f1b476..b16038ee1f8 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -40,6 +40,7 @@ impl f64 {
     /// assert_eq!(g.floor(), 3.0);
     /// assert_eq!(h.floor(), -4.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn floor(self) -> f64 {
@@ -57,6 +58,7 @@ impl f64 {
     /// assert_eq!(f.ceil(), 4.0);
     /// assert_eq!(g.ceil(), 4.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ceil(self) -> f64 {
@@ -75,6 +77,7 @@ impl f64 {
     /// assert_eq!(f.round(), 3.0);
     /// assert_eq!(g.round(), -3.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn round(self) -> f64 {
@@ -94,6 +97,7 @@ impl f64 {
     /// assert_eq!(g.trunc(), 3.0);
     /// assert_eq!(h.trunc(), -3.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn trunc(self) -> f64 {
@@ -113,6 +117,7 @@ impl f64 {
     /// assert!(abs_difference_x < 1e-10);
     /// assert!(abs_difference_y < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn fract(self) -> f64 { self - self.trunc() }
@@ -136,6 +141,7 @@ impl f64 {
     ///
     /// assert!(f64::NAN.abs().is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn abs(self) -> f64 {
@@ -160,6 +166,7 @@ impl f64 {
     ///
     /// assert!(f64::NAN.signum().is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn signum(self) -> f64 {
@@ -191,9 +198,9 @@ impl f64 {
     ///
     /// assert!(f64::NAN.copysign(1.0).is_nan());
     /// ```
-    #[inline]
-    #[must_use]
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "copysign", since = "1.35.0")]
+    #[inline]
     pub fn copysign(self, sign: f64) -> f64 {
         unsafe { intrinsics::copysignf64(self, sign) }
     }
@@ -216,6 +223,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn mul_add(self, a: f64, b: f64) -> f64 {
@@ -239,6 +247,7 @@ impl f64 {
     /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
     /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn div_euclid(self, rhs: f64) -> f64 {
@@ -272,6 +281,7 @@ impl f64 {
     /// // limitation due to round-off error
     /// assert!((-std::f64::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[inline]
     #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn rem_euclid(self, rhs: f64) -> f64 {
@@ -295,6 +305,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powi(self, n: i32) -> f64 {
@@ -311,6 +322,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn powf(self, n: f64) -> f64 {
@@ -332,6 +344,7 @@ impl f64 {
     /// assert!(abs_difference < 1e-10);
     /// assert!(negative.sqrt().is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sqrt(self) -> f64 {
@@ -356,6 +369,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp(self) -> f64 {
@@ -374,6 +388,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp2(self) -> f64 {
@@ -394,6 +409,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln(self) -> f64 {
@@ -409,13 +425,14 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// let five = 5.0_f64;
+    /// let twenty_five = 25.0_f64;
     ///
-    /// // log5(5) - 1 == 0
-    /// let abs_difference = (five.log(5.0) - 1.0).abs();
+    /// // log5(25) - 2 == 0
+    /// let abs_difference = (twenty_five.log(5.0) - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log(self, base: f64) -> f64 { self.ln() / base.ln() }
@@ -425,13 +442,14 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// let two = 2.0_f64;
+    /// let four = 4.0_f64;
     ///
-    /// // log2(2) - 1 == 0
-    /// let abs_difference = (two.log2() - 1.0).abs();
+    /// // log2(4) - 2 == 0
+    /// let abs_difference = (four.log2() - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log2(self) -> f64 {
@@ -448,13 +466,14 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// let ten = 10.0_f64;
+    /// let hundred = 100.0_f64;
     ///
-    /// // log10(10) - 1 == 0
-    /// let abs_difference = (ten.log10() - 1.0).abs();
+    /// // log10(100) - 2 == 0
+    /// let abs_difference = (hundred.log10() - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn log10(self) -> f64 {
@@ -478,6 +497,7 @@ impl f64 {
     /// assert!(abs_difference_x < 1e-10);
     /// assert!(abs_difference_y < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     #[rustc_deprecated(since = "1.10.0",
@@ -504,6 +524,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cbrt(self) -> f64 {
@@ -524,6 +545,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn hypot(self, other: f64) -> f64 {
@@ -543,6 +565,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sin(self) -> f64 {
@@ -562,6 +585,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cos(self) -> f64 {
@@ -580,6 +604,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-14);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn tan(self) -> f64 {
@@ -602,6 +627,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asin(self) -> f64 {
@@ -624,6 +650,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acos(self) -> f64 {
@@ -643,6 +670,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn atan(self) -> f64 {
@@ -677,6 +705,7 @@ impl f64 {
     /// assert!(abs_difference_1 < 1e-10);
     /// assert!(abs_difference_2 < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn atan2(self, other: f64) -> f64 {
@@ -719,6 +748,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn exp_m1(self) -> f64 {
@@ -740,6 +770,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn ln_1p(self) -> f64 {
@@ -763,6 +794,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn sinh(self) -> f64 {
@@ -786,6 +818,7 @@ impl f64 {
     /// // Same result
     /// assert!(abs_difference < 1.0e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn cosh(self) -> f64 {
@@ -809,6 +842,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn tanh(self) -> f64 {
@@ -827,6 +861,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f64 {
@@ -849,6 +884,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f64 {
@@ -873,6 +909,7 @@ impl f64 {
     ///
     /// assert!(abs_difference < 1.0e-10);
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn atanh(self) -> f64 {
@@ -900,6 +937,7 @@ impl f64 {
     /// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0);
     /// assert!((std::f64::NAN).clamp(-2.0, 1.0).is_nan());
     /// ```
+    #[must_use = "method returns a new number and does not mutate the original value"]
     #[unstable(feature = "clamp", issue = "44095")]
     #[inline]
     pub fn clamp(self, min: f64, max: f64) -> f64 {
@@ -1535,18 +1573,18 @@ mod tests {
     #[test]
     #[should_panic]
     fn test_clamp_min_greater_than_max() {
-        1.0f64.clamp(3.0, 1.0);
+        let _ = 1.0f64.clamp(3.0, 1.0);
     }
 
     #[test]
     #[should_panic]
     fn test_clamp_min_is_nan() {
-        1.0f64.clamp(NAN, 1.0);
+        let _ = 1.0f64.clamp(NAN, 1.0);
     }
 
     #[test]
     #[should_panic]
     fn test_clamp_max_is_nan() {
-        1.0f64.clamp(3.0, NAN);
+        let _ = 1.0f64.clamp(3.0, NAN);
     }
 }
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 9593a1bae0a..ad567c97c2c 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -24,7 +24,9 @@ use crate::memchr;
 ///
 /// When the `BufReader<R>` is dropped, the contents of its buffer will be
 /// discarded. Creating multiple instances of a `BufReader<R>` on the same
-/// stream can cause data loss.
+/// stream can cause data loss. Reading from the underlying reader after
+/// unwrapping the `BufReader<R>` with `BufReader::into_inner` can also cause
+/// data loss.
 ///
 /// [`Read`]: ../../std/io/trait.Read.html
 /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
@@ -179,7 +181,8 @@ impl<R> BufReader<R> {
 
     /// Unwraps this `BufReader<R>`, returning the underlying reader.
     ///
-    /// Note that any leftover data in the internal buffer is lost.
+    /// Note that any leftover data in the internal buffer is lost. Therefore,
+    /// a following read from the underlying reader may lead to data loss.
     ///
     /// # Examples
     ///
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c7adad896a5..927fd2a6b0b 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -284,7 +284,7 @@
 #![feature(never_type)]
 #![feature(nll)]
 #![cfg_attr(bootstrap, feature(non_exhaustive))]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(optin_builtin_traits)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 70b68d13485..21f674af8cf 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -536,7 +536,7 @@ impl Ipv4Addr {
     /// // the broadcast address is not global
     /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
     ///
-    /// // the broadcast address is not global
+    /// // the address space designated for documentation is not global
     /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
     /// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
     /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
@@ -1130,7 +1130,7 @@ impl Ipv6Addr {
     /// The following return [`false`]:
     ///
     /// - the loopback address
-    /// - link-local, site-local, and unique local unicast addresses
+    /// - link-local and unique local unicast addresses
     /// - interface-, link-, realm-, admin- and site-local multicast addresses
     ///
     /// [`true`]: ../../std/primitive.bool.html
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 4b0cf8312f1..b1274a08cbe 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1661,7 +1661,7 @@ mod tests {
     // FIXME(#10380) these tests should not all be ignored on android.
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn smoke() {
         let p = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 0"]).spawn()
@@ -1683,7 +1683,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn exit_reported_right() {
         let p = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).spawn()
@@ -1698,7 +1698,7 @@ mod tests {
 
     #[test]
     #[cfg(unix)]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn signal_reported_right() {
         use crate::os::unix::process::ExitStatusExt;
 
@@ -1726,7 +1726,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn stdout_works() {
         if cfg!(target_os = "windows") {
             let mut cmd = Command::new("cmd");
@@ -1740,7 +1740,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(any(windows, target_os = "android"), ignore)]
+    #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
     fn set_current_dir_works() {
         let mut cmd = Command::new("/bin/sh");
         cmd.arg("-c").arg("pwd")
@@ -1750,7 +1750,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(any(windows, target_os = "android"), ignore)]
+    #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
     fn stdin_works() {
         let mut p = Command::new("/bin/sh")
                             .arg("-c").arg("read line; echo $line")
@@ -1766,7 +1766,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_process_status() {
         let mut status = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
@@ -1792,7 +1792,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_process_output_output() {
         let Output {status, stdout, stderr}
              = if cfg!(target_os = "windows") {
@@ -1808,7 +1808,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_process_output_error() {
         let Output {status, stdout, stderr}
              = if cfg!(target_os = "windows") {
@@ -1823,7 +1823,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_finish_once() {
         let mut prog = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
@@ -1834,7 +1834,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_finish_twice() {
         let mut prog = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
@@ -1846,7 +1846,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_wait_with_output_once() {
         let prog = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
@@ -1881,6 +1881,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_override_env() {
         use crate::env;
 
@@ -1901,6 +1902,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_add_to_env() {
         let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
         let output = String::from_utf8_lossy(&result.stdout).to_string();
@@ -1910,6 +1912,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_capture_env_at_spawn() {
         use crate::env;
 
@@ -1965,6 +1968,7 @@ mod tests {
 
     // Regression tests for #30862.
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_interior_nul_in_env_key_is_error() {
         match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
@@ -1973,6 +1977,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_interior_nul_in_env_value_is_error() {
         match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index e28fbca7fa1..e8e395247f9 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -51,11 +51,43 @@
 //
 // You'll find a few more details in the implementation, but that's the gist of
 // it!
-
+//
+// Atomic orderings:
+// When running `Once` we deal with multiple atomics:
+// `Once.state_and_queue` and an unknown number of `Waiter.signaled`.
+// * `state_and_queue` is used (1) as a state flag, (2) for synchronizing the
+//   result of the `Once`, and (3) for synchronizing `Waiter` nodes.
+//     - At the end of the `call_inner` function we have to make sure the result
+//       of the `Once` is acquired. So every load which can be the only one to
+//       load COMPLETED must have at least Acquire ordering, which means all
+//       three of them.
+//     - `WaiterQueue::Drop` is the only place that may store COMPLETED, and
+//       must do so with Release ordering to make the result available.
+//     - `wait` inserts `Waiter` nodes as a pointer in `state_and_queue`, and
+//       needs to make the nodes available with Release ordering. The load in
+//       its `compare_and_swap` can be Relaxed because it only has to compare
+//       the atomic, not to read other data.
+//     - `WaiterQueue::Drop` must see the `Waiter` nodes, so it must load
+//       `state_and_queue` with Acquire ordering.
+//     - There is just one store where `state_and_queue` is used only as a
+//       state flag, without having to synchronize data: switching the state
+//       from INCOMPLETE to RUNNING in `call_inner`. This store can be Relaxed,
+//       but the read has to be Acquire because of the requirements mentioned
+//       above.
+// * `Waiter.signaled` is both used as a flag, and to protect a field with
+//   interior mutability in `Waiter`. `Waiter.thread` is changed in
+//   `WaiterQueue::Drop` which then sets `signaled` with Release ordering.
+//   After `wait` loads `signaled` with Acquire and sees it is true, it needs to
+//   see the changes to drop the `Waiter` struct correctly.
+// * There is one place where the two atomics `Once.state_and_queue` and
+//   `Waiter.signaled` come together, and might be reordered by the compiler or
+//   processor. Because both use Aquire ordering such a reordering is not
+//   allowed, so no need for SeqCst.
+
+use crate::cell::Cell;
 use crate::fmt;
 use crate::marker;
-use crate::ptr;
-use crate::sync::atomic::{AtomicUsize, AtomicBool, Ordering};
+use crate::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
 use crate::thread::{self, Thread};
 
 /// A synchronization primitive which can be used to run a one-time global
@@ -78,10 +110,10 @@ use crate::thread::{self, Thread};
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Once {
-    // This `state` word is actually an encoded version of just a pointer to a
-    // `Waiter`, so we add the `PhantomData` appropriately.
-    state: AtomicUsize,
-    _marker: marker::PhantomData<*mut Waiter>,
+    // `state_and_queue` is actually an a pointer to a `Waiter` with extra state
+    // bits, so we add the `PhantomData` appropriately.
+    state_and_queue: AtomicUsize,
+    _marker: marker::PhantomData<*const Waiter>,
 }
 
 // The `PhantomData` of a raw pointer removes these two auto traits, but we
@@ -117,12 +149,12 @@ pub struct OnceState {
 #[rustc_deprecated(
     since = "1.38.0",
     reason = "the `new` function is now preferred",
-    suggestion = "Once::new()",
+    suggestion = "Once::new()"
 )]
 pub const ONCE_INIT: Once = Once::new();
 
-// Four states that a Once can be in, encoded into the lower bits of `state` in
-// the Once structure.
+// Four states that a Once can be in, encoded into the lower bits of
+// `state_and_queue` in the Once structure.
 const INCOMPLETE: usize = 0x0;
 const POISONED: usize = 0x1;
 const RUNNING: usize = 0x2;
@@ -132,28 +164,32 @@ const COMPLETE: usize = 0x3;
 // this is in the RUNNING state.
 const STATE_MASK: usize = 0x3;
 
-// Representation of a node in the linked list of waiters in the RUNNING state.
+// Representation of a node in the linked list of waiters, used while in the
+// RUNNING state.
+// Note: `Waiter` can't hold a mutable pointer to the next thread, because then
+// `wait` would both hand out a mutable reference to its `Waiter` node, and keep
+// a shared reference to check `signaled`. Instead we hold shared references and
+// use interior mutability.
+#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
 struct Waiter {
-    thread: Option<Thread>,
+    thread: Cell<Option<Thread>>,
     signaled: AtomicBool,
-    next: *mut Waiter,
+    next: *const Waiter,
 }
 
-// Helper struct used to clean up after a closure call with a `Drop`
-// implementation to also run on panic.
-struct Finish<'a> {
-    panicked: bool,
-    me: &'a Once,
+// Head of a linked list of waiters.
+// Every node is a struct on the stack of a waiting thread.
+// Will wake up the waiters when it gets dropped, i.e. also on panic.
+struct WaiterQueue<'a> {
+    state_and_queue: &'a AtomicUsize,
+    set_state_on_drop_to: usize,
 }
 
 impl Once {
     /// Creates a new `Once` value.
     #[stable(feature = "once_new", since = "1.2.0")]
     pub const fn new() -> Once {
-        Once {
-            state: AtomicUsize::new(INCOMPLETE),
-            _marker: marker::PhantomData,
-        }
+        Once { state_and_queue: AtomicUsize::new(INCOMPLETE), _marker: marker::PhantomData }
     }
 
     /// Performs an initialization routine once and only once. The given closure
@@ -214,7 +250,10 @@ impl Once {
     ///
     /// [poison]: struct.Mutex.html#poisoning
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn call_once<F>(&self, f: F) where F: FnOnce() {
+    pub fn call_once<F>(&self, f: F)
+    where
+        F: FnOnce(),
+    {
         // Fast path check
         if self.is_completed() {
             return;
@@ -271,16 +310,17 @@ impl Once {
     /// INIT.call_once(|| {});
     /// ```
     #[unstable(feature = "once_poison", issue = "33577")]
-    pub fn call_once_force<F>(&self, f: F) where F: FnOnce(&OnceState) {
+    pub fn call_once_force<F>(&self, f: F)
+    where
+        F: FnOnce(&OnceState),
+    {
         // Fast path check
         if self.is_completed() {
             return;
         }
 
         let mut f = Some(f);
-        self.call_inner(true, &mut |p| {
-            f.take().unwrap()(&OnceState { poisoned: p })
-        });
+        self.call_inner(true, &mut |p| f.take().unwrap()(&OnceState { poisoned: p }));
     }
 
     /// Returns `true` if some `call_once` call has completed
@@ -329,8 +369,8 @@ impl Once {
         // An `Acquire` load is enough because that makes all the initialization
         // operations visible to us, and, this being a fast path, weaker
         // ordering helps with performance. This `Acquire` synchronizes with
-        // `SeqCst` operations on the slow path.
-        self.state.load(Ordering::Acquire) == COMPLETE
+        // `Release` operations on the slow path.
+        self.state_and_queue.load(Ordering::Acquire) == COMPLETE
     }
 
     // This is a non-generic function to reduce the monomorphization cost of
@@ -345,94 +385,92 @@ impl Once {
     // currently no way to take an `FnOnce` and call it via virtual dispatch
     // without some allocation overhead.
     #[cold]
-    fn call_inner(&self,
-                  ignore_poisoning: bool,
-                  init: &mut dyn FnMut(bool)) {
-
-        // This cold path uses SeqCst consistently because the
-        // performance difference really does not matter there, and
-        // SeqCst minimizes the chances of something going wrong.
-        let mut state = self.state.load(Ordering::SeqCst);
-
-        'outer: loop {
-            match state {
-                // If we're complete, then there's nothing to do, we just
-                // jettison out as we shouldn't run the closure.
-                COMPLETE => return,
-
-                // If we're poisoned and we're not in a mode to ignore
-                // poisoning, then we panic here to propagate the poison.
+    fn call_inner(&self, ignore_poisoning: bool, init: &mut dyn FnMut(bool)) {
+        let mut state_and_queue = self.state_and_queue.load(Ordering::Acquire);
+        loop {
+            match state_and_queue {
+                COMPLETE => break,
                 POISONED if !ignore_poisoning => {
+                    // Panic to propagate the poison.
                     panic!("Once instance has previously been poisoned");
                 }
-
-                // Otherwise if we see a poisoned or otherwise incomplete state
-                // we will attempt to move ourselves into the RUNNING state. If
-                // we succeed, then the queue of waiters starts at null (all 0
-                // bits).
-                POISONED |
-                INCOMPLETE => {
-                    let old = self.state.compare_and_swap(state, RUNNING,
-                                                          Ordering::SeqCst);
-                    if old != state {
-                        state = old;
-                        continue
+                POISONED | INCOMPLETE => {
+                    // Try to register this thread as the one RUNNING.
+                    let old = self.state_and_queue.compare_and_swap(
+                        state_and_queue,
+                        RUNNING,
+                        Ordering::Acquire,
+                    );
+                    if old != state_and_queue {
+                        state_and_queue = old;
+                        continue;
                     }
-
-                    // Run the initialization routine, letting it know if we're
-                    // poisoned or not. The `Finish` struct is then dropped, and
-                    // the `Drop` implementation here is responsible for waking
-                    // up other waiters both in the normal return and panicking
-                    // case.
-                    let mut complete = Finish {
-                        panicked: true,
-                        me: self,
+                    // `waiter_queue` will manage other waiting threads, and
+                    // wake them up on drop.
+                    let mut waiter_queue = WaiterQueue {
+                        state_and_queue: &self.state_and_queue,
+                        set_state_on_drop_to: POISONED,
                     };
-                    init(state == POISONED);
-                    complete.panicked = false;
-                    return
+                    // Run the initialization function, letting it know if we're
+                    // poisoned or not.
+                    init(state_and_queue == POISONED);
+                    waiter_queue.set_state_on_drop_to = COMPLETE;
+                    break;
                 }
-
-                // All other values we find should correspond to the RUNNING
-                // state with an encoded waiter list in the more significant
-                // bits. We attempt to enqueue ourselves by moving us to the
-                // head of the list and bail out if we ever see a state that's
-                // not RUNNING.
                 _ => {
-                    assert!(state & STATE_MASK == RUNNING);
-                    let mut node = Waiter {
-                        thread: Some(thread::current()),
-                        signaled: AtomicBool::new(false),
-                        next: ptr::null_mut(),
-                    };
-                    let me = &mut node as *mut Waiter as usize;
-                    assert!(me & STATE_MASK == 0);
-
-                    while state & STATE_MASK == RUNNING {
-                        node.next = (state & !STATE_MASK) as *mut Waiter;
-                        let old = self.state.compare_and_swap(state,
-                                                              me | RUNNING,
-                                                              Ordering::SeqCst);
-                        if old != state {
-                            state = old;
-                            continue
-                        }
-
-                        // Once we've enqueued ourselves, wait in a loop.
-                        // Afterwards reload the state and continue with what we
-                        // were doing from before.
-                        while !node.signaled.load(Ordering::SeqCst) {
-                            thread::park();
-                        }
-                        state = self.state.load(Ordering::SeqCst);
-                        continue 'outer
-                    }
+                    // All other values must be RUNNING with possibly a
+                    // pointer to the waiter queue in the more significant bits.
+                    assert!(state_and_queue & STATE_MASK == RUNNING);
+                    wait(&self.state_and_queue, state_and_queue);
+                    state_and_queue = self.state_and_queue.load(Ordering::Acquire);
                 }
             }
         }
     }
 }
 
+fn wait(state_and_queue: &AtomicUsize, mut current_state: usize) {
+    // Note: the following code was carefully written to avoid creating a
+    // mutable reference to `node` that gets aliased.
+    loop {
+        // Don't queue this thread if the status is no longer running,
+        // otherwise we will not be woken up.
+        if current_state & STATE_MASK != RUNNING {
+            return;
+        }
+
+        // Create the node for our current thread.
+        let node = Waiter {
+            thread: Cell::new(Some(thread::current())),
+            signaled: AtomicBool::new(false),
+            next: (current_state & !STATE_MASK) as *const Waiter,
+        };
+        let me = &node as *const Waiter as usize;
+
+        // Try to slide in the node at the head of the linked list, making sure
+        // that another thread didn't just replace the head of the linked list.
+        let old = state_and_queue.compare_and_swap(current_state, me | RUNNING, Ordering::Release);
+        if old != current_state {
+            current_state = old;
+            continue;
+        }
+
+        // We have enqueued ourselves, now lets wait.
+        // It is important not to return before being signaled, otherwise we
+        // would drop our `Waiter` node and leave a hole in the linked list
+        // (and a dangling reference). Guard against spurious wakeups by
+        // reparking ourselves until we are signaled.
+        while !node.signaled.load(Ordering::Acquire) {
+            // If the managing thread happens to signal and unpark us before we
+            // can park ourselves, the result could be this thread never gets
+            // unparked. Luckily `park` comes with the guarantee that if it got
+            // an `unpark` just before on an unparked thread is does not park.
+            thread::park();
+        }
+        break;
+    }
+}
+
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl fmt::Debug for Once {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -440,29 +478,31 @@ impl fmt::Debug for Once {
     }
 }
 
-impl Drop for Finish<'_> {
+impl Drop for WaiterQueue<'_> {
     fn drop(&mut self) {
-        // Swap out our state with however we finished. We should only ever see
-        // an old state which was RUNNING.
-        let queue = if self.panicked {
-            self.me.state.swap(POISONED, Ordering::SeqCst)
-        } else {
-            self.me.state.swap(COMPLETE, Ordering::SeqCst)
-        };
-        assert_eq!(queue & STATE_MASK, RUNNING);
+        // Swap out our state with however we finished.
+        let state_and_queue =
+            self.state_and_queue.swap(self.set_state_on_drop_to, Ordering::AcqRel);
+
+        // We should only ever see an old state which was RUNNING.
+        assert_eq!(state_and_queue & STATE_MASK, RUNNING);
 
-        // Decode the RUNNING to a list of waiters, then walk that entire list
-        // and wake them up. Note that it is crucial that after we store `true`
-        // in the node it can be free'd! As a result we load the `thread` to
-        // signal ahead of time and then unpark it after the store.
+        // Walk the entire linked list of waiters and wake them up (in lifo
+        // order, last to register is first to wake up).
         unsafe {
-            let mut queue = (queue & !STATE_MASK) as *mut Waiter;
+            // Right after setting `node.signaled = true` the other thread may
+            // free `node` if there happens to be has a spurious wakeup.
+            // So we have to take out the `thread` field and copy the pointer to
+            // `next` first.
+            let mut queue = (state_and_queue & !STATE_MASK) as *const Waiter;
             while !queue.is_null() {
                 let next = (*queue).next;
-                let thread = (*queue).thread.take().unwrap();
-                (*queue).signaled.store(true, Ordering::SeqCst);
-                thread.unpark();
+                let thread = (*queue).thread.replace(None).unwrap();
+                (*queue).signaled.store(true, Ordering::Release);
+                // ^- FIXME (maybe): This is another case of issue #55005
+                // `store()` has a potentially dangling ref to `signaled`.
                 queue = next;
+                thread.unpark();
             }
         }
     }
@@ -518,10 +558,10 @@ impl OnceState {
 
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
+    use super::Once;
     use crate::panic;
     use crate::sync::mpsc::channel;
     use crate::thread;
-    use super::Once;
 
     #[test]
     fn smoke_once() {
@@ -541,8 +581,10 @@ mod tests {
         let (tx, rx) = channel();
         for _ in 0..10 {
             let tx = tx.clone();
-            thread::spawn(move|| {
-                for _ in 0..4 { thread::yield_now() }
+            thread::spawn(move || {
+                for _ in 0..4 {
+                    thread::yield_now()
+                }
                 unsafe {
                     O.call_once(|| {
                         assert!(!RUN);
@@ -631,6 +673,5 @@ mod tests {
 
         assert!(t1.join().is_ok());
         assert!(t2.join().is_ok());
-
     }
 }
diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs
index 0f107de83f0..3a9b1fc8684 100644
--- a/src/libstd/sys/sgx/abi/mod.rs
+++ b/src/libstd/sys/sgx/abi/mod.rs
@@ -53,6 +53,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
 // (main function exists). If this is a library, the crate author should be
 // able to specify this
 #[cfg(not(test))]
+#[allow(improper_ctypes)]
 #[no_mangle]
 extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
     // FIXME: how to support TLS in library mode?
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
index e2f94b1d928..c32e6dd3786 100644
--- a/src/libstd/sys/sgx/rwlock.rs
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -172,6 +172,7 @@ const EINVAL: i32 = 22;
 
 #[cfg(not(test))]
 #[no_mangle]
+#[allow(improper_ctypes)]
 pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
         return EINVAL;
@@ -181,6 +182,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
 }
 
 #[cfg(not(test))]
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
@@ -190,6 +192,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
     return 0;
 }
 #[cfg(not(test))]
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index be112f6fc03..bc387544c4c 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -15,6 +15,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
           not(target_os = "ios"),
           not(target_os = "openbsd"),
           not(target_os = "freebsd"),
+          not(target_os = "netbsd"),
           not(target_os = "fuchsia"),
           not(target_os = "redox")))]
 mod imp {
@@ -142,7 +143,7 @@ mod imp {
     }
 }
 
-#[cfg(target_os = "freebsd")]
+#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
 mod imp {
     use crate::ptr;
 
diff --git a/src/libstd/sys/vxworks/os.rs b/src/libstd/sys/vxworks/os.rs
index f4798da1876..baa6c425d2e 100644
--- a/src/libstd/sys/vxworks/os.rs
+++ b/src/libstd/sys/vxworks/os.rs
@@ -287,7 +287,8 @@ pub fn temp_dir() -> PathBuf {
 }
 
 pub fn home_dir() -> Option<PathBuf> {
-    None
+    crate::env::var_os("HOME").or_else(|| None
+    ).map(PathBuf::from)
 }
 
 pub fn exit(code: i32) -> ! {
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index cfaab4e22e9..46453b47fca 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -149,7 +149,7 @@ macro_rules! thread_local {
 #[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
 #[allow_internal_unsafe]
 macro_rules! __thread_local_inner {
-    (@key $(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
+    (@key $t:ty, $init:expr) => {
         {
             #[inline]
             fn __init() -> $t { $init }
@@ -184,7 +184,7 @@ macro_rules! __thread_local_inner {
     };
     ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
         $(#[$attr])* $vis const $name: $crate::thread::LocalKey<$t> =
-            $crate::__thread_local_inner!(@key $(#[$attr])* $vis $name, $t, $init);
+            $crate::__thread_local_inner!(@key $t, $init);
     }
 }
 
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 0ffa6ace2e4..0c632d2afbd 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -1271,6 +1271,18 @@ impl fmt::Debug for Thread {
 ///
 /// Indicates the manner in which a thread exited.
 ///
+/// The value contained in the `Result::Err` variant
+/// is the value the thread panicked with;
+/// that is, the argument the `panic!` macro was called with.
+/// Unlike with normal errors, this value doesn't implement
+/// the [`Error`](crate::error::Error) trait.
+///
+/// Thus, a sensible way to handle a thread panic is to either:
+/// 1. `unwrap` the `Result<T>`, propagating the panic
+/// 2. or in case the thread is intended to be a subsystem boundary
+/// that is supposed to isolate system-level failures,
+/// match on the `Err` variant and handle the panic in an appropriate way.
+///
 /// A thread that completes without panicking is considered to exit successfully.
 ///
 /// # Examples
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index 3ce47e6a7b8..3e17e7949ea 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -20,5 +20,4 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_index = { path = "../librustc_index" }
 rustc_lexer = { path = "../librustc_lexer" }
-rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8b967048848..13bf6752ba2 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -22,12 +22,11 @@ pub use GenericArgs::*;
 pub use UnsafeSource::*;
 pub use crate::util::parser::ExprPrecedence;
 
-pub use rustc_target::abi::FloatTy;
 pub use syntax_pos::symbol::{Ident, Symbol as Name};
 
-use crate::parse::token::{self, DelimToken};
 use crate::ptr::P;
 use crate::source_map::{dummy_spanned, respan, Spanned};
+use crate::token::{self, DelimToken};
 use crate::tokenstream::TokenStream;
 
 use syntax_pos::symbol::{kw, sym, Symbol};
@@ -38,10 +37,6 @@ use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_index::vec::Idx;
 use rustc_serialize::{self, Decoder, Encoder};
-use rustc_target::spec::abi::Abi;
-
-#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert_size;
 
 use std::fmt;
 
@@ -90,7 +85,7 @@ impl fmt::Debug for Lifetime {
 
 impl fmt::Display for Lifetime {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ident.name.as_str())
+        write!(f, "{}", self.ident.name)
     }
 }
 
@@ -539,7 +534,7 @@ pub struct Pat {
 impl Pat {
     /// Attempt reparsing the pattern as a type.
     /// This is intended for use by diagnostics.
-    pub(super) fn to_ty(&self) -> Option<P<Ty>> {
+    pub fn to_ty(&self) -> Option<P<Ty>> {
         let kind = match &self.kind {
             // In a type expression `_` is an inference variable.
             PatKind::Wild => TyKind::Infer,
@@ -735,6 +730,30 @@ pub enum Mutability {
     Immutable,
 }
 
+impl Mutability {
+    /// Returns `MutMutable` only if both `self` and `other` are mutable.
+    pub fn and(self, other: Self) -> Self {
+        match self {
+            Mutability::Mutable => other,
+            Mutability::Immutable => Mutability::Immutable,
+        }
+    }
+
+    pub fn invert(self) -> Self {
+        match self {
+            Mutability::Mutable => Mutability::Immutable,
+            Mutability::Immutable => Mutability::Mutable,
+        }
+    }
+
+    pub fn prefix_str(&self) -> &'static str {
+        match self {
+            Mutability::Mutable => "mut ",
+            Mutability::Immutable => "",
+        }
+    }
+}
+
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum BinOpKind {
     /// The `+` operator (addition)
@@ -1006,7 +1025,7 @@ pub struct Expr {
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(Expr, 96);
+rustc_data_structures::static_assert_size!(Expr, 96);
 
 impl Expr {
     /// Returns `true` if this expression would be valid somewhere that expects a value;
@@ -1033,7 +1052,7 @@ impl Expr {
         }
     }
 
-    fn to_bound(&self) -> Option<GenericBound> {
+    pub fn to_bound(&self) -> Option<GenericBound> {
         match &self.kind {
             ExprKind::Path(None, path) => Some(GenericBound::Trait(
                 PolyTraitRef::new(Vec::new(), path.clone(), self.span),
@@ -1044,7 +1063,7 @@ impl Expr {
     }
 
     /// Attempts to reparse as `Ty` (for diagnostic purposes).
-    pub(super) fn to_ty(&self) -> Option<P<Ty>> {
+    pub fn to_ty(&self) -> Option<P<Ty>> {
         let kind = match &self.kind {
             // Trivial conversions.
             ExprKind::Path(qself, path) => TyKind::Path(qself.clone(), path.clone()),
@@ -1317,10 +1336,14 @@ pub enum CaptureBy {
     Ref,
 }
 
-/// The movability of a generator / closure literal.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
+/// The movability of a generator / closure literal:
+/// whether a generator contains self-references, causing it to be `!Unpin`.
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+         RustcEncodable, RustcDecodable, Debug, Copy)]
 pub enum Movability {
+    /// May contain self-references, `!Unpin`.
     Static,
+    /// Must not contain self-references, `Unpin`.
     Movable,
 }
 
@@ -1401,7 +1424,7 @@ pub struct Lit {
 
 // Clippy uses Hash and PartialEq
 /// Type of the integer literal based on provided suffix.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
 pub enum LitIntType {
     /// e.g. `42_i32`.
     Signed(IntTy),
@@ -1411,6 +1434,15 @@ pub enum LitIntType {
     Unsuffixed,
 }
 
+/// Type of the float literal based on provided suffix.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
+pub enum LitFloatType {
+    /// A float literal with a suffix (`1f32` or `1E10f32`).
+    Suffixed(FloatTy),
+    /// A float literal without a suffix (`1.0 or 1.0E10`).
+    Unsuffixed,
+}
+
 /// Literal kind.
 ///
 /// E.g., `"foo"`, `42`, `12.34`, or `bool`.
@@ -1428,9 +1460,7 @@ pub enum LitKind {
     /// An integer literal (`1`).
     Int(u128, LitIntType),
     /// A float literal (`1f64` or `1E10f64`).
-    Float(Symbol, FloatTy),
-    /// A float literal without a suffix (`1.0 or 1.0E10`).
-    FloatUnsuffixed(Symbol),
+    Float(Symbol, LitFloatType),
     /// A boolean literal.
     Bool(bool),
     /// Placeholder for a literal that wasn't well-formed in some way.
@@ -1457,7 +1487,7 @@ impl LitKind {
     /// Returns `true` if this is a numeric literal.
     pub fn is_numeric(&self) -> bool {
         match *self {
-            LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => true,
+            LitKind::Int(..) | LitKind::Float(..) => true,
             _ => false,
         }
     }
@@ -1474,14 +1504,14 @@ impl LitKind {
             // suffixed variants
             LitKind::Int(_, LitIntType::Signed(..))
             | LitKind::Int(_, LitIntType::Unsigned(..))
-            | LitKind::Float(..) => true,
+            | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
             // unsuffixed variants
             LitKind::Str(..)
             | LitKind::ByteStr(..)
             | LitKind::Byte(..)
             | LitKind::Char(..)
             | LitKind::Int(_, LitIntType::Unsuffixed)
-            | LitKind::FloatUnsuffixed(..)
+            | LitKind::Float(_, LitFloatType::Unsuffixed)
             | LitKind::Bool(..)
             | LitKind::Err(..) => false,
         }
@@ -1496,10 +1526,10 @@ pub struct MutTy {
     pub mutbl: Mutability,
 }
 
-/// Represents a method's signature in a trait declaration,
-/// or in an implementation.
+/// Represents a function's signature in a trait declaration,
+/// trait implementation, or free function.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct MethodSig {
+pub struct FnSig {
     pub header: FnHeader,
     pub decl: P<FnDecl>,
 }
@@ -1523,7 +1553,7 @@ pub struct TraitItem {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum TraitItemKind {
     Const(P<Ty>, Option<P<Expr>>),
-    Method(MethodSig, Option<P<Block>>),
+    Method(FnSig, Option<P<Block>>),
     Type(GenericBounds, Option<P<Ty>>),
     Macro(Mac),
 }
@@ -1547,13 +1577,42 @@ pub struct ImplItem {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum ImplItemKind {
     Const(P<Ty>, P<Expr>),
-    Method(MethodSig, P<Block>),
+    Method(FnSig, P<Block>),
     TyAlias(P<Ty>),
     OpaqueTy(GenericBounds),
     Macro(Mac),
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
+pub enum FloatTy {
+    F32,
+    F64,
+}
+
+impl FloatTy {
+    pub fn name_str(self) -> &'static str {
+        match self {
+            FloatTy::F32 => "f32",
+            FloatTy::F64 => "f64",
+        }
+    }
+
+    pub fn name(self) -> Symbol {
+        match self {
+            FloatTy::F32 => sym::f32,
+            FloatTy::F64 => sym::f64,
+        }
+    }
+
+    pub fn bit_width(self) -> usize {
+        match self {
+            FloatTy::F32 => 32,
+            FloatTy::F64 => 64,
+        }
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub enum IntTy {
     Isize,
     I8,
@@ -1563,20 +1622,8 @@ pub enum IntTy {
     I128,
 }
 
-impl fmt::Debug for IntTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Display for IntTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ty_to_string())
-    }
-}
-
 impl IntTy {
-    pub fn ty_to_string(&self) -> &'static str {
+    pub fn name_str(&self) -> &'static str {
         match *self {
             IntTy::Isize => "isize",
             IntTy::I8 => "i8",
@@ -1587,7 +1634,7 @@ impl IntTy {
         }
     }
 
-    pub fn to_symbol(&self) -> Symbol {
+    pub fn name(&self) -> Symbol {
         match *self {
             IntTy::Isize => sym::isize,
             IntTy::I8 => sym::i8,
@@ -1602,7 +1649,7 @@ impl IntTy {
         // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
         // are parsed as `u128`, so we wouldn't want to print an extra negative
         // sign.
-        format!("{}{}", val as u128, self.ty_to_string())
+        format!("{}{}", val as u128, self.name_str())
     }
 
     pub fn bit_width(&self) -> Option<usize> {
@@ -1617,7 +1664,7 @@ impl IntTy {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy, Debug)]
 pub enum UintTy {
     Usize,
     U8,
@@ -1628,7 +1675,7 @@ pub enum UintTy {
 }
 
 impl UintTy {
-    pub fn ty_to_string(&self) -> &'static str {
+    pub fn name_str(&self) -> &'static str {
         match *self {
             UintTy::Usize => "usize",
             UintTy::U8 => "u8",
@@ -1639,7 +1686,7 @@ impl UintTy {
         }
     }
 
-    pub fn to_symbol(&self) -> Symbol {
+    pub fn name(&self) -> Symbol {
         match *self {
             UintTy::Usize => sym::usize,
             UintTy::U8 => sym::u8,
@@ -1651,7 +1698,7 @@ impl UintTy {
     }
 
     pub fn val_to_string(&self, val: u128) -> String {
-        format!("{}{}", val, self.ty_to_string())
+        format!("{}{}", val, self.name_str())
     }
 
     pub fn bit_width(&self) -> Option<usize> {
@@ -1666,18 +1713,6 @@ impl UintTy {
     }
 }
 
-impl fmt::Debug for UintTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Display for UintTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ty_to_string())
-    }
-}
-
 /// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -1957,12 +1992,34 @@ pub enum IsAuto {
     No,
 }
 
-#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
+         RustcEncodable, RustcDecodable, Debug)]
 pub enum Unsafety {
     Unsafe,
     Normal,
 }
 
+impl Unsafety {
+    pub fn prefix_str(&self) -> &'static str {
+        match self {
+            Unsafety::Unsafe => "unsafe ",
+            Unsafety::Normal => "",
+        }
+    }
+}
+
+impl fmt::Display for Unsafety {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(
+            match *self {
+                Unsafety::Normal => "normal",
+                Unsafety::Unsafe => "unsafe",
+            },
+            f,
+        )
+    }
+}
+
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum IsAsync {
     Async {
@@ -2007,18 +2064,6 @@ pub enum Defaultness {
     Final,
 }
 
-impl fmt::Display for Unsafety {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(
-            match *self {
-                Unsafety::Normal => "normal",
-                Unsafety::Unsafe => "unsafe",
-            },
-            f,
-        )
-    }
-}
-
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum ImplPolarity {
     /// `impl Trait for Type`
@@ -2190,22 +2235,29 @@ pub struct AttrItem {
 }
 
 /// Metadata associated with an item.
-/// Doc-comments are promoted to attributes that have `is_sugared_doc = true`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Attribute {
-    pub item: AttrItem,
+    pub kind: AttrKind,
     pub id: AttrId,
     /// Denotes if the attribute decorates the following construct (outer)
     /// or the construct this attribute is contained within (inner).
     pub style: AttrStyle,
-    pub is_sugared_doc: bool,
     pub span: Span,
 }
 
-// Compatibility impl to avoid churn, consider removing.
-impl std::ops::Deref for Attribute {
-    type Target = AttrItem;
-    fn deref(&self) -> &Self::Target { &self.item }
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub enum AttrKind {
+    /// A normal attribute.
+    Normal(AttrItem),
+
+    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
+    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
+    /// variant (which is much less compact and thus more expensive).
+    ///
+    /// Note: `self.has_name(sym::doc)` and `self.check_name(sym::doc)` succeed
+    /// for this variant, but this may change in the future.
+    /// ```
+    DocComment(Symbol),
 }
 
 /// `TraitRef`s appear in impls.
@@ -2351,6 +2403,27 @@ impl Item {
     }
 }
 
+/// A reference to an ABI.
+///
+/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
+pub struct Abi {
+    pub symbol: Symbol,
+    pub span: Span,
+}
+
+impl Abi {
+    pub fn new(symbol: Symbol, span: Span) -> Self {
+        Self { symbol, span }
+    }
+}
+
+impl Default for Abi {
+    fn default() -> Self {
+        Self::new(sym::Rust, DUMMY_SP)
+    }
+}
+
 /// A function header.
 ///
 /// All the information between the visibility and the name of the function is
@@ -2369,7 +2442,7 @@ impl Default for FnHeader {
             unsafety: Unsafety::Normal,
             asyncness: dummy_spanned(IsAsync::NotAsync),
             constness: dummy_spanned(Constness::NotConst),
-            abi: Abi::Rust,
+            abi: Abi::default(),
         }
     }
 }
@@ -2395,7 +2468,7 @@ pub enum ItemKind {
     /// A function declaration (`fn`).
     ///
     /// E.g., `fn foo(bar: usize) -> usize { .. }`.
-    Fn(P<FnDecl>, FnHeader, Generics, P<Block>),
+    Fn(FnSig, Generics, P<Block>),
     /// A module declaration (`mod`).
     ///
     /// E.g., `mod foo;` or `mod foo { .. }`.
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 84c86c9651f..2b759c205f5 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -1,12 +1,12 @@
 //! Parsing and validation of builtin attributes
 
 use crate::ast::{self, Attribute, MetaItem, NestedMetaItem};
-use crate::early_buffered_lints::BufferedEarlyLintId;
 use crate::feature_gate::{Features, GatedCfg};
 use crate::print::pprust;
 use crate::sess::ParseSess;
 
 use errors::{Applicability, Handler};
+use std::num::NonZeroU32;
 use syntax_pos::hygiene::Transparency;
 use syntax_pos::{symbol::Symbol, symbol::sym, Span};
 
@@ -25,9 +25,9 @@ enum AttrError {
 /// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
 #[derive(Clone, Copy)]
 pub struct AttributeTemplate {
-    crate word: bool,
-    crate list: Option<&'static str>,
-    crate name_value_str: Option<&'static str>,
+    pub word: bool,
+    pub list: Option<&'static str>,
+    pub name_value_str: Option<&'static str>,
 }
 
 impl AttributeTemplate {
@@ -36,7 +36,7 @@ impl AttributeTemplate {
     }
 
     /// Checks that the given meta-item is compatible with this template.
-    fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool {
+    pub fn compatible(&self, meta_item_kind: &ast::MetaItemKind) -> bool {
         match meta_item_kind {
             ast::MetaItemKind::Word => self.word,
             ast::MetaItemKind::List(..) => self.list.is_some(),
@@ -158,7 +158,7 @@ pub struct Stability {
 #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
 pub enum StabilityLevel {
     // Reason for the current stability level and the relevant rust-lang issue
-    Unstable { reason: Option<Symbol>, issue: u32, is_soft: bool },
+    Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
     Stable { since: Symbol },
 }
 
@@ -228,7 +228,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
             sym::stable,
             sym::rustc_promotable,
             sym::rustc_allow_const_fn_ptr,
-        ].iter().any(|&s| attr.path == s) {
+        ].iter().any(|&s| attr.has_name(s)) {
             continue // not a stability level
         }
 
@@ -236,10 +236,10 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
 
         let meta = attr.meta();
 
-        if attr.path == sym::rustc_promotable {
+        if attr.has_name(sym::rustc_promotable) {
             promotable = true;
         }
-        if attr.path == sym::rustc_allow_const_fn_ptr {
+        if attr.has_name(sym::rustc_allow_const_fn_ptr) {
             allow_const_fn_ptr = true;
         }
         // attributes with data
@@ -395,18 +395,28 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
 
                     match (feature, reason, issue) {
                         (Some(feature), reason, Some(issue)) => {
+                            let issue = match &*issue.as_str() {
+                                // FIXME(rossmacarthur): remove "0" because "none" should be used
+                                // See #41260
+                                "none" | "0" => None,
+                                issue => {
+                                    if let Ok(num) = issue.parse() {
+                                        NonZeroU32::new(num)
+                                    } else {
+                                        span_err!(
+                                            diagnostic,
+                                            attr.span,
+                                            E0545,
+                                            "incorrect 'issue'"
+                                        );
+                                        continue
+                                    }
+                                }
+                            };
                             stab = Some(Stability {
                                 level: Unstable {
                                     reason,
-                                    issue: {
-                                        if let Ok(issue) = issue.as_str().parse() {
-                                            issue
-                                        } else {
-                                            span_err!(diagnostic, attr.span, E0545,
-                                                      "incorrect 'issue'");
-                                            continue
-                                        }
-                                    },
+                                    issue,
                                     is_soft,
                                 },
                                 feature,
@@ -778,7 +788,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
 
     let mut acc = Vec::new();
     let diagnostic = &sess.span_diagnostic;
-    if attr.path == sym::repr {
+    if attr.has_name(sym::repr) {
         if let Some(items) = attr.meta_item_list() {
             mark_used(attr);
             for item in items {
@@ -938,69 +948,3 @@ pub fn find_transparency(
     let fallback = if is_legacy { Transparency::SemiTransparent } else { Transparency::Opaque };
     (transparency.map_or(fallback, |t| t.0), error)
 }
-
-pub fn check_builtin_attribute(
-    sess: &ParseSess, attr: &ast::Attribute, name: Symbol, template: AttributeTemplate
-) {
-    // Some special attributes like `cfg` must be checked
-    // before the generic check, so we skip them here.
-    let should_skip = |name| name == sym::cfg;
-    // Some of previously accepted forms were used in practice,
-    // report them as warnings for now.
-    let should_warn = |name| name == sym::doc || name == sym::ignore ||
-                             name == sym::inline || name == sym::link ||
-                             name == sym::test || name == sym::bench;
-
-    match attr.parse_meta(sess) {
-        Ok(meta) => if !should_skip(name) && !template.compatible(&meta.kind) {
-            let error_msg = format!("malformed `{}` attribute input", name);
-            let mut msg = "attribute must be of the form ".to_owned();
-            let mut suggestions = vec![];
-            let mut first = true;
-            if template.word {
-                first = false;
-                let code = format!("#[{}]", name);
-                msg.push_str(&format!("`{}`", &code));
-                suggestions.push(code);
-            }
-            if let Some(descr) = template.list {
-                if !first {
-                    msg.push_str(" or ");
-                }
-                first = false;
-                let code = format!("#[{}({})]", name, descr);
-                msg.push_str(&format!("`{}`", &code));
-                suggestions.push(code);
-            }
-            if let Some(descr) = template.name_value_str {
-                if !first {
-                    msg.push_str(" or ");
-                }
-                let code = format!("#[{} = \"{}\"]", name, descr);
-                msg.push_str(&format!("`{}`", &code));
-                suggestions.push(code);
-            }
-            if should_warn(name) {
-                sess.buffer_lint(
-                    BufferedEarlyLintId::IllFormedAttributeInput,
-                    meta.span,
-                    ast::CRATE_NODE_ID,
-                    &msg,
-                );
-            } else {
-                sess.span_diagnostic.struct_span_err(meta.span, &error_msg)
-                    .span_suggestions(
-                        meta.span,
-                        if suggestions.len() == 1 {
-                            "must be of the form"
-                        } else {
-                            "the following are the possible correct uses"
-                        },
-                        suggestions.into_iter(),
-                        Applicability::HasPlaceholders,
-                    ).emit();
-            }
-        }
-        Err(mut err) => err.emit(),
-    }
-}
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 3e240a855e2..29eff5c2981 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -9,17 +9,13 @@ pub use StabilityLevel::*;
 pub use crate::ast::Attribute;
 
 use crate::ast;
-use crate::ast::{AttrItem, AttrId, AttrStyle, Name, Ident, Path, PathSegment};
+use crate::ast::{AttrItem, AttrId, AttrKind, AttrStyle, Name, Ident, Path, PathSegment};
 use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem};
 use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam};
 use crate::mut_visit::visit_clobber;
 use crate::source_map::{BytePos, Spanned};
-use crate::parse::lexer::comments::doc_comment_style;
-use crate::parse;
-use crate::parse::PResult;
-use crate::parse::token::{self, Token};
+use crate::token::{self, Token};
 use crate::ptr::P;
-use crate::sess::ParseSess;
 use crate::symbol::{sym, Symbol};
 use crate::ThinVec;
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
@@ -145,12 +141,17 @@ impl NestedMetaItem {
 }
 
 impl Attribute {
+    pub fn has_name(&self, name: Symbol) -> bool {
+        match self.kind {
+            AttrKind::Normal(ref item) => item.path == name,
+            AttrKind::DocComment(_) => name == sym::doc,
+        }
+    }
+
     /// Returns `true` if the attribute's path matches the argument. If it matches, then the
     /// attribute is marked as used.
-    ///
-    /// To check the attribute name without marking it used, use the `path` field directly.
     pub fn check_name(&self, name: Symbol) -> bool {
-        let matches = self.path == name;
+        let matches = self.has_name(name);
         if matches {
             mark_used(self);
         }
@@ -159,10 +160,15 @@ impl Attribute {
 
     /// For a single-segment attribute, returns its name; otherwise, returns `None`.
     pub fn ident(&self) -> Option<Ident> {
-        if self.path.segments.len() == 1 {
-            Some(self.path.segments[0].ident)
-        } else {
-            None
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                if item.path.segments.len() == 1 {
+                    Some(item.path.segments[0].ident)
+                } else {
+                    None
+                }
+            }
+            AttrKind::DocComment(_) => Some(Ident::new(sym::doc, self.span)),
         }
     }
     pub fn name_or_empty(&self) -> Symbol {
@@ -170,18 +176,32 @@ impl Attribute {
     }
 
     pub fn value_str(&self) -> Option<Symbol> {
-        self.meta().and_then(|meta| meta.value_str())
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                item.meta(self.span).and_then(|meta| meta.value_str())
+            }
+            AttrKind::DocComment(comment) => Some(comment),
+        }
     }
 
     pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
-        match self.meta() {
-            Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
-            _ => None
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                match item.meta(self.span) {
+                    Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
+                    _ => None
+                }
+            }
+            AttrKind::DocComment(_) => None,
         }
     }
 
     pub fn is_word(&self) -> bool {
-        self.tokens.is_empty()
+        if let AttrKind::Normal(item) = &self.kind {
+            item.tokens.is_empty()
+        } else {
+            false
+        }
     }
 
     pub fn is_meta_item_list(&self) -> bool {
@@ -257,7 +277,7 @@ impl MetaItem {
 }
 
 impl AttrItem {
-    crate fn meta(&self, span: Span) -> Option<MetaItem> {
+    pub fn meta(&self, span: Span) -> Option<MetaItem> {
         let mut tokens = self.tokens.trees().peekable();
         Some(MetaItem {
             path: self.path.clone(),
@@ -275,17 +295,34 @@ impl AttrItem {
 }
 
 impl Attribute {
-    /// Extracts the MetaItem from inside this Attribute.
-    pub fn meta(&self) -> Option<MetaItem> {
-        self.item.meta(self.span)
+    pub fn is_doc_comment(&self) -> bool {
+        match self.kind {
+            AttrKind::Normal(_) => false,
+            AttrKind::DocComment(_) => true,
+        }
     }
 
-    pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
-        Ok(MetaItem {
-            path: self.path.clone(),
-            kind: parse::parse_in_attr(sess, self, |p| p.parse_meta_item_kind())?,
-            span: self.span,
-        })
+    pub fn get_normal_item(&self) -> &AttrItem {
+        match self.kind {
+            AttrKind::Normal(ref item) => item,
+            AttrKind::DocComment(_) => panic!("unexpected sugared doc"),
+        }
+    }
+
+    pub fn unwrap_normal_item(self) -> AttrItem {
+        match self.kind {
+            AttrKind::Normal(item) => item,
+            AttrKind::DocComment(_) => panic!("unexpected sugared doc"),
+        }
+    }
+
+    /// Extracts the MetaItem from inside this Attribute.
+    pub fn meta(&self) -> Option<MetaItem> {
+        match self.kind {
+            AttrKind::Normal(ref item) => item.meta(self.span),
+            AttrKind::DocComment(comment) =>
+                Some(mk_name_value_item_str(Ident::new(sym::doc, self.span), comment, self.span)),
+        }
     }
 }
 
@@ -326,11 +363,14 @@ crate fn mk_attr_id() -> AttrId {
 }
 
 pub fn mk_attr(style: AttrStyle, path: Path, tokens: TokenStream, span: Span) -> Attribute {
+    mk_attr_from_item(style, AttrItem { path, tokens }, span)
+}
+
+pub fn mk_attr_from_item(style: AttrStyle, item: AttrItem, span: Span) -> Attribute {
     Attribute {
-        item: AttrItem { path, tokens },
+        kind: AttrKind::Normal(item),
         id: mk_attr_id(),
         style,
-        is_sugared_doc: false,
         span,
     }
 }
@@ -345,18 +385,11 @@ pub fn mk_attr_outer(item: MetaItem) -> Attribute {
     mk_attr(AttrStyle::Outer, item.path, item.kind.tokens(item.span), item.span)
 }
 
-pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute {
-    let style = doc_comment_style(&text.as_str());
-    let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked);
-    let lit = Lit::from_lit_kind(lit_kind, span);
+pub fn mk_doc_comment(style: AttrStyle, comment: Symbol, span: Span) -> Attribute {
     Attribute {
-        item: AttrItem {
-            path: Path::from_ident(Ident::with_dummy_span(sym::doc).with_span_pos(span)),
-            tokens: MetaItemKind::NameValue(lit).tokens(span),
-        },
+        kind: AttrKind::DocComment(comment),
         id: mk_attr_id(),
         style,
-        is_sugared_doc: true,
         span,
     }
 }
diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs
index 941df5ea570..0e81de7d4a7 100644
--- a/src/libsyntax/error_codes.rs
+++ b/src/libsyntax/error_codes.rs
@@ -4,28 +4,6 @@
 // `:set tw=0` to disable.
 register_diagnostics! {
 
-E0178: r##"
-In types, the `+` type operator has low precedence, so it is often necessary
-to use parentheses.
-
-For example:
-
-```compile_fail,E0178
-trait Foo {}
-
-struct Bar<'a> {
-    w: &'a Foo + Copy,   // error, use &'a (Foo + Copy)
-    x: &'a Foo + 'a,     // error, use &'a (Foo + 'a)
-    y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a)
-    z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a)
-}
-```
-
-More details can be found in [RFC 438].
-
-[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
-"##,
-
 E0536: r##"
 The `not` cfg-predicate was malformed.
 
@@ -278,106 +256,6 @@ pub fn something() {}
 ```
 "##,
 
-E0583: r##"
-A file wasn't found for an out-of-line module.
-
-Erroneous code example:
-
-```ignore (compile_fail not working here; see Issue #43707)
-mod file_that_doesnt_exist; // error: file not found for module
-
-fn main() {}
-```
-
-Please be sure that a file corresponding to the module exists. If you
-want to use a module named `file_that_doesnt_exist`, you need to have a file
-named `file_that_doesnt_exist.rs` or `file_that_doesnt_exist/mod.rs` in the
-same directory.
-"##,
-
-E0584: r##"
-A doc comment that is not attached to anything has been encountered.
-
-Erroneous code example:
-
-```compile_fail,E0584
-trait Island {
-    fn lost();
-
-    /// I'm lost!
-}
-```
-
-A little reminder: a doc comment has to be placed before the item it's supposed
-to document. So if you want to document the `Island` trait, you need to put a
-doc comment before it, not inside it. Same goes for the `lost` method: the doc
-comment needs to be before it:
-
-```
-/// I'm THE island!
-trait Island {
-    /// I'm lost!
-    fn lost();
-}
-```
-"##,
-
-E0585: r##"
-A documentation comment that doesn't document anything was found.
-
-Erroneous code example:
-
-```compile_fail,E0585
-fn main() {
-    // The following doc comment will fail:
-    /// This is a useless doc comment!
-}
-```
-
-Documentation comments need to be followed by items, including functions,
-types, modules, etc. Examples:
-
-```
-/// I'm documenting the following struct:
-struct Foo;
-
-/// I'm documenting the following function:
-fn foo() {}
-```
-"##,
-
-E0586: r##"
-An inclusive range was used with no end.
-
-Erroneous code example:
-
-```compile_fail,E0586
-fn main() {
-    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
-    let x = &tmp[1..=]; // error: inclusive range was used with no end
-}
-```
-
-An inclusive range needs an end in order to *include* it. If you just need a
-start and no end, use a non-inclusive range (with `..`):
-
-```
-fn main() {
-    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
-    let x = &tmp[1..]; // ok!
-}
-```
-
-Or put an end to your inclusive range:
-
-```
-fn main() {
-    let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1];
-    let x = &tmp[1..=3]; // ok!
-}
-```
-"##,
-
 E0589: r##"
 The value of `N` that was specified for `repr(align(N))` was not a power
 of two, or was greater than 2^29.
@@ -446,35 +324,6 @@ and likely to change in the future.
 
 "##,
 
-E0704: r##"
-This error indicates that a incorrect visibility restriction was specified.
-
-Example of erroneous code:
-
-```compile_fail,E0704
-mod foo {
-    pub(foo) struct Bar {
-        x: i32
-    }
-}
-```
-
-To make struct `Bar` only visible in module `foo` the `in` keyword should be
-used:
-```
-mod foo {
-    pub(in crate::foo) struct Bar {
-        x: i32
-    }
-}
-# fn main() {}
-```
-
-For more information see the Rust Reference on [Visibility].
-
-[Visibility]: https://doc.rust-lang.org/reference/visibility-and-privacy.html
-"##,
-
 E0705: r##"
 A `#![feature]` attribute was declared for a feature that is stable in
 the current edition, but not in all editions.
@@ -504,20 +353,6 @@ Delete the offending feature attribute, or add it to the list of allowed
 features in the `-Z allow_features` flag.
 "##,
 
-E0743: r##"
-C-variadic has been used on a non-foreign function.
-
-Erroneous code example:
-
-```compile_fail,E0743
-fn foo2(x: u8, ...) {} // error!
-```
-
-Only foreign functions can use C-variadic (`...`). It is used to give an
-undefined number of parameters to a given function (like `printf` in C). The
-equivalent in Rust would be to use macros directly.
-"##,
-
 ;
 
     E0539, // incorrect meta item
@@ -540,6 +375,5 @@ equivalent in Rust would be to use macros directly.
     E0630,
     E0693, // incorrect `repr(align)` attribute format
 //  E0694, // an unknown tool name found in scoped attributes
-    E0703, // invalid ABI
     E0717, // rustc_promotable without stability attribute
 }
diff --git a/src/libsyntax/expand/mod.rs b/src/libsyntax/expand/mod.rs
index 038f60287be..03b30fda745 100644
--- a/src/libsyntax/expand/mod.rs
+++ b/src/libsyntax/expand/mod.rs
@@ -5,16 +5,6 @@ use syntax_pos::symbol::sym;
 
 pub mod allocator;
 
-bitflags::bitflags! {
-    /// Built-in derives that need some extra tracking beyond the usual macro functionality.
-    #[derive(Default)]
-    pub struct SpecialDerives: u8 {
-        const PARTIAL_EQ = 1 << 0;
-        const EQ         = 1 << 1;
-        const COPY       = 1 << 2;
-    }
-}
-
 pub fn is_proc_macro_attr(attr: &Attribute) -> bool {
     [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
         .iter().any(|kind| attr.check_name(*kind))
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index a1cf2d42108..0107611460b 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -253,6 +253,9 @@ declare_features! (
     (accepted, const_constructor, "1.40.0", Some(61456), None),
     /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
     (accepted, cfg_doctest, "1.40.0", Some(62210), None),
+    /// Allows relaxing the coherence rules such that
+    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
+    (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 736a363bbfc..2819ee273d9 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -134,9 +134,6 @@ declare_features! (
     /// Allows using `rustc_*` attributes (RFC 572).
     (active, rustc_attrs, "1.0.0", Some(29642), None),
 
-    /// Allows using `#[on_unimplemented(..)]` on traits.
-    (active, on_unimplemented, "1.0.0", Some(29628), None),
-
     /// Allows using the `box $expr` syntax.
     (active, box_syntax, "1.0.0", Some(49733), None),
 
@@ -210,10 +207,10 @@ declare_features! (
     /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
     (active, allocator_internals, "1.20.0", None, None),
 
-    // no-tracking-issue-end
-
     /// Added for testing E0705; perma-unstable.
-    (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
+    (active, test_2018_feature, "1.31.0", None, Some(Edition::Edition2018)),
+
+    // no-tracking-issue-end
 
     // -------------------------------------------------------------------------
     // feature-group-end: internal feature gates
@@ -268,9 +265,6 @@ declare_features! (
     /// Allows the use of SIMD types in functions declared in `extern` blocks.
     (active, simd_ffi, "1.0.0", Some(27731), None),
 
-    /// Allows using custom attributes (RFC 572).
-    (active, custom_attribute, "1.0.0", Some(29642), None),
-
     /// Allows using non lexical lifetimes (RFC 2094).
     (active, nll, "1.0.0", Some(43234), None),
 
@@ -469,10 +463,6 @@ declare_features! (
     /// Allows exhaustive integer pattern matching on `usize` and `isize`.
     (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
-    /// Allows relaxing the coherence rules such that
-    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
-    (active, re_rebalance_coherence, "1.32.0", Some(55437), None),
-
     /// Allows using `#[ffi_returns_twice]` on foreign functions.
     (active, ffi_returns_twice, "1.34.0", Some(58314), None),
 
@@ -533,6 +523,12 @@ declare_features! (
     /// Allows using the `efiapi` ABI.
     (active, abi_efiapi, "1.40.0", Some(65815), None),
 
+    /// Allows using the `#[register_attr]` attribute.
+    (active, register_attr, "1.41.0", Some(66080), None),
+
+    /// Allows using the `#[register_attr]` attribute.
+    (active, register_tool, "1.41.0", Some(66079), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index eb811c3e0ff..608cc2a09cb 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -166,7 +166,7 @@ macro_rules! experimental {
 }
 
 const IMPL_DETAIL: &str = "internal implementation detail";
-const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
+const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
 
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
@@ -329,6 +329,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
     gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),
+    gated!(
+        register_attr, CrateLevel, template!(List: "attr1, attr2, ..."),
+        experimental!(register_attr),
+    ),
+    gated!(
+        register_tool, CrateLevel, template!(List: "tool1, tool2, ..."),
+        experimental!(register_tool),
+    ),
 
     // ==========================================================================
     // Internal attributes: Stability, deprecation, and unsafe:
@@ -418,14 +426,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
         "the `linkage` attribute is experimental and not portable across platforms",
     ),
-    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Macro related:
     // ==========================================================================
 
     rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
     rustc_attr!(
         rustc_macro_transparency, Whitelisted,
         template!(NameValueStr: "transparent|semitransparent|opaque"),
@@ -436,17 +444,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Internal attributes, Diagnostics related:
     // ==========================================================================
 
-    gated!(
+    rustc_attr!(
         rustc_on_unimplemented, Whitelisted,
         template!(
             List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
             NameValueStr: "message"
         ),
-        on_unimplemented,
-        experimental!(rustc_on_unimplemented),
+        INTERNAL_UNSTABLE
     ),
     // Whitelists "identity-like" conversion methods to suggest on type mismatch.
-    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Const related:
@@ -454,7 +461,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL),
     rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Layout related:
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 13a24ca046d..3bf1e24bf12 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -3,26 +3,22 @@ use super::accepted::ACCEPTED_FEATURES;
 use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 use super::builtin_attrs::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
 
-use crate::ast::{
-    self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
-    PatKind, RangeEnd, VariantData,
-};
-use crate::attr::{self, check_builtin_attribute};
+use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
+use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
+use crate::attr;
 use crate::source_map::Spanned;
 use crate::edition::{ALL_EDITIONS, Edition};
 use crate::visit::{self, FnKind, Visitor};
-use crate::parse::token;
 use crate::sess::ParseSess;
 use crate::symbol::{Symbol, sym};
-use crate::tokenstream::TokenTree;
 
 use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
 
 use std::env;
+use std::num::NonZeroU32;
 
 #[derive(Copy, Clone, Debug)]
 pub enum Stability {
@@ -60,25 +56,28 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
     PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
 }
 
-fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
+fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
     if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.name == feature) {
         // FIXME (#28244): enforce that active features have issue numbers
-        // assert!(info.issue.is_some())
-        info.issue
+        // assert!(info.issue().is_some())
+        info.issue()
     } else {
         // search in Accepted, Removed, or Stable Removed features
-        let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
+        let found = ACCEPTED_FEATURES
+            .iter()
+            .chain(REMOVED_FEATURES)
+            .chain(STABLE_REMOVED_FEATURES)
             .find(|t| t.name == feature);
         match found {
-            Some(&Feature { issue, .. }) => issue,
-            None => panic!("Feature `{}` is not declared anywhere", feature),
+            Some(found) => found.issue(),
+            None => panic!("feature `{}` is not declared anywhere", feature),
         }
     }
 }
 
 pub enum GateIssue {
     Language,
-    Library(Option<u32>)
+    Library(Option<NonZeroU32>)
 }
 
 #[derive(Debug, Copy, Clone, PartialEq)]
@@ -131,14 +130,11 @@ fn leveled_feature_err<'a, S: Into<MultiSpan>>(
         GateStrength::Soft => diag.struct_span_warn(span, explain),
     };
 
-    match issue {
-        None | Some(0) => {}  // We still accept `0` as a stand-in for backwards compatibility
-        Some(n) => {
-            err.note(&format!(
-                "for more information, see https://github.com/rust-lang/rust/issues/{}",
-                n,
-            ));
-        }
+    if let Some(n) = issue {
+        err.note(&format!(
+            "for more information, see https://github.com/rust-lang/rust/issues/{}",
+            n,
+        ));
     }
 
     // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
@@ -192,62 +188,70 @@ macro_rules! gate_feature_post {
 }
 
 impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: Abi, span: Span) {
-        match abi {
-            Abi::RustIntrinsic => {
+    fn check_abi(&self, abi: ast::Abi) {
+        let ast::Abi { symbol, span } = abi;
+
+        match &*symbol.as_str() {
+            // Stable
+            "Rust" |
+            "C" |
+            "cdecl" |
+            "stdcall" |
+            "fastcall" |
+            "aapcs" |
+            "win64" |
+            "sysv64" |
+            "system" => {}
+            "rust-intrinsic" => {
                 gate_feature_post!(&self, intrinsics, span,
                                    "intrinsics are subject to change");
             },
-            Abi::PlatformIntrinsic => {
+            "platform-intrinsic" => {
                 gate_feature_post!(&self, platform_intrinsics, span,
                                    "platform intrinsics are experimental and possibly buggy");
             },
-            Abi::Vectorcall => {
+            "vectorcall" => {
                 gate_feature_post!(&self, abi_vectorcall, span,
                                    "vectorcall is experimental and subject to change");
             },
-            Abi::Thiscall => {
+            "thiscall" => {
                 gate_feature_post!(&self, abi_thiscall, span,
                                    "thiscall is experimental and subject to change");
             },
-            Abi::RustCall => {
+            "rust-call" => {
                 gate_feature_post!(&self, unboxed_closures, span,
                                    "rust-call ABI is subject to change");
             },
-            Abi::PtxKernel => {
+            "ptx-kernel" => {
                 gate_feature_post!(&self, abi_ptx, span,
                                    "PTX ABIs are experimental and subject to change");
             },
-            Abi::Unadjusted => {
+            "unadjusted" => {
                 gate_feature_post!(&self, abi_unadjusted, span,
                                    "unadjusted ABI is an implementation detail and perma-unstable");
             },
-            Abi::Msp430Interrupt => {
+            "msp430-interrupt" => {
                 gate_feature_post!(&self, abi_msp430_interrupt, span,
                                    "msp430-interrupt ABI is experimental and subject to change");
             },
-            Abi::X86Interrupt => {
+            "x86-interrupt" => {
                 gate_feature_post!(&self, abi_x86_interrupt, span,
                                    "x86-interrupt ABI is experimental and subject to change");
             },
-            Abi::AmdGpuKernel => {
+            "amdgpu-kernel" => {
                 gate_feature_post!(&self, abi_amdgpu_kernel, span,
                                    "amdgpu-kernel ABI is experimental and subject to change");
             },
-            Abi::EfiApi => {
+            "efiapi" => {
                 gate_feature_post!(&self, abi_efiapi, span,
                                    "efiapi ABI is experimental and subject to change");
             },
-            // Stable
-            Abi::Cdecl |
-            Abi::Stdcall |
-            Abi::Fastcall |
-            Abi::Aapcs |
-            Abi::Win64 |
-            Abi::SysV64 |
-            Abi::Rust |
-            Abi::C |
-            Abi::System => {}
+            abi => {
+                self.parse_sess.span_diagnostic.delay_span_bug(
+                    span,
+                    &format!("unrecognized ABI not caught in lowering: {}", abi),
+                )
+            }
         }
     }
 
@@ -324,18 +328,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
             gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard);
         }
-        // Check input tokens for built-in and key-value attributes.
-        match attr_info {
-            // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
-            Some((name, _, template, _)) if name != sym::rustc_dummy =>
-                check_builtin_attribute(self.parse_sess, attr, name, template),
-            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
-                if token == token::Eq {
-                    // All key-value attributes are restricted to meta-item syntax.
-                    attr.parse_meta(self.parse_sess).map_err(|mut err| err.emit()).ok();
-                }
-            }
-        }
         // Check unstable flavors of the `#[doc]` attribute.
         if attr.check_name(sym::doc) {
             for nested_meta in attr.meta_item_list().unwrap_or_default() {
@@ -372,7 +364,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_item(&mut self, i: &'a ast::Item) {
         match i.kind {
             ast::ItemKind::ForeignMod(ref foreign_module) => {
-                self.check_abi(foreign_module.abi, i.span);
+                self.check_abi(foreign_module.abi);
             }
 
             ast::ItemKind::Fn(..) => {
@@ -502,7 +494,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
         match ty.kind {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_abi(bare_fn_ty.abi, ty.span);
+                self.check_abi(bare_fn_ty.abi);
             }
             ast::TyKind::Never => {
                 gate_feature_post!(&self, never_type, ty.span,
@@ -596,7 +588,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             // Stability of const fn methods are covered in
             // `visit_trait_item` and `visit_impl_item` below; this is
             // because default methods don't pass through this point.
-            self.check_abi(header.abi, span);
+            self.check_abi(header.abi);
         }
 
         if fn_decl.c_variadic() {
@@ -630,7 +622,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match ti.kind {
             ast::TraitItemKind::Method(ref sig, ref block) => {
                 if block.is_none() {
-                    self.check_abi(sig.header.abi, ti.span);
+                    self.check_abi(sig.header.abi);
                 }
                 if sig.decl.c_variadic() {
                     gate_feature_post!(&self, c_variadic, ti.span,
@@ -823,7 +815,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
             }
 
             if let Some(allowed) = allow_features.as_ref() {
-                if allowed.iter().find(|&f| f == &name.as_str() as &str).is_none() {
+                if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
                     span_err!(span_handler, mi.span(), E0725,
                               "the feature `{}` is not in the list of allowed features",
                               name);
@@ -862,18 +854,17 @@ pub fn check_crate(krate: &ast::Crate,
     maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
     let mut visitor = PostExpansionVisitor { parse_sess, features };
 
+    let spans = parse_sess.gated_spans.spans.borrow();
     macro_rules! gate_all {
-        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
-        ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*parse_sess.gated_spans.$spans.borrow() {
+        ($gate:ident, $msg:literal) => {
+            for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                 gate_feature!(&visitor, $gate, *span, $msg);
             }
         }
     }
-
     gate_all!(let_chains, "`let` expressions in this position are experimental");
     gate_all!(async_closure, "async closures are unstable");
-    gate_all!(yields, generators, "yield syntax is experimental");
+    gate_all!(generators, "yield syntax is experimental");
     gate_all!(or_patterns, "or-patterns syntax is experimental");
     gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");
 
@@ -884,7 +875,7 @@ pub fn check_crate(krate: &ast::Crate,
             // FIXME(eddyb) do something more useful than always
             // disabling these uses of early feature-gatings.
             if false {
-                for span in &*parse_sess.gated_spans.$gate.borrow() {
+                for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                     gate_feature!(&visitor, $gate, *span, $msg);
                 }
             }
@@ -901,7 +892,6 @@ pub fn check_crate(krate: &ast::Crate,
     gate_all!(try_blocks, "`try` blocks are unstable");
     gate_all!(label_break_value, "labels on blocks are unstable");
     gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
-
     // To avoid noise about type ascription in common syntax errors,
     // only emit if it is the *only* error. (Also check it last.)
     if parse_sess.span_diagnostic.err_count() == 0 {
diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs
index ba970618c0e..c4418c0f0f6 100644
--- a/src/libsyntax/feature_gate/mod.rs
+++ b/src/libsyntax/feature_gate/mod.rs
@@ -18,8 +18,9 @@ mod active;
 mod builtin_attrs;
 mod check;
 
-use std::fmt;
 use crate::{edition::Edition, symbol::Symbol};
+use std::fmt;
+use std::num::NonZeroU32;
 use syntax_pos::Span;
 
 #[derive(Clone, Copy)]
@@ -46,11 +47,17 @@ pub struct Feature {
     state: State,
     name: Symbol,
     since: &'static str,
-    issue: Option<u32>,
+    issue: Option<u32>,  // FIXME: once #58732 is done make this an Option<NonZeroU32>
     edition: Option<Edition>,
     description: &'static str,
 }
 
+impl Feature {
+    fn issue(&self) -> Option<NonZeroU32> {
+        self.issue.and_then(|i| NonZeroU32::new(i))
+    }
+}
+
 pub use active::{Features, INCOMPLETE_FEATURES};
 pub use builtin_attrs::{
     AttributeGate, AttributeType, GatedCfg,
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 2c29e1ebf14..f0aa74c65df 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -67,6 +67,9 @@ declare_features! (
      Some("merged into `#![feature(slice_patterns)]`")),
     (removed, macro_reexport, "1.0.0", Some(29638), None,
      Some("subsumed by `pub use`")),
+    /// Allows using custom attributes (RFC 572).
+    (removed, custom_attribute, "1.0.0", Some(29642), None,
+     Some("removed in favor of `#![register_tool]` and `#![register_attr]`")),
     (removed, pushpop_unsafe, "1.2.0", None, None, None),
     (removed, needs_allocator, "1.4.0", Some(27389), None,
      Some("subsumed by `#![feature(allocator_internals)]`")),
@@ -99,6 +102,9 @@ declare_features! (
     /// + `__register_diagnostic`
     /// +`__build_diagnostic_array`
     (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
+    /// Allows using `#[on_unimplemented(..)]` on traits.
+    /// (Moved to `rustc_attrs`.)
+    (removed, on_unimplemented, "1.40.0", None, None, None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
diff --git a/src/libsyntax/json/tests.rs b/src/libsyntax/json/tests.rs
index eb0d9ef3947..1edefd5bc4b 100644
--- a/src/libsyntax/json/tests.rs
+++ b/src/libsyntax/json/tests.rs
@@ -2,7 +2,6 @@ use super::*;
 
 use crate::json::JsonEmitter;
 use crate::source_map::{FilePathMapping, SourceMap};
-use crate::tests::Shared;
 use crate::with_default_globals;
 
 use errors::emitter::{ColorConfig, HumanReadableErrorType};
@@ -27,6 +26,20 @@ struct SpanTestData {
     pub column_end: u32,
 }
 
+struct Shared<T> {
+    data: Arc<Mutex<T>>,
+}
+
+impl<T: Write> Write for Shared<T> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.data.lock().unwrap().write(buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        self.data.lock().unwrap().flush()
+    }
+}
+
 /// Test the span yields correct positions in JSON.
 fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
     let expected_output = TestData { spans: vec![expected_output] };
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 7be6e6c7e18..317fcf29389 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -26,11 +26,6 @@ pub use rustc_data_structures::thin_vec::ThinVec;
 use ast::AttrId;
 use syntax_pos::edition::Edition;
 
-#[cfg(test)]
-mod tests;
-
-pub const MACRO_ARGUMENTS: Option<&'static str> = Some("macro arguments");
-
 #[macro_export]
 macro_rules! unwrap_or {
     ($opt:expr, $default:expr) => {
@@ -85,7 +80,10 @@ pub mod diagnostics {
 pub mod error_codes;
 
 pub mod util {
+    pub mod classify;
+    pub mod comments;
     pub mod lev_distance;
+    pub mod literal;
     pub mod node_count;
     pub mod parser;
     pub mod map_in_place;
@@ -97,16 +95,15 @@ pub mod ast;
 pub mod attr;
 pub mod expand;
 pub mod source_map;
-#[macro_use] pub mod config;
 pub mod entry;
 pub mod feature_gate;
 pub mod mut_visit;
-pub mod parse;
 pub mod ptr;
 pub mod show_span;
 pub use syntax_pos::edition;
 pub use syntax_pos::symbol;
 pub mod sess;
+pub mod token;
 pub mod tokenstream;
 pub mod visit;
 
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 60ee17d09b7..376323a83ea 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -9,7 +9,7 @@
 
 use crate::ast::*;
 use crate::source_map::{Spanned, respan};
-use crate::parse::token::{self, Token};
+use crate::token::{self, Token};
 use crate::ptr::P;
 use crate::ThinVec;
 use crate::tokenstream::*;
@@ -22,9 +22,6 @@ use rustc_data_structures::sync::Lrc;
 use std::ops::DerefMut;
 use std::{panic, process, ptr};
 
-#[cfg(test)]
-mod tests;
-
 pub trait ExpectOne<A: Array> {
     fn expect_one(self, err: &'static str) -> A::Item;
 }
@@ -357,7 +354,7 @@ pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) {
 }
 
 // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
-pub fn visit_method_sig<T: MutVisitor>(MethodSig { header, decl }: &mut MethodSig, vis: &mut T) {
+pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl }: &mut FnSig, vis: &mut T) {
     vis.visit_fn_header(header);
     vis.visit_fn_decl(decl);
 }
@@ -550,10 +547,14 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
 }
 
 pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
-    let Attribute { item: AttrItem { path, tokens }, id: _, style: _, is_sugared_doc: _, span }
-        = attr;
-    vis.visit_path(path);
-    vis.visit_tts(tokens);
+    let Attribute { kind, id: _, style: _, span } = attr;
+    match kind {
+        AttrKind::Normal(AttrItem { path, tokens }) => {
+            vis.visit_path(path);
+            vis.visit_tts(tokens);
+        }
+        AttrKind::DocComment(_) => {}
+    }
     vis.visit_span(span);
 }
 
@@ -874,9 +875,8 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_ty(ty);
             vis.visit_expr(expr);
         }
-        ItemKind::Fn(decl, header, generics, body) => {
-            vis.visit_fn_decl(decl);
-            vis.visit_fn_header(header);
+        ItemKind::Fn(sig, generics, body) => {
+            visit_fn_sig(sig, vis);
             vis.visit_generics(generics);
             vis.visit_block(body);
         }
@@ -934,7 +934,7 @@ pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, vis: &mut T)
             visit_opt(default, |default| vis.visit_expr(default));
         }
         TraitItemKind::Method(sig, body) => {
-            visit_method_sig(sig, vis);
+            visit_fn_sig(sig, vis);
             visit_opt(body, |body| vis.visit_block(body));
         }
         TraitItemKind::Type(bounds, default) => {
@@ -966,7 +966,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
             visitor.visit_expr(expr);
         }
         ImplItemKind::Method(sig, body) => {
-            visit_method_sig(sig, visitor);
+            visit_fn_sig(sig, visitor);
             visitor.visit_block(body);
         }
         ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 136fc355f89..f154b7bde98 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2,19 +2,18 @@ use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
 use crate::ast::{SelfKind, GenericBound, TraitBoundModifier};
 use crate::ast::{Attribute, MacDelimiter, GenericArg};
 use crate::util::parser::{self, AssocOp, Fixity};
+use crate::util::comments;
 use crate::attr;
 use crate::source_map::{self, SourceMap, Spanned};
-use crate::parse::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
-use crate::parse::lexer::comments;
-use crate::parse;
+use crate::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
 use crate::print::pp::{self, Breaks};
 use crate::print::pp::Breaks::{Consistent, Inconsistent};
 use crate::ptr::P;
+use crate::util::classify;
 use crate::sess::ParseSess;
 use crate::symbol::{kw, sym};
 use crate::tokenstream::{self, TokenStream, TokenTree};
 
-use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{self, BytePos};
 use syntax_pos::{FileName, Span};
 
@@ -322,7 +321,7 @@ fn token_to_string_ext(token: &Token, convert_dollar_crate: bool) -> String {
     token_kind_to_string_ext(&token.kind, convert_dollar_crate)
 }
 
-crate fn nonterminal_to_string(nt: &Nonterminal) -> String {
+pub fn nonterminal_to_string(nt: &Nonterminal) -> String {
     match *nt {
         token::NtExpr(ref e)        => expr_to_string(e),
         token::NtMeta(ref e)        => attr_item_to_string(e),
@@ -622,16 +621,19 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             self.hardbreak_if_not_bol();
         }
         self.maybe_print_comment(attr.span.lo());
-        if attr.is_sugared_doc {
-            self.word(attr.value_str().unwrap().as_str().to_string());
-            self.hardbreak()
-        } else {
-            match attr.style {
-                ast::AttrStyle::Inner => self.word("#!["),
-                ast::AttrStyle::Outer => self.word("#["),
+        match attr.kind {
+            ast::AttrKind::Normal(ref item) => {
+                match attr.style {
+                    ast::AttrStyle::Inner => self.word("#!["),
+                    ast::AttrStyle::Outer => self.word("#["),
+                }
+                self.print_attr_item(&item, attr.span);
+                self.word("]");
+            }
+            ast::AttrKind::DocComment(comment) => {
+                self.word(comment.to_string());
+                self.hardbreak()
             }
-            self.print_attr_item(&attr.item, attr.span);
-            self.word("]");
         }
     }
 
@@ -937,8 +939,11 @@ impl<'a> State<'a> {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
     }
 
-    crate fn print_mod(&mut self, _mod: &ast::Mod,
-                       attrs: &[ast::Attribute]) {
+    pub fn print_mod(
+        &mut self,
+        _mod: &ast::Mod,
+        attrs: &[ast::Attribute],
+    ) {
         self.print_inner_attributes(attrs);
         for item in &_mod.items {
             self.print_item(item);
@@ -953,7 +958,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) {
+    pub fn print_opt_lifetime(&mut self, lifetime: &Option<ast::Lifetime>) {
         if let Some(lt) = *lifetime {
             self.print_lifetime(lt);
             self.nbsp();
@@ -968,7 +973,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_type(&mut self, ty: &ast::Ty) {
+    pub fn print_type(&mut self, ty: &ast::Ty) {
         self.maybe_print_comment(ty.span.lo());
         self.ibox(0);
         match ty.kind {
@@ -1197,11 +1202,11 @@ impl<'a> State<'a> {
                 self.s.word(";");
                 self.end(); // end the outer cbox
             }
-            ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => {
+            ast::ItemKind::Fn(ref sig, ref param_names, ref body) => {
                 self.head("");
                 self.print_fn(
-                    decl,
-                    header,
+                    &sig.decl,
+                    sig.header,
                     Some(item.ident),
                     param_names,
                     &item.vis
@@ -1227,14 +1232,14 @@ impl<'a> State<'a> {
             }
             ast::ItemKind::ForeignMod(ref nmod) => {
                 self.head("extern");
-                self.word_nbsp(nmod.abi.to_string());
+                self.print_abi(nmod.abi);
                 self.bopen();
                 self.print_foreign_mod(nmod, &item.attrs);
                 self.bclose(item.span);
             }
             ast::ItemKind::GlobalAsm(ref ga) => {
                 self.head(visibility_qualified(&item.vis, "global_asm!"));
-                self.s.word(ga.asm.as_str().to_string());
+                self.s.word(ga.asm.to_string());
                 self.end();
             }
             ast::ItemKind::TyAlias(ref ty, ref generics) => {
@@ -1539,7 +1544,7 @@ impl<'a> State<'a> {
     crate fn print_method_sig(&mut self,
                             ident: ast::Ident,
                             generics: &ast::Generics,
-                            m: &ast::MethodSig,
+                            m: &ast::FnSig,
                             vis: &ast::Visibility)
                             {
         self.print_fn(&m.decl,
@@ -1657,7 +1662,7 @@ impl<'a> State<'a> {
             ast::StmtKind::Expr(ref expr) => {
                 self.space_if_not_bol();
                 self.print_expr_outer_attr_style(expr, false);
-                if parse::classify::expr_requires_semi_to_be_stmt(expr) {
+                if classify::expr_requires_semi_to_be_stmt(expr) {
                     self.s.word(";");
                 }
             }
@@ -1993,7 +1998,7 @@ impl<'a> State<'a> {
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
-    crate fn print_expr(&mut self, expr: &ast::Expr) {
+    pub fn print_expr(&mut self, expr: &ast::Expr) {
         self.print_expr_outer_attr_style(expr, true)
     }
 
@@ -2330,12 +2335,12 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_usize(&mut self, i: usize) {
+    pub fn print_usize(&mut self, i: usize) {
         self.s.word(i.to_string())
     }
 
     crate fn print_name(&mut self, name: ast::Name) {
-        self.s.word(name.as_str().to_string());
+        self.s.word(name.to_string());
         self.ann.post(self, AnnNode::Name(&name))
     }
 
@@ -2599,7 +2604,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) {
+    pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::GenericBound]) {
         if !bounds.is_empty() {
             self.s.word(prefix);
             let mut first = true;
@@ -2758,7 +2763,7 @@ impl<'a> State<'a> {
         }
     }
 
-    crate fn print_mutability(&mut self, mutbl: ast::Mutability) {
+    pub fn print_mutability(&mut self, mutbl: ast::Mutability) {
         match mutbl {
             ast::Mutability::Mutable => self.word_nbsp("mut"),
             ast::Mutability::Immutable => {},
@@ -2820,7 +2825,7 @@ impl<'a> State<'a> {
     }
 
     crate fn print_ty_fn(&mut self,
-                       abi: abi::Abi,
+                       abi: ast::Abi,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
                        name: Option<ast::Ident>,
@@ -2881,14 +2886,18 @@ impl<'a> State<'a> {
         self.print_asyncness(header.asyncness.node);
         self.print_unsafety(header.unsafety);
 
-        if header.abi != Abi::Rust {
+        if header.abi.symbol != sym::Rust {
             self.word_nbsp("extern");
-            self.word_nbsp(header.abi.to_string());
+            self.print_abi(header.abi);
         }
 
         self.s.word("fn")
     }
 
+    fn print_abi(&mut self, abi: ast::Abi) {
+        self.word_nbsp(format!("\"{}\"", abi.symbol));
+    }
+
     crate fn print_unsafety(&mut self, s: ast::Unsafety) {
         match s {
             ast::Unsafety::Normal => {},
diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs
index faa70edbfa2..2c6dd0fb1c6 100644
--- a/src/libsyntax/print/pprust/tests.rs
+++ b/src/libsyntax/print/pprust/tests.rs
@@ -34,12 +34,7 @@ fn test_fun_to_string() {
         assert_eq!(
             fun_to_string(
                 &decl,
-                ast::FnHeader {
-                    unsafety: ast::Unsafety::Normal,
-                    constness: source_map::dummy_spanned(ast::Constness::NotConst),
-                    asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
-                    abi: Abi::Rust,
-                },
+                ast::FnHeader::default(),
                 abba_ident,
                 &generics
             ),
diff --git a/src/libsyntax/sess.rs b/src/libsyntax/sess.rs
index 323fe01f067..953f0d1d190 100644
--- a/src/libsyntax/sess.rs
+++ b/src/libsyntax/sess.rs
@@ -1,12 +1,12 @@
 //! Contains `ParseSess` which holds state living beyond what one `Parser` might.
 //! It also serves as an input to the parser itself.
 
-use crate::ast::{CrateConfig, NodeId};
+use crate::ast::{CrateConfig, NodeId, Attribute};
 use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
 use crate::source_map::{SourceMap, FilePathMapping};
 use crate::feature_gate::UnstableFeatures;
 
-use errors::{Applicability, Handler, ColorConfig, DiagnosticBuilder};
+use errors::{Applicability, emitter::SilentEmitter, Handler, ColorConfig, DiagnosticBuilder};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc_data_structures::sync::{Lrc, Lock, Once};
 use syntax_pos::{Symbol, Span, MultiSpan};
@@ -19,52 +19,66 @@ use std::str;
 /// Collected spans during parsing for places where a certain feature was
 /// used and should be feature gated accordingly in `check_crate`.
 #[derive(Default)]
-crate struct GatedSpans {
-    /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
-    crate let_chains: Lock<Vec<Span>>,
-    /// Spans collected for gating `async_closure`, e.g. `async || ..`.
-    crate async_closure: Lock<Vec<Span>>,
-    /// Spans collected for gating `yield e?` expressions (`generators` gate).
-    crate yields: Lock<Vec<Span>>,
-    /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
-    crate or_patterns: Lock<Vec<Span>>,
-    /// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`.
-    crate const_extern_fn: Lock<Vec<Span>>,
-    /// Spans collected for gating `trait_alias`, e.g. `trait Foo = Ord + Eq;`.
-    pub trait_alias: Lock<Vec<Span>>,
-    /// Spans collected for gating `associated_type_bounds`, e.g. `Iterator<Item: Ord>`.
-    pub associated_type_bounds: Lock<Vec<Span>>,
-    /// Spans collected for gating `crate_visibility_modifier`, e.g. `crate fn`.
-    pub crate_visibility_modifier: Lock<Vec<Span>>,
-    /// Spans collected for gating `const_generics`, e.g. `const N: usize`.
-    pub const_generics: Lock<Vec<Span>>,
-    /// Spans collected for gating `decl_macro`, e.g. `macro m() {}`.
-    pub decl_macro: Lock<Vec<Span>>,
-    /// Spans collected for gating `box_patterns`, e.g. `box 0`.
-    pub box_patterns: Lock<Vec<Span>>,
-    /// Spans collected for gating `exclusive_range_pattern`, e.g. `0..2`.
-    pub exclusive_range_pattern: Lock<Vec<Span>>,
-    /// Spans collected for gating `try_blocks`, e.g. `try { a? + b? }`.
-    pub try_blocks: Lock<Vec<Span>>,
-    /// Spans collected for gating `label_break_value`, e.g. `'label: { ... }`.
-    pub label_break_value: Lock<Vec<Span>>,
-    /// Spans collected for gating `box_syntax`, e.g. `box $expr`.
-    pub box_syntax: Lock<Vec<Span>>,
-    /// Spans collected for gating `type_ascription`, e.g. `42: usize`.
-    pub type_ascription: Lock<Vec<Span>>,
+pub struct GatedSpans {
+    pub spans: Lock<FxHashMap<Symbol, Vec<Span>>>,
+}
+
+impl GatedSpans {
+    /// Feature gate the given `span` under the given `feature`
+    /// which is same `Symbol` used in `active.rs`.
+    pub fn gate(&self, feature: Symbol, span: Span) {
+        self.spans
+            .borrow_mut()
+            .entry(feature)
+            .or_default()
+            .push(span);
+    }
+
+    /// Ungate the last span under the given `feature`.
+    /// Panics if the given `span` wasn't the last one.
+    ///
+    /// Using this is discouraged unless you have a really good reason to.
+    pub fn ungate_last(&self, feature: Symbol, span: Span) {
+        let removed_span = self.spans
+            .borrow_mut()
+            .entry(feature)
+            .or_default()
+            .pop()
+            .unwrap();
+        debug_assert_eq!(span, removed_span);
+    }
+
+    /// Is the provided `feature` gate ungated currently?
+    ///
+    /// Using this is discouraged unless you have a really good reason to.
+    pub fn is_ungated(&self, feature: Symbol) -> bool {
+        self.spans
+            .borrow()
+            .get(&feature)
+            .map_or(true, |spans| spans.is_empty())
+    }
+
+    /// Prepend the given set of `spans` onto the set in `self`.
+    pub fn merge(&self, mut spans: FxHashMap<Symbol, Vec<Span>>) {
+        let mut inner = self.spans.borrow_mut();
+        for (gate, mut gate_spans) in inner.drain() {
+            spans.entry(gate).or_default().append(&mut gate_spans);
+        }
+        *inner = spans;
+    }
 }
 
 /// Info about a parsing session.
 pub struct ParseSess {
     pub span_diagnostic: Handler,
-    crate unstable_features: UnstableFeatures,
+    pub unstable_features: UnstableFeatures,
     pub config: CrateConfig,
     pub edition: Edition,
     pub missing_fragment_specifiers: Lock<FxHashSet<Span>>,
     /// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
     pub raw_identifier_spans: Lock<Vec<Span>>,
     /// Used to determine and report recursive module inclusions.
-    pub(super) included_mod_stack: Lock<Vec<PathBuf>>,
+    pub included_mod_stack: Lock<Vec<PathBuf>>,
     source_map: Lrc<SourceMap>,
     pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
     /// Contains the spans of block expressions that could have been incomplete based on the
@@ -72,13 +86,25 @@ pub struct ParseSess {
     /// analysis.
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
     pub injected_crate_name: Once<Symbol>,
-    crate gated_spans: GatedSpans,
+    pub gated_spans: GatedSpans,
     /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
     pub reached_eof: Lock<bool>,
+    /// Process the potential `cfg` attributes on a module.
+    /// Also determine if the module should be included in this configuration.
+    ///
+    /// HACK(Centril): This is used to break a cyclic dependency between
+    /// the parser and cfg-stripping as defined in `syntax_expand::config`.
+    /// The dependency edge from the parser comes from `parse_item_mod`.
+    /// A principled solution to this hack would be to implement [#64197].
+    ///
+    /// [#64197]: https://github.com/rust-lang/rust/issues/64197
+    pub process_cfg_mod: ProcessCfgMod,
 }
 
+pub type ProcessCfgMod = fn(&ParseSess, bool, &[Attribute]) -> (bool, Vec<Attribute>);
+
 impl ParseSess {
-    pub fn new(file_path_mapping: FilePathMapping) -> Self {
+    pub fn new(file_path_mapping: FilePathMapping, process_cfg_mod: ProcessCfgMod) -> Self {
         let cm = Lrc::new(SourceMap::new(file_path_mapping));
         let handler = Handler::with_tty_emitter(
             ColorConfig::Auto,
@@ -86,12 +112,17 @@ impl ParseSess {
             None,
             Some(cm.clone()),
         );
-        ParseSess::with_span_handler(handler, cm)
+        ParseSess::with_span_handler(handler, cm, process_cfg_mod)
     }
 
-    pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> Self {
+    pub fn with_span_handler(
+        handler: Handler,
+        source_map: Lrc<SourceMap>,
+        process_cfg_mod: ProcessCfgMod,
+    ) -> Self {
         Self {
             span_diagnostic: handler,
+            process_cfg_mod,
             unstable_features: UnstableFeatures::from_environment(),
             config: FxHashSet::default(),
             edition: ExpnId::root().expn_data().edition,
@@ -107,6 +138,12 @@ impl ParseSess {
         }
     }
 
+    pub fn with_silent_emitter(process_cfg_mod: ProcessCfgMod) -> Self {
+        let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+        let handler = Handler::with_emitter(false, None, Box::new(SilentEmitter));
+        ParseSess::with_span_handler(handler, cm, process_cfg_mod)
+    }
+
     #[inline]
     pub fn source_map(&self) -> &SourceMap {
         &self.source_map
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index d7760e0cf9e..d9f618602a4 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -498,10 +498,6 @@ impl SourceMap {
     pub fn span_to_lines(&self, sp: Span) -> FileLinesResult {
         debug!("span_to_lines(sp={:?})", sp);
 
-        if sp.lo() > sp.hi() {
-            return Err(SpanLinesError::IllFormedSpan(sp));
-        }
-
         let lo = self.lookup_char_pos(sp.lo());
         debug!("span_to_lines: lo={:?}", lo);
         let hi = self.lookup_char_pos(sp.hi());
@@ -549,10 +545,6 @@ impl SourceMap {
     fn span_to_source<F>(&self, sp: Span, extract_source: F) -> Result<String, SpanSnippetError>
         where F: Fn(&str, usize, usize) -> Result<String, SpanSnippetError>
     {
-        if sp.lo() > sp.hi() {
-            return Err(SpanSnippetError::IllFormedSpan(sp));
-        }
-
         let local_begin = self.lookup_byte_offset(sp.lo());
         let local_end = self.lookup_byte_offset(sp.hi());
 
@@ -762,14 +754,14 @@ impl SourceMap {
 
     /// Finds the width of a character, either before or after the provided span.
     fn find_width_of_character_at_span(&self, sp: Span, forwards: bool) -> u32 {
-        // Disregard malformed spans and assume a one-byte wide character.
-        if sp.lo() >= sp.hi() {
-            debug!("find_width_of_character_at_span: early return malformed span");
+        let sp = sp.data();
+        if sp.lo == sp.hi {
+            debug!("find_width_of_character_at_span: early return empty span");
             return 1;
         }
 
-        let local_begin = self.lookup_byte_offset(sp.lo());
-        let local_end = self.lookup_byte_offset(sp.hi());
+        let local_begin = self.lookup_byte_offset(sp.lo);
+        let local_end = self.lookup_byte_offset(sp.hi);
         debug!("find_width_of_character_at_span: local_begin=`{:?}`, local_end=`{:?}`",
                local_begin, local_end);
 
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/token.rs
index 03e77b199cc..ab798e93d67 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/token.rs
@@ -14,8 +14,6 @@ use syntax_pos::{self, Span, DUMMY_SP};
 
 use std::fmt;
 use std::mem;
-#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert_size;
 use rustc_data_structures::sync::Lrc;
 
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
@@ -107,14 +105,14 @@ impl fmt::Display for Lit {
 
 impl LitKind {
     /// An English article for the literal token kind.
-    crate fn article(self) -> &'static str {
+    pub fn article(self) -> &'static str {
         match self {
             Integer | Err => "an",
             _ => "a",
         }
     }
 
-    crate fn descr(self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self {
             Bool => panic!("literal token contains `Lit::Bool`"),
             Byte => "byte",
@@ -141,12 +139,12 @@ impl Lit {
     }
 }
 
-pub(crate) fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool {
+pub fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool {
     let ident_token = Token::new(Ident(name, is_raw), span);
     token_can_begin_expr(&ident_token)
 }
 
-pub(crate) fn token_can_begin_expr(ident_token: &Token) -> bool {
+pub fn token_can_begin_expr(ident_token: &Token) -> bool {
     !ident_token.is_reserved_ident() ||
     ident_token.is_path_segment_keyword() ||
     match ident_token.kind {
@@ -261,7 +259,7 @@ pub enum TokenKind {
 
 // `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(TokenKind, 16);
+rustc_data_structures::static_assert_size!(TokenKind, 16);
 
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
 pub struct Token {
@@ -276,7 +274,7 @@ impl TokenKind {
 
     /// Returns tokens that are likely to be typed accidentally instead of the current token.
     /// Enables better error recovery when the wrong token is found.
-    crate fn similar_tokens(&self) -> Option<Vec<TokenKind>> {
+    pub fn similar_tokens(&self) -> Option<Vec<TokenKind>> {
         match *self {
             Comma => Some(vec![Dot, Lt, Semi]),
             Semi => Some(vec![Colon, Comma]),
@@ -291,7 +289,7 @@ impl Token {
     }
 
     /// Some token that will be thrown away later.
-    crate fn dummy() -> Self {
+    pub fn dummy() -> Self {
         Token::new(TokenKind::Whitespace, DUMMY_SP)
     }
 
@@ -305,7 +303,7 @@ impl Token {
         mem::replace(self, Token::dummy())
     }
 
-    crate fn is_op(&self) -> bool {
+    pub fn is_op(&self) -> bool {
         match self.kind {
             OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) |
             Ident(..) | Lifetime(..) | Interpolated(..) |
@@ -314,7 +312,7 @@ impl Token {
         }
     }
 
-    crate fn is_like_plus(&self) -> bool {
+    pub fn is_like_plus(&self) -> bool {
         match self.kind {
             BinOp(Plus) | BinOpEq(Plus) => true,
             _ => false,
@@ -377,13 +375,11 @@ impl Token {
     }
 
     /// Returns `true` if the token can appear at the start of a const param.
-    crate fn can_begin_const_arg(&self) -> bool {
+    pub fn can_begin_const_arg(&self) -> bool {
         match self.kind {
             OpenDelim(Brace) => true,
             Interpolated(ref nt) => match **nt {
-                NtExpr(..) => true,
-                NtBlock(..) => true,
-                NtLiteral(..) => true,
+                NtExpr(..) | NtBlock(..) | NtLiteral(..) => true,
                 _ => false,
             }
             _ => self.can_begin_literal_or_bool(),
@@ -391,7 +387,7 @@ impl Token {
     }
 
     /// Returns `true` if the token can appear at the start of a generic bound.
-    crate fn can_begin_bound(&self) -> bool {
+    pub fn can_begin_bound(&self) -> bool {
         self.is_path_start() || self.is_lifetime() || self.is_keyword(kw::For) ||
         self == &Question || self == &OpenDelim(Paren)
     }
@@ -404,13 +400,6 @@ impl Token {
         }
     }
 
-    crate fn expect_lit(&self) -> Lit {
-        match self.kind {
-            Literal(lit) => lit,
-            _ => panic!("`expect_lit` called on non-literal"),
-        }
-    }
-
     /// Returns `true` if the token is any literal, a minus (which can prefix a literal,
     /// for example a '-42', or one of the boolean idents).
     pub fn can_begin_literal_or_bool(&self) -> bool {
@@ -455,13 +444,13 @@ impl Token {
     }
 
     /// Returns `true` if the token is a lifetime.
-    crate fn is_lifetime(&self) -> bool {
+    pub fn is_lifetime(&self) -> bool {
         self.lifetime().is_some()
     }
 
     /// Returns `true` if the token is a identifier whose name is the given
     /// string slice.
-    crate fn is_ident_named(&self, name: Symbol) -> bool {
+    pub fn is_ident_named(&self, name: Symbol) -> bool {
         self.ident().map_or(false, |(ident, _)| ident.name == name)
     }
 
@@ -478,7 +467,7 @@ impl Token {
     /// Would `maybe_whole_expr` in `parser.rs` return `Ok(..)`?
     /// That is, is this a pre-parsed expression dropped into the token stream
     /// (which happens while parsing the result of macro expansion)?
-    crate fn is_whole_expr(&self) -> bool {
+    pub fn is_whole_expr(&self) -> bool {
         if let Interpolated(ref nt) = self.kind {
             if let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtIdent(..) | NtBlock(_) = **nt {
                 return true;
@@ -489,16 +478,16 @@ impl Token {
     }
 
     /// Returns `true` if the token is either the `mut` or `const` keyword.
-    crate fn is_mutability(&self) -> bool {
+    pub fn is_mutability(&self) -> bool {
         self.is_keyword(kw::Mut) ||
         self.is_keyword(kw::Const)
     }
 
-    crate fn is_qpath_start(&self) -> bool {
+    pub fn is_qpath_start(&self) -> bool {
         self == &Lt || self == &BinOp(Shl)
     }
 
-    crate fn is_path_start(&self) -> bool {
+    pub fn is_path_start(&self) -> bool {
         self == &ModSep || self.is_qpath_start() || self.is_path() ||
         self.is_path_segment_keyword() || self.is_ident() && !self.is_reserved_ident()
     }
@@ -508,23 +497,23 @@ impl Token {
         self.is_non_raw_ident_where(|id| id.name == kw)
     }
 
-    crate fn is_path_segment_keyword(&self) -> bool {
+    pub fn is_path_segment_keyword(&self) -> bool {
         self.is_non_raw_ident_where(ast::Ident::is_path_segment_keyword)
     }
 
     // Returns true for reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
-    crate fn is_special_ident(&self) -> bool {
+    pub fn is_special_ident(&self) -> bool {
         self.is_non_raw_ident_where(ast::Ident::is_special)
     }
 
     /// Returns `true` if the token is a keyword used in the language.
-    crate fn is_used_keyword(&self) -> bool {
+    pub fn is_used_keyword(&self) -> bool {
         self.is_non_raw_ident_where(ast::Ident::is_used_keyword)
     }
 
     /// Returns `true` if the token is a keyword reserved for possible future use.
-    crate fn is_unused_keyword(&self) -> bool {
+    pub fn is_unused_keyword(&self) -> bool {
         self.is_non_raw_ident_where(ast::Ident::is_unused_keyword)
     }
 
@@ -534,7 +523,7 @@ impl Token {
     }
 
     /// Returns `true` if the token is the identifier `true` or `false`.
-    crate fn is_bool_lit(&self) -> bool {
+    pub fn is_bool_lit(&self) -> bool {
         self.is_non_raw_ident_where(|id| id.name.is_bool_lit())
     }
 
@@ -546,7 +535,7 @@ impl Token {
         }
     }
 
-    crate fn glue(&self, joint: &Token) -> Option<Token> {
+    pub fn glue(&self, joint: &Token) -> Option<Token> {
         let kind = match self.kind {
             Eq => match joint.kind {
                 Eq => EqEq,
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 0559f224f1f..2201f1ed6ca 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -13,19 +13,14 @@
 //! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking
 //! ownership of the original.
 
-use crate::parse::token::{self, DelimToken, Token, TokenKind};
+use crate::token::{self, DelimToken, Token, TokenKind};
 
-use syntax_pos::{BytePos, Span, DUMMY_SP};
-#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert_size;
+use syntax_pos::{Span, DUMMY_SP};
 use rustc_data_structures::sync::Lrc;
 use smallvec::{SmallVec, smallvec};
 
 use std::{iter, mem};
 
-#[cfg(test)]
-mod tests;
-
 /// When the main rust parser encounters a syntax-extension invocation, it
 /// parses the arguments to the invocation as a token-tree. This is a very
 /// loose structure, such that all sorts of different AST-fragments can
@@ -110,23 +105,13 @@ impl TokenTree {
     }
 
     /// Returns the opening delimiter as a token tree.
-    pub fn open_tt(span: Span, delim: DelimToken) -> TokenTree {
-        let open_span = if span.is_dummy() {
-            span
-        } else {
-            span.with_hi(span.lo() + BytePos(delim.len() as u32))
-        };
-        TokenTree::token(token::OpenDelim(delim), open_span)
+    pub fn open_tt(span: DelimSpan, delim: DelimToken) -> TokenTree {
+        TokenTree::token(token::OpenDelim(delim), span.open)
     }
 
     /// Returns the closing delimiter as a token tree.
-    pub fn close_tt(span: Span, delim: DelimToken) -> TokenTree {
-        let close_span = if span.is_dummy() {
-            span
-        } else {
-            span.with_lo(span.hi() - BytePos(delim.len() as u32))
-        };
-        TokenTree::token(token::CloseDelim(delim), close_span)
+    pub fn close_tt(span: DelimSpan, delim: DelimToken) -> TokenTree {
+        TokenTree::token(token::CloseDelim(delim), span.close)
     }
 }
 
@@ -142,7 +127,7 @@ pub type TreeAndJoint = (TokenTree, IsJoint);
 
 // `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(TokenStream, 8);
+rustc_data_structures::static_assert_size!(TokenStream, 8);
 
 #[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum IsJoint {
@@ -228,7 +213,7 @@ impl TokenStream {
         self.0.len()
     }
 
-    pub(crate) fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream {
+    pub fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream {
         match streams.len() {
             0 => TokenStream::default(),
             1 => streams.pop().unwrap(),
@@ -253,7 +238,7 @@ impl TokenStream {
 
                 // Get the first stream. If it's `None`, create an empty
                 // stream.
-                let mut iter = streams.drain();
+                let mut iter = streams.drain(..);
                 let mut first_stream_lrc = iter.next().unwrap().0;
 
                 // Append the elements to the first stream, after reserving
diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/util/classify.rs
index 44560688750..44560688750 100644
--- a/src/libsyntax/parse/classify.rs
+++ b/src/libsyntax/util/classify.rs
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/util/comments.rs
index ac79ce323bf..5e9b7bf8322 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/util/comments.rs
@@ -2,13 +2,14 @@ pub use CommentStyle::*;
 
 use crate::ast;
 use crate::source_map::SourceMap;
-use crate::parse::lexer::is_block_doc_comment;
-use crate::parse::lexer::ParseSess;
+use crate::sess::ParseSess;
 
 use syntax_pos::{BytePos, CharPos, Pos, FileName};
 
 use std::usize;
 
+use log::debug;
+
 #[cfg(test)]
 mod tests;
 
@@ -31,8 +32,24 @@ pub struct Comment {
     pub pos: BytePos,
 }
 
-fn is_doc_comment(s: &str) -> bool {
-    (s.starts_with("///") && super::is_doc_comment(s)) || s.starts_with("//!") ||
+pub fn is_line_doc_comment(s: &str) -> bool {
+    let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/') ||
+              s.starts_with("//!");
+    debug!("is {:?} a doc comment? {}", s, res);
+    res
+}
+
+pub fn is_block_doc_comment(s: &str) -> bool {
+    // Prevent `/**/` from being parsed as a doc comment
+    let res = ((s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*') ||
+               s.starts_with("/*!")) && s.len() >= 5;
+    debug!("is {:?} a doc comment? {}", s, res);
+    res
+}
+
+// FIXME(#64197): Try to privatize this again.
+pub fn is_doc_comment(s: &str) -> bool {
+    (s.starts_with("///") && is_line_doc_comment(s)) || s.starts_with("//!") ||
     (s.starts_with("/**") && is_block_doc_comment(s)) || s.starts_with("/*!")
 }
 
diff --git a/src/libsyntax/parse/lexer/comments/tests.rs b/src/libsyntax/util/comments/tests.rs
index f9cd69fb50d..f9cd69fb50d 100644
--- a/src/libsyntax/parse/lexer/comments/tests.rs
+++ b/src/libsyntax/util/comments/tests.rs
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/util/literal.rs
index 7952e293a53..af7afab6b9b 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/util/literal.rs
@@ -1,8 +1,8 @@
 //! Code related to parsing literals.
 
 use crate::ast::{self, Lit, LitKind};
-use crate::parse::token::{self, Token};
 use crate::symbol::{kw, sym, Symbol};
+use crate::token::{self, Token};
 use crate::tokenstream::TokenTree;
 
 use log::debug;
@@ -14,7 +14,7 @@ use rustc_lexer::unescape::{unescape_raw_str, unescape_raw_byte_str};
 
 use std::ascii;
 
-crate enum LitError {
+pub enum LitError {
     NotLiteral,
     LexerError,
     InvalidSuffix,
@@ -134,9 +134,9 @@ impl LitKind {
         let (kind, symbol, suffix) = match *self {
             LitKind::Str(symbol, ast::StrStyle::Cooked) => {
                 // Don't re-intern unless the escaped string is different.
-                let s: &str = &symbol.as_str();
+                let s = symbol.as_str();
                 let escaped = s.escape_default().to_string();
-                let symbol = if escaped == *s { symbol } else { Symbol::intern(&escaped) };
+                let symbol = if s == escaped { symbol } else { Symbol::intern(&escaped) };
                 (token::Str, symbol, None)
             }
             LitKind::Str(symbol, ast::StrStyle::Raw(n)) => {
@@ -157,17 +157,18 @@ impl LitKind {
             }
             LitKind::Int(n, ty) => {
                 let suffix = match ty {
-                    ast::LitIntType::Unsigned(ty) => Some(ty.to_symbol()),
-                    ast::LitIntType::Signed(ty) => Some(ty.to_symbol()),
+                    ast::LitIntType::Unsigned(ty) => Some(ty.name()),
+                    ast::LitIntType::Signed(ty) => Some(ty.name()),
                     ast::LitIntType::Unsuffixed => None,
                 };
                 (token::Integer, sym::integer(n), suffix)
             }
             LitKind::Float(symbol, ty) => {
-                (token::Float, symbol, Some(ty.to_symbol()))
-            }
-            LitKind::FloatUnsuffixed(symbol) => {
-                (token::Float, symbol, None)
+                let suffix = match ty {
+                    ast::LitFloatType::Suffixed(ty) => Some(ty.name()),
+                    ast::LitFloatType::Unsuffixed => None,
+                };
+                (token::Float, symbol, suffix)
             }
             LitKind::Bool(value) => {
                 let symbol = if value { kw::True } else { kw::False };
@@ -184,12 +185,12 @@ impl LitKind {
 
 impl Lit {
     /// Converts literal token into an AST literal.
-    crate fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> {
+    pub fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> {
         Ok(Lit { token, kind: LitKind::from_lit_token(token)?, span })
     }
 
     /// Converts arbitrary token into an AST literal.
-    crate fn from_token(token: &Token) -> Result<Lit, LitError> {
+    pub fn from_token(token: &Token) -> Result<Lit, LitError> {
         let lit = match token.kind {
             token::Ident(name, false) if name.is_bool_lit() =>
                 token::Lit::new(token::Bool, name, None),
@@ -216,8 +217,8 @@ impl Lit {
         Lit { token: kind.to_lit_token(), kind, span }
     }
 
-    /// Losslessly convert an AST literal into a token tree.
-    crate fn token_tree(&self) -> TokenTree {
+    /// Losslessly convert an AST literal into a token stream.
+    pub fn token_tree(&self) -> TokenTree {
         let token = match self.token.kind {
             token::Bool => token::Ident(self.token.symbol, false),
             _ => token::Literal(self.token),
@@ -244,12 +245,12 @@ fn filtered_float_lit(symbol: Symbol, suffix: Option<Symbol>, base: u32)
         return Err(LitError::NonDecimalFloat(base));
     }
     Ok(match suffix {
-        Some(suf) => match suf {
-            sym::f32 => LitKind::Float(symbol, ast::FloatTy::F32),
-            sym::f64 => LitKind::Float(symbol, ast::FloatTy::F64),
+        Some(suf) => LitKind::Float(symbol, ast::LitFloatType::Suffixed(match suf {
+            sym::f32 => ast::FloatTy::F32,
+            sym::f64 => ast::FloatTy::F64,
             _ => return Err(LitError::InvalidFloatSuffix),
-        }
-        None => LitKind::FloatUnsuffixed(symbol)
+        })),
+        None => LitKind::Float(symbol, ast::LitFloatType::Unsuffixed)
     })
 }
 
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index 982755e8680..df72fdc8014 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -1,4 +1,4 @@
-use crate::parse::token::{self, Token, BinOpToken};
+use crate::token::{self, Token, BinOpToken};
 use crate::symbol::kw;
 use crate::ast::{self, BinOpKind};
 
@@ -69,7 +69,7 @@ pub enum Fixity {
 
 impl AssocOp {
     /// Creates a new AssocOP from a token
-    crate fn from_token(t: &Token) -> Option<AssocOp> {
+    pub fn from_token(t: &Token) -> Option<AssocOp> {
         use AssocOp::*;
         match t.kind {
             token::BinOpEq(k) => Some(AssignOp(k)),
@@ -358,7 +358,7 @@ impl ExprPrecedence {
 }
 
 /// In `let p = e`, operators with precedence `<=` this one requires parenthesis in `e`.
-crate fn prec_let_scrutinee_needs_par() -> usize {
+pub fn prec_let_scrutinee_needs_par() -> usize {
     AssocOp::LAnd.precedence()
 }
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a36783e2b64..ea2dc357e6e 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -14,7 +14,7 @@
 //! those that are created by the expansion of a macro.
 
 use crate::ast::*;
-use crate::parse::token::Token;
+use crate::token::Token;
 use crate::tokenstream::{TokenTree, TokenStream};
 
 use syntax_pos::Span;
@@ -25,7 +25,7 @@ pub enum FnKind<'a> {
     ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block),
 
     /// E.g., `fn foo(&self)`.
-    Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block),
+    Method(Ident, &'a FnSig, Option<&'a Visibility>, &'a Block),
 
     /// E.g., `|x, y| body`.
     Closure(&'a Expr),
@@ -244,12 +244,11 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_ty(typ);
             visitor.visit_expr(expr);
         }
-        ItemKind::Fn(ref declaration, ref header, ref generics, ref body) => {
+        ItemKind::Fn(ref sig, ref generics, ref body) => {
             visitor.visit_generics(generics);
-            visitor.visit_fn_header(header);
-            visitor.visit_fn(FnKind::ItemFn(item.ident, header,
-                                            &item.vis, body),
-                             declaration,
+            visitor.visit_fn_header(&sig.header);
+            visitor.visit_fn(FnKind::ItemFn(item.ident, &sig.header, &item.vis, body),
+                             &sig.decl,
                              item.span,
                              item.id)
         }
@@ -846,7 +845,10 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
 }
 
 pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
-    visitor.visit_tts(attr.tokens.clone());
+    match attr.kind {
+        AttrKind::Normal(ref item) => visitor.visit_tts(item.tokens.clone()),
+        AttrKind::DocComment(_) => {}
+    }
 }
 
 pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) {
diff --git a/src/libsyntax_expand/Cargo.toml b/src/libsyntax_expand/Cargo.toml
index f063753f599..653b87f0d82 100644
--- a/src/libsyntax_expand/Cargo.toml
+++ b/src/libsyntax_expand/Cargo.toml
@@ -11,16 +11,12 @@ path = "lib.rs"
 doctest = false
 
 [dependencies]
-bitflags = "1.0"
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 log = "0.4"
-scoped-tls = "1.0"
-lazy_static = "1.0.0"
 syntax_pos = { path = "../libsyntax_pos" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
-rustc_index = { path = "../librustc_index" }
 rustc_lexer = { path = "../librustc_lexer" }
-rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+rustc_parse = { path = "../librustc_parse" }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
diff --git a/src/libsyntax_expand/base.rs b/src/libsyntax_expand/base.rs
index d79b6910587..97ee241d838 100644
--- a/src/libsyntax_expand/base.rs
+++ b/src/libsyntax_expand/base.rs
@@ -1,27 +1,26 @@
 use crate::expand::{self, AstFragment, Invocation};
 
+use rustc_parse::{self, parser, DirectoryOwnership, MACRO_ARGUMENTS};
 use syntax::ast::{self, NodeId, Attribute, Name, PatKind};
 use syntax::attr::{self, HasAttrs, Stability, Deprecation};
 use syntax::source_map::SourceMap;
 use syntax::edition::Edition;
 use syntax::mut_visit::{self, MutVisitor};
-use syntax::parse::{self, parser, DirectoryOwnership};
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Ident, Symbol};
-use syntax::{ThinVec, MACRO_ARGUMENTS};
+use syntax::ThinVec;
+use syntax::token;
 use syntax::tokenstream::{self, TokenStream};
 use syntax::visit::Visitor;
-crate use syntax::expand::SpecialDerives;
 
 use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP};
 use syntax_pos::hygiene::{AstPass, ExpnId, ExpnData, ExpnKind};
-
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
+
 use std::iter;
 use std::path::PathBuf;
 use std::rc::Rc;
@@ -860,8 +859,8 @@ pub trait Resolver {
 
     fn check_unused_macros(&mut self);
 
-    fn has_derives(&self, expn_id: ExpnId, derives: SpecialDerives) -> bool;
-    fn add_derives(&mut self, expn_id: ExpnId, derives: SpecialDerives);
+    fn has_derive_copy(&self, expn_id: ExpnId) -> bool;
+    fn add_derive_copy(&mut self, expn_id: ExpnId);
 }
 
 #[derive(Clone)]
@@ -923,7 +922,7 @@ impl<'a> ExtCtxt<'a> {
         expand::MacroExpander::new(self, true)
     }
     pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
-        parse::stream_to_parser(self.parse_sess, stream, MACRO_ARGUMENTS)
+        rustc_parse::stream_to_parser(self.parse_sess, stream, MACRO_ARGUMENTS)
     }
     pub fn source_map(&self) -> &'a SourceMap { self.parse_sess.source_map() }
     pub fn parse_sess(&self) -> &'a ParseSess { self.parse_sess }
@@ -954,18 +953,7 @@ impl<'a> ExtCtxt<'a> {
     ///
     /// Stops backtracing at include! boundary.
     pub fn expansion_cause(&self) -> Option<Span> {
-        let mut expn_id = self.current_expansion.id;
-        let mut last_macro = None;
-        loop {
-            let expn_data = expn_id.expn_data();
-            // Stop going up the backtrace once include! is encountered
-            if expn_data.is_root() || expn_data.kind.descr() == sym::include {
-                break;
-            }
-            expn_id = expn_data.call_site.ctxt().outer_expn();
-            last_macro = Some(expn_data.call_site);
-        }
-        last_macro
+        self.current_expansion.id.expansion_cause()
     }
 
     pub fn struct_span_warn<S: Into<MultiSpan>>(&self,
diff --git a/src/libsyntax/config.rs b/src/libsyntax_expand/config.rs
index 6003fd1d286..7b927fb55f9 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax_expand/config.rs
@@ -1,20 +1,20 @@
-use crate::attr::HasAttrs;
-use crate::feature_gate::{
+use rustc_parse::validate_attr;
+use syntax::attr::HasAttrs;
+use syntax::feature_gate::{
     feature_err,
     EXPLAIN_STMT_ATTR_SYNTAX,
     Features,
     get_features,
     GateIssue,
 };
-use crate::attr;
-use crate::ast;
-use crate::edition::Edition;
-use crate::mut_visit::*;
-use crate::parse;
-use crate::ptr::P;
-use crate::sess::ParseSess;
-use crate::symbol::sym;
-use crate::util::map_in_place::MapInPlace;
+use syntax::attr;
+use syntax::ast;
+use syntax::edition::Edition;
+use syntax::mut_visit::*;
+use syntax::ptr::P;
+use syntax::sess::ParseSess;
+use syntax::util::map_in_place::MapInPlace;
+use syntax_pos::symbol::sym;
 
 use errors::Applicability;
 use smallvec::SmallVec;
@@ -93,10 +93,10 @@ impl<'a> StripUnconfigured<'a> {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
-        if attr.path != sym::cfg_attr {
+        if !attr.has_name(sym::cfg_attr) {
             return vec![attr];
         }
-        if attr.tokens.is_empty() {
+        if attr.get_normal_item().tokens.is_empty() {
             self.sess.span_diagnostic
                 .struct_span_err(
                     attr.span,
@@ -113,7 +113,7 @@ impl<'a> StripUnconfigured<'a> {
             return vec![];
         }
 
-        let res = parse::parse_in_attr(self.sess, &attr, |p| p.parse_cfg_attr());
+        let res = rustc_parse::parse_in_attr(self.sess, &attr, |p| p.parse_cfg_attr());
         let (cfg_predicate, expanded_attrs) = match res {
             Ok(result) => result,
             Err(mut e) => {
@@ -135,13 +135,11 @@ impl<'a> StripUnconfigured<'a> {
             // `cfg_attr` inside of another `cfg_attr`. E.g.
             //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
             expanded_attrs.into_iter()
-            .flat_map(|(item, span)| self.process_cfg_attr(ast::Attribute {
+            .flat_map(|(item, span)| self.process_cfg_attr(attr::mk_attr_from_item(
+                attr.style,
                 item,
-                id: attr::mk_attr_id(),
-                style: attr.style,
-                is_sugared_doc: false,
                 span,
-            }))
+            )))
             .collect()
         } else {
             vec![]
@@ -149,7 +147,7 @@ impl<'a> StripUnconfigured<'a> {
     }
 
     /// Determines if a node with the given attributes should be included in this configuration.
-    pub fn in_cfg(&mut self, attrs: &[ast::Attribute]) -> bool {
+    pub fn in_cfg(&self, attrs: &[ast::Attribute]) -> bool {
         attrs.iter().all(|attr| {
             if !is_cfg(attr) {
                 return true;
@@ -169,7 +167,7 @@ impl<'a> StripUnconfigured<'a> {
                 true
             };
 
-            let meta_item = match attr.parse_meta(self.sess) {
+            let meta_item = match validate_attr::parse_meta(self.sess, attr) {
                 Ok(meta_item) => meta_item,
                 Err(mut err) => { err.emit(); return true; }
             };
@@ -212,7 +210,7 @@ impl<'a> StripUnconfigured<'a> {
                                       GateIssue::Language,
                                       EXPLAIN_STMT_ATTR_SYNTAX);
 
-            if attr.is_sugared_doc {
+            if attr.is_doc_comment() {
                 err.help("`///` is for documentation comments. For a plain comment, use `//`.");
             }
 
@@ -351,3 +349,17 @@ impl<'a> MutVisitor for StripUnconfigured<'a> {
 fn is_cfg(attr: &ast::Attribute) -> bool {
     attr.check_name(sym::cfg)
 }
+
+/// Process the potential `cfg` attributes on a module.
+/// Also determine if the module should be included in this configuration.
+pub fn process_configure_mod(
+    sess: &ParseSess,
+    cfg_mods: bool,
+    attrs: &[ast::Attribute],
+) -> (bool, Vec<ast::Attribute>) {
+    // Don't perform gated feature checking.
+    let mut strip_unconfigured = StripUnconfigured { sess, features: None };
+    let mut attrs = attrs.to_owned();
+    strip_unconfigured.process_cfg_attrs(&mut attrs);
+    (!cfg_mods || strip_unconfigured.in_cfg(&attrs), attrs)
+}
diff --git a/src/libsyntax_expand/expand.rs b/src/libsyntax_expand/expand.rs
index bdb50dbfb4f..b7f6364c2b5 100644
--- a/src/libsyntax_expand/expand.rs
+++ b/src/libsyntax_expand/expand.rs
@@ -3,27 +3,28 @@ use crate::proc_macro::{collect_derives, MarkAttrs};
 use crate::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind};
 use crate::mbe::macro_rules::annotate_err_with_kind;
 use crate::placeholders::{placeholder, PlaceholderExpander};
+use crate::config::StripUnconfigured;
+use crate::configure;
 
+use rustc_parse::DirectoryOwnership;
+use rustc_parse::parser::Parser;
+use rustc_parse::validate_attr;
 use syntax::ast::{self, AttrItem, Block, Ident, LitKind, NodeId, PatKind, Path};
 use syntax::ast::{MacStmtStyle, StmtKind, ItemKind};
 use syntax::attr::{self, HasAttrs};
 use syntax::source_map::respan;
-use syntax::configure;
-use syntax::config::StripUnconfigured;
 use syntax::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
 use syntax::mut_visit::*;
-use syntax::parse::{DirectoryOwnership, PResult};
-use syntax::parse::token;
-use syntax::parse::parser::Parser;
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::sess::ParseSess;
 use syntax::symbol::{sym, Symbol};
+use syntax::token;
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::visit::{self, Visitor};
 use syntax::util::map_in_place::MapInPlace;
 
-use errors::{Applicability, FatalError};
+use errors::{PResult, Applicability, FatalError};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{Span, DUMMY_SP, FileName};
 
@@ -419,7 +420,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     }
 
                     let mut item = self.fully_configure(item);
-                    item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
+                    item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
                     let mut helper_attrs = Vec::new();
                     let mut has_copy = false;
                     for ext in exts {
@@ -432,7 +433,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     // can be in scope for all code produced by that container's expansion.
                     item.visit_with(&mut MarkAttrs(&helper_attrs));
                     if has_copy {
-                        self.cx.resolver.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
+                        self.cx.resolver.add_derive_copy(invoc.expansion_data.id);
                     }
 
                     let mut derive_placeholders = Vec::with_capacity(derives.len());
@@ -634,12 +635,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         | Annotatable::Variant(..)
                             => panic!("unexpected annotatable"),
                     })), DUMMY_SP).into();
-                    let input = self.extract_proc_macro_attr_input(attr.item.tokens, span);
+                    let item = attr.unwrap_normal_item();
+                    let input = self.extract_proc_macro_attr_input(item.tokens, span);
                     let tok_result = expander.expand(self.cx, span, input, item_tok);
-                    self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span)
+                    self.parse_ast_fragment(tok_result, fragment_kind, &item.path, span)
                 }
                 SyntaxExtensionKind::LegacyAttr(expander) => {
-                    match attr.parse_meta(self.cx.parse_sess) {
+                    match validate_attr::parse_meta(self.cx.parse_sess, &attr) {
                         Ok(meta) => {
                             let item = expander.expand(self.cx, span, &meta, item);
                             fragment_kind.expect_from_annotatables(item)
@@ -974,7 +976,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                        -> Option<ast::Attribute> {
         let attr = attrs.iter()
                         .position(|a| {
-                            if a.path == sym::derive {
+                            if a.has_name(sym::derive) {
                                 *after_derive = true;
                             }
                             !attr::is_known(a) && !is_builtin_attr(a)
@@ -982,7 +984,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                         .map(|i| attrs.remove(i));
         if let Some(attr) = &attr {
             if !self.cx.ecfg.custom_inner_attributes() &&
-               attr.style == ast::AttrStyle::Inner && attr.path != sym::test {
+               attr.style == ast::AttrStyle::Inner && !attr.has_name(sym::test) {
                 emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
                                  attr.span, GateIssue::Language,
                                  "non-builtin inner attributes are unstable");
@@ -1030,9 +1032,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
         let features = self.cx.ecfg.features.unwrap();
         for attr in attrs.iter() {
             feature_gate::check_attribute(attr, self.cx.parse_sess, features);
+            validate_attr::check_meta(self.cx.parse_sess, attr);
 
             // macros are expanded before any lint passes so this warning has to be hardcoded
-            if attr.path == sym::derive {
+            if attr.has_name(sym::derive) {
                 self.cx.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
                     .note("this may become a hard error in a future release")
                     .emit();
@@ -1300,7 +1303,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
                         Some(_) => DirectoryOwnership::Owned {
                             relative: Some(item.ident),
                         },
-                        None => DirectoryOwnership::UnownedViaMod(false),
+                        None => DirectoryOwnership::UnownedViaMod,
                     };
                     path.pop();
                     module.directory = path;
@@ -1547,11 +1550,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
 
             let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items);
             *at = attr::Attribute {
-                item: AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) },
+                kind: ast::AttrKind::Normal(
+                    AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) },
+                ),
                 span: at.span,
                 id: at.id,
                 style: at.style,
-                is_sugared_doc: false,
             };
         } else {
             noop_visit_attribute(at, self)
diff --git a/src/libsyntax_expand/lib.rs b/src/libsyntax_expand/lib.rs
index 10eb3ecb20b..46d59dd249c 100644
--- a/src/libsyntax_expand/lib.rs
+++ b/src/libsyntax_expand/lib.rs
@@ -33,6 +33,35 @@ pub use mbe::macro_rules::compile_declarative_macro;
 pub mod base;
 pub mod build;
 pub mod expand;
+#[macro_use] pub mod config;
 pub mod proc_macro;
 
 crate mod mbe;
+
+// HACK(Centril, #64197): These shouldn't really be here.
+// Rather, they should be with their respective modules which are defined in other crates.
+// However, since for now constructing a `ParseSess` sorta requires `config` from this crate,
+// these tests will need to live here in the iterim.
+
+#[cfg(test)]
+mod tests;
+#[cfg(test)]
+mod parse {
+    #[cfg(test)]
+    mod tests;
+    #[cfg(test)]
+    mod lexer {
+        #[cfg(test)]
+        mod tests;
+    }
+}
+#[cfg(test)]
+mod tokenstream {
+    #[cfg(test)]
+    mod tests;
+}
+#[cfg(test)]
+mod mut_visit {
+    #[cfg(test)]
+    mod tests;
+}
diff --git a/src/libsyntax_expand/mbe.rs b/src/libsyntax_expand/mbe.rs
index d0f790638ef..6964d01b719 100644
--- a/src/libsyntax_expand/mbe.rs
+++ b/src/libsyntax_expand/mbe.rs
@@ -10,10 +10,10 @@ crate mod macro_rules;
 crate mod quoted;
 
 use syntax::ast;
-use syntax::parse::token::{self, Token, TokenKind};
+use syntax::token::{self, Token, TokenKind};
 use syntax::tokenstream::{DelimSpan};
 
-use syntax_pos::{BytePos, Span};
+use syntax_pos::Span;
 
 use rustc_data_structures::sync::Lrc;
 
@@ -27,23 +27,13 @@ struct Delimited {
 
 impl Delimited {
     /// Returns a `self::TokenTree` with a `Span` corresponding to the opening delimiter.
-    fn open_tt(&self, span: Span) -> TokenTree {
-        let open_span = if span.is_dummy() {
-            span
-        } else {
-            span.with_hi(span.lo() + BytePos(self.delim.len() as u32))
-        };
-        TokenTree::token(token::OpenDelim(self.delim), open_span)
+    fn open_tt(&self, span: DelimSpan) -> TokenTree {
+        TokenTree::token(token::OpenDelim(self.delim), span.open)
     }
 
     /// Returns a `self::TokenTree` with a `Span` corresponding to the closing delimiter.
-    fn close_tt(&self, span: Span) -> TokenTree {
-        let close_span = if span.is_dummy() {
-            span
-        } else {
-            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
-        };
-        TokenTree::token(token::CloseDelim(self.delim), close_span)
+    fn close_tt(&self, span: DelimSpan) -> TokenTree {
+        TokenTree::token(token::CloseDelim(self.delim), span.close)
     }
 }
 
@@ -138,10 +128,10 @@ impl TokenTree {
             }
             (&TokenTree::Delimited(span, ref delimed), _) => {
                 if index == 0 {
-                    return delimed.open_tt(span.open);
+                    return delimed.open_tt(span);
                 }
                 if index == delimed.tts.len() + 1 {
-                    return delimed.close_tt(span.close);
+                    return delimed.close_tt(span);
                 }
                 delimed.tts[index - 1].clone()
             }
diff --git a/src/libsyntax_expand/mbe/macro_check.rs b/src/libsyntax_expand/mbe/macro_check.rs
index 50abda8d45e..25754ed4217 100644
--- a/src/libsyntax_expand/mbe/macro_check.rs
+++ b/src/libsyntax_expand/mbe/macro_check.rs
@@ -108,7 +108,7 @@ use crate::mbe::{KleeneToken, TokenTree};
 
 use syntax::ast::NodeId;
 use syntax::early_buffered_lints::BufferedEarlyLintId;
-use syntax::parse::token::{DelimToken, Token, TokenKind};
+use syntax::token::{DelimToken, Token, TokenKind};
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym};
 
diff --git a/src/libsyntax_expand/mbe/macro_parser.rs b/src/libsyntax_expand/mbe/macro_parser.rs
index 3efe22626a9..0dcb2c39fdc 100644
--- a/src/libsyntax_expand/mbe/macro_parser.rs
+++ b/src/libsyntax_expand/mbe/macro_parser.rs
@@ -76,16 +76,16 @@ use TokenTreeOrTokenTreeSlice::*;
 
 use crate::mbe::{self, TokenTree};
 
+use rustc_parse::Directory;
+use rustc_parse::parser::{Parser, PathStyle};
 use syntax::ast::{Ident, Name};
-use syntax::parse::{Directory, PResult};
-use syntax::parse::parser::{Parser, PathStyle};
-use syntax::parse::token::{self, DocComment, Nonterminal, Token};
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Symbol};
+use syntax::token::{self, DocComment, Nonterminal, Token};
 use syntax::tokenstream::{DelimSpan, TokenStream};
 
-use errors::FatalError;
+use errors::{PResult, FatalError};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::Span;
 
@@ -652,7 +652,7 @@ pub(super) fn parse(
         directory,
         recurse_into_modules,
         true,
-        syntax::MACRO_ARGUMENTS,
+        rustc_parse::MACRO_ARGUMENTS,
     );
 
     // A queue of possible matcher positions. We initialize it with the matcher position in which
diff --git a/src/libsyntax_expand/mbe/macro_rules.rs b/src/libsyntax_expand/mbe/macro_rules.rs
index 9a4130b2d8d..72b7996628a 100644
--- a/src/libsyntax_expand/mbe/macro_rules.rs
+++ b/src/libsyntax_expand/mbe/macro_rules.rs
@@ -8,31 +8,30 @@ use crate::mbe::macro_parser::{Error, Failure, Success};
 use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedParseResult};
 use crate::mbe::transcribe::transcribe;
 
+use rustc_parse::parser::Parser;
+use rustc_parse::Directory;
 use syntax::ast;
 use syntax::attr::{self, TransparencyError};
 use syntax::edition::Edition;
 use syntax::feature_gate::Features;
-use syntax::parse::parser::Parser;
-use syntax::parse::token::TokenKind::*;
-use syntax::parse::token::{self, NtTT, Token};
-use syntax::parse::Directory;
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Symbol};
+use syntax::token::{self, NtTT, Token, TokenKind::*};
 use syntax::tokenstream::{DelimSpan, TokenStream};
+use syntax_pos::hygiene::Transparency;
+use syntax_pos::Span;
 
 use errors::{DiagnosticBuilder, FatalError};
 use log::debug;
-use syntax_pos::hygiene::Transparency;
-use syntax_pos::Span;
 
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sync::Lrc;
 use std::borrow::Cow;
 use std::collections::hash_map::Entry;
-use std::slice;
+use std::{mem, slice};
 
 use errors::Applicability;
-use rustc_data_structures::sync::Lrc;
 
 const VALID_FRAGMENT_NAMES_MSG: &str = "valid fragment specifiers are \
                                         `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, \
@@ -182,7 +181,6 @@ fn generic_extension<'cx>(
 
     // Which arm's failure should we report? (the one furthest along)
     let mut best_failure: Option<(Token, &str)> = None;
-
     for (i, lhs) in lhses.iter().enumerate() {
         // try each arm's matchers
         let lhs_tt = match *lhs {
@@ -190,8 +188,18 @@ fn generic_extension<'cx>(
             _ => cx.span_bug(sp, "malformed macro lhs"),
         };
 
+        // Take a snapshot of the state of pre-expansion gating at this point.
+        // This is used so that if a matcher is not `Success(..)`ful,
+        // then the spans which became gated when parsing the unsucessful matcher
+        // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
+        let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut());
+
         match parse_tt(cx, lhs_tt, arg.clone()) {
             Success(named_matches) => {
+                // The matcher was `Success(..)`ful.
+                // Merge the gated spans from parsing the matcher with the pre-existing ones.
+                cx.parse_sess.gated_spans.merge(gated_spans_snaphot);
+
                 let rhs = match rhses[i] {
                     // ignore delimiters
                     mbe::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(),
@@ -225,7 +233,7 @@ fn generic_extension<'cx>(
                 };
                 let mut p = Parser::new(cx.parse_sess(), tts, Some(directory), true, false, None);
                 p.root_module_name =
-                    cx.current_expansion.module.mod_path.last().map(|id| id.as_str().to_string());
+                    cx.current_expansion.module.mod_path.last().map(|id| id.to_string());
                 p.last_type_ascription = cx.current_expansion.prior_type_ascription;
 
                 p.process_potential_macro_variable();
@@ -248,6 +256,10 @@ fn generic_extension<'cx>(
             },
             Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]),
         }
+
+        // The matcher was not `Success(..)`ful.
+        // Restore to the state before snapshotting and maybe try again.
+        mem::swap(&mut gated_spans_snaphot, &mut cx.parse_sess.gated_spans.spans.borrow_mut());
     }
 
     let (token, label) = best_failure.expect("ran no matchers");
@@ -566,7 +578,7 @@ impl FirstSets {
                     }
                     TokenTree::Delimited(span, ref delimited) => {
                         build_recur(sets, &delimited.tts[..]);
-                        first.replace_with(delimited.open_tt(span.open));
+                        first.replace_with(delimited.open_tt(span));
                     }
                     TokenTree::Sequence(sp, ref seq_rep) => {
                         let subfirst = build_recur(sets, &seq_rep.tts[..]);
@@ -628,7 +640,7 @@ impl FirstSets {
                     return first;
                 }
                 TokenTree::Delimited(span, ref delimited) => {
-                    first.add_one(delimited.open_tt(span.open));
+                    first.add_one(delimited.open_tt(span));
                     return first;
                 }
                 TokenTree::Sequence(sp, ref seq_rep) => {
@@ -826,7 +838,7 @@ fn check_matcher_core(
                 }
             }
             TokenTree::Delimited(span, ref d) => {
-                let my_suffix = TokenSet::singleton(d.close_tt(span.close));
+                let my_suffix = TokenSet::singleton(d.close_tt(span));
                 check_matcher_core(sess, features, attrs, first_sets, &d.tts, &my_suffix);
                 // don't track non NT tokens
                 last.replace_with_irrelevant();
diff --git a/src/libsyntax_expand/mbe/quoted.rs b/src/libsyntax_expand/mbe/quoted.rs
index cedd59233ad..dec504c0d97 100644
--- a/src/libsyntax_expand/mbe/quoted.rs
+++ b/src/libsyntax_expand/mbe/quoted.rs
@@ -2,10 +2,10 @@ use crate::mbe::macro_parser;
 use crate::mbe::{TokenTree, KleeneOp, KleeneToken, SequenceRepetition, Delimited};
 
 use syntax::ast;
-use syntax::parse::token::{self, Token};
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
 use syntax::symbol::kw;
+use syntax::token::{self, Token};
 use syntax::tokenstream;
 
 use syntax_pos::Span;
diff --git a/src/libsyntax_expand/mbe/transcribe.rs b/src/libsyntax_expand/mbe/transcribe.rs
index 94523bbf91b..4092d4b97de 100644
--- a/src/libsyntax_expand/mbe/transcribe.rs
+++ b/src/libsyntax_expand/mbe/transcribe.rs
@@ -4,12 +4,12 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
 
 use syntax::ast::{Ident, Mac};
 use syntax::mut_visit::{self, MutVisitor};
-use syntax::parse::token::{self, NtTT, Token};
+use syntax::token::{self, NtTT, Token};
 use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
 use smallvec::{smallvec, SmallVec};
 
-use errors::pluralise;
+use errors::pluralize;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::hygiene::{ExpnId, Transparency};
@@ -350,10 +350,10 @@ impl LockstepIterSize {
                         "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}",
                         l_id,
                         l_len,
-                        pluralise!(l_len),
+                        pluralize!(l_len),
                         r_id,
                         r_len,
-                        pluralise!(r_len),
+                        pluralize!(r_len),
                     );
                     LockstepIterSize::Contradiction(msg)
                 }
diff --git a/src/libsyntax/mut_visit/tests.rs b/src/libsyntax_expand/mut_visit/tests.rs
index f779e0d0a60..30e812a1179 100644
--- a/src/libsyntax/mut_visit/tests.rs
+++ b/src/libsyntax_expand/mut_visit/tests.rs
@@ -1,10 +1,9 @@
-use super::*;
-
-use crate::ast::{self, Ident};
 use crate::tests::{string_to_crate, matches_codepattern};
-use crate::print::pprust;
-use crate::mut_visit;
-use crate::with_default_globals;
+
+use syntax::ast::{self, Ident};
+use syntax::print::pprust;
+use syntax::mut_visit::{self, MutVisitor};
+use syntax::with_default_globals;
 
 // This version doesn't care about getting comments or doc-strings in.
 fn fake_print_crate(s: &mut pprust::State<'_>,
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax_expand/parse/lexer/tests.rs
index de301b1fc49..d8a1c359c95 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax_expand/parse/lexer/tests.rs
@@ -1,14 +1,18 @@
-use super::*;
+use crate::config::process_configure_mod;
 
-use crate::symbol::Symbol;
-use crate::source_map::{SourceMap, FilePathMapping};
-use crate::parse::token;
-use crate::with_default_globals;
+use rustc_data_structures::sync::Lrc;
+use rustc_parse::lexer::StringReader;
+use syntax::token::{self, Token, TokenKind};
+use syntax::sess::ParseSess;
+use syntax::source_map::{SourceMap, FilePathMapping};
+use syntax::util::comments::is_doc_comment;
+use syntax::with_default_globals;
+use syntax_pos::symbol::Symbol;
+use syntax_pos::{BytePos, Span};
 
 use errors::{Handler, emitter::EmitterWriter};
 use std::io;
 use std::path::PathBuf;
-use syntax_pos::{BytePos, Span};
 
 fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
     let emitter = EmitterWriter::new(
@@ -20,7 +24,11 @@ fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
         None,
         false,
     );
-    ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
+    ParseSess::with_span_handler(
+        Handler::with_emitter(true, None, Box::new(emitter)),
+        sm,
+        process_configure_mod,
+    )
 }
 
 // Creates a string reader for the given string.
diff --git a/src/libsyntax/parse/tests.rs b/src/libsyntax_expand/parse/tests.rs
index 3bdb9227b4e..60911617995 100644
--- a/src/libsyntax/parse/tests.rs
+++ b/src/libsyntax_expand/parse/tests.rs
@@ -1,21 +1,27 @@
-use super::*;
-
-use crate::ast::{self, Name, PatKind};
-use crate::attr::first_attr_value_str_by_name;
-use crate::parse::{ParseSess, PResult};
-use crate::parse::new_parser_from_source_str;
-use crate::parse::token::Token;
-use crate::print::pprust::item_to_string;
-use crate::ptr::P;
-use crate::source_map::FilePathMapping;
-use crate::symbol::{kw, sym};
+use crate::config::process_configure_mod;
 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};
+
+use rustc_parse::new_parser_from_source_str;
+use syntax::ast::{self, Name, PatKind};
+use syntax::attr::first_attr_value_str_by_name;
+use syntax::sess::ParseSess;
+use syntax::token::{self, Token};
+use syntax::print::pprust::item_to_string;
+use syntax::ptr::P;
+use syntax::source_map::FilePathMapping;
+use syntax::symbol::{kw, sym};
+use syntax::tokenstream::{DelimSpan, TokenTree, TokenStream};
+use syntax::visit;
+use syntax::with_default_globals;
+use syntax_pos::{Span, BytePos, Pos, FileName};
+use errors::PResult;
 
 use std::path::PathBuf;
 
+fn sess() -> ParseSess {
+    ParseSess::new(FilePathMapping::empty(), process_configure_mod)
+}
+
 /// Parses an item.
 ///
 /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err`
@@ -32,18 +38,12 @@ fn sp(a: u32, b: u32) -> Span {
 
 /// Parses a string, return an expression.
 fn string_to_expr(source_str : String) -> P<ast::Expr> {
-    let ps = ParseSess::new(FilePathMapping::empty());
-    with_error_checking_parse(source_str, &ps, |p| {
-        p.parse_expr()
-    })
+    with_error_checking_parse(source_str, &sess(), |p| p.parse_expr())
 }
 
 /// Parses a string, returns an item.
 fn string_to_item(source_str : String) -> Option<P<ast::Item>> {
-    let ps = ParseSess::new(FilePathMapping::empty());
-    with_error_checking_parse(source_str, &ps, |p| {
-        p.parse_item()
-    })
+    with_error_checking_parse(source_str, &sess(), |p| p.parse_item())
 }
 
 #[should_panic]
@@ -169,20 +169,20 @@ fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
     struct PatIdentVisitor {
         spans: Vec<Span>
     }
-    impl<'a> crate::visit::Visitor<'a> for PatIdentVisitor {
+    impl<'a> visit::Visitor<'a> for PatIdentVisitor {
         fn visit_pat(&mut self, p: &'a ast::Pat) {
             match p.kind {
                 PatKind::Ident(_ , ref ident, _) => {
                     self.spans.push(ident.span.clone());
                 }
                 _ => {
-                    crate::visit::walk_pat(self, p);
+                    visit::walk_pat(self, p);
                 }
             }
         }
     }
     let mut v = PatIdentVisitor { spans: Vec::new() };
-    crate::visit::walk_item(&mut v, &item);
+    visit::walk_item(&mut v, &item);
     return v.spans;
 }
 
@@ -233,7 +233,7 @@ let mut fflags: c_int = wb();
 
 #[test] fn crlf_doc_comments() {
     with_default_globals(|| {
-        let sess = ParseSess::new(FilePathMapping::empty());
+        let sess = sess();
 
         let name_1 = FileName::Custom("crlf_source_1".to_string());
         let source = "/// doc comment\r\nfn foo() {}".to_string();
@@ -246,7 +246,7 @@ let mut fflags: c_int = wb();
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name_2, source, &sess)
             .unwrap().unwrap();
-        let docs = item.attrs.iter().filter(|a| a.path == sym::doc)
+        let docs = item.attrs.iter().filter(|a| a.has_name(sym::doc))
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
         let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
         assert_eq!(&docs[..], b);
@@ -268,7 +268,7 @@ fn ttdelim_span() {
     }
 
     with_default_globals(|| {
-        let sess = ParseSess::new(FilePathMapping::empty());
+        let sess = sess();
         let expr = parse_expr_from_source_str(PathBuf::from("foo").into(),
             "foo!( fn main() { body } )".to_string(), &sess).unwrap();
 
@@ -292,11 +292,10 @@ fn ttdelim_span() {
 #[test]
 fn out_of_line_mod() {
     with_default_globals(|| {
-        let sess = ParseSess::new(FilePathMapping::empty());
         let item = parse_item_from_source_str(
             PathBuf::from("foo").into(),
             "mod foo { struct S; mod this_does_not_exist; }".to_owned(),
-            &sess,
+            &sess(),
         ).unwrap().unwrap();
 
         if let ast::ItemKind::Mod(ref m) = item.kind {
diff --git a/src/libsyntax_expand/proc_macro.rs b/src/libsyntax_expand/proc_macro.rs
index bda9478ce96..db981fae5c2 100644
--- a/src/libsyntax_expand/proc_macro.rs
+++ b/src/libsyntax_expand/proc_macro.rs
@@ -4,8 +4,8 @@ use crate::proc_macro_server;
 use syntax::ast::{self, ItemKind, Attribute, Mac};
 use syntax::attr::{mark_used, mark_known};
 use syntax::errors::{Applicability, FatalError};
-use syntax::parse::{self, token};
 use syntax::symbol::sym;
+use syntax::token;
 use syntax::tokenstream::{self, TokenStream};
 use syntax::visit::Visitor;
 
@@ -134,7 +134,11 @@ impl MultiItemModifier for ProcMacroDerive {
         let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
         let msg = "proc-macro derive produced unparseable tokens";
 
-        let mut parser = parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
+        let mut parser = rustc_parse::stream_to_parser(
+            ecx.parse_sess,
+            stream,
+            Some("proc-macro derive"),
+        );
         let mut items = vec![];
 
         loop {
@@ -181,7 +185,7 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> {
 crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
     let mut result = Vec::new();
     attrs.retain(|attr| {
-        if attr.path != sym::derive {
+        if !attr.has_name(sym::derive) {
             return true;
         }
         if !attr.is_meta_item_list() {
@@ -196,10 +200,10 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>)
         }
 
         let parse_derive_paths = |attr: &ast::Attribute| {
-            if attr.tokens.is_empty() {
+            if attr.get_normal_item().tokens.is_empty() {
                 return Ok(Vec::new());
             }
-            parse::parse_in_attr(cx.parse_sess, attr, |p| p.parse_derive_paths())
+            rustc_parse::parse_in_attr(cx.parse_sess, attr, |p| p.parse_derive_paths())
         };
 
         match parse_derive_paths(attr) {
diff --git a/src/libsyntax_expand/proc_macro_server.rs b/src/libsyntax_expand/proc_macro_server.rs
index 4ce99cfe73b..43a9d4169f6 100644
--- a/src/libsyntax_expand/proc_macro_server.rs
+++ b/src/libsyntax_expand/proc_macro_server.rs
@@ -1,16 +1,17 @@
 use crate::base::ExtCtxt;
 
+use rustc_parse::{parse_stream_from_source_str, nt_to_tokenstream};
 use syntax::ast;
-use syntax::parse::{self, token};
-use syntax::parse::lexer::comments;
+use syntax::util::comments;
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
+use syntax::token;
 use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
+use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
+use syntax_pos::symbol::{kw, sym, Symbol};
 
 use errors::Diagnostic;
 use rustc_data_structures::sync::Lrc;
-use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
-use syntax_pos::symbol::{kw, sym, Symbol};
 
 use pm::{Delimiter, Level, LineColumn, Spacing};
 use pm::bridge::{server, TokenTree};
@@ -52,7 +53,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
 {
     fn from_internal(((tree, is_joint), sess, stack): (TreeAndJoint, &ParseSess, &mut Vec<Self>))
                     -> Self {
-        use syntax::parse::token::*;
+        use syntax::token::*;
 
         let joint = is_joint == Joint;
         let Token { kind, span } = match tree {
@@ -177,7 +178,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
             }
 
             Interpolated(nt) => {
-                let stream = parse::nt_to_tokenstream(&nt, sess, span);
+                let stream = nt_to_tokenstream(&nt, sess, span);
                 TokenTree::Group(Group {
                     delimiter: Delimiter::None,
                     stream,
@@ -193,7 +194,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
 
 impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
     fn to_internal(self) -> TokenStream {
-        use syntax::parse::token::*;
+        use syntax::token::*;
 
         let (ch, joint, span) = match self {
             TokenTree::Punct(Punct { ch, joint, span }) => (ch, joint, span),
@@ -401,7 +402,7 @@ impl server::TokenStream for Rustc<'_> {
         stream.is_empty()
     }
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        parse::parse_stream_from_source_str(
+        parse_stream_from_source_str(
             FileName::proc_macro_source_code(src),
             src.to_string(),
             self.sess,
diff --git a/src/libsyntax/tests.rs b/src/libsyntax_expand/tests.rs
index e73c8b43bcc..2683620e845 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax_expand/tests.rs
@@ -1,16 +1,15 @@
-use crate::ast;
-use crate::parse::{PResult, source_file_to_stream};
-use crate::parse::new_parser_from_source_str;
-use crate::parse::parser::Parser;
-use crate::sess::ParseSess;
-use crate::source_map::{SourceMap, FilePathMapping};
-use crate::tokenstream::TokenStream;
-use crate::with_default_globals;
+use crate::config::process_configure_mod;
+use rustc_parse::{source_file_to_stream, new_parser_from_source_str, parser::Parser};
+use syntax::ast;
+use syntax::tokenstream::TokenStream;
+use syntax::sess::ParseSess;
+use syntax::source_map::{SourceMap, FilePathMapping};
+use syntax::with_default_globals;
+use syntax_pos::{BytePos, Span, MultiSpan};
 
 use errors::emitter::EmitterWriter;
-use errors::Handler;
+use errors::{PResult, Handler};
 use rustc_data_structures::sync::Lrc;
-use syntax_pos::{BytePos, Span, MultiSpan};
 
 use std::io;
 use std::io::prelude::*;
@@ -35,7 +34,7 @@ crate fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F)
 
 /// Maps a string to tts, using a made-up filename.
 crate fn string_to_stream(source_str: String) -> TokenStream {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = ParseSess::new(FilePathMapping::empty(), process_configure_mod);
     source_file_to_stream(
         &ps,
         ps.source_map().new_source_file(PathBuf::from("bogofile").into(),
@@ -45,7 +44,7 @@ crate fn string_to_stream(source_str: String) -> TokenStream {
 
 /// Parses a string, returns a crate.
 crate fn string_to_crate(source_str : String) -> ast::Crate {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = ParseSess::new(FilePathMapping::empty(), process_configure_mod);
     with_error_checking_parse(source_str, &ps, |p| {
         p.parse_crate_mod()
     })
diff --git a/src/libsyntax/tokenstream/tests.rs b/src/libsyntax_expand/tokenstream/tests.rs
index 5017e5f5424..cf9fead638e 100644
--- a/src/libsyntax/tokenstream/tests.rs
+++ b/src/libsyntax_expand/tokenstream/tests.rs
@@ -1,9 +1,11 @@
-use super::*;
-
-use crate::ast::Name;
-use crate::with_default_globals;
 use crate::tests::string_to_stream;
+
+use syntax::ast::Name;
+use syntax::token;
+use syntax::tokenstream::{TokenStream, TokenStreamBuilder, TokenTree};
+use syntax::with_default_globals;
 use syntax_pos::{Span, BytePos};
+use smallvec::smallvec;
 
 fn string_to_ts(string: &str) -> TokenStream {
     string_to_stream(string.to_owned())
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 440873f3c2b..5ae8b3a3e0c 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -14,8 +14,9 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 fmt_macros = { path = "../libfmt_macros" }
 log = "0.4"
 rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_parse = { path = "../librustc_parse" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
+smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_expand = { path = "../libsyntax_expand" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 8c9a34713ea..539d777105d 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -8,7 +8,7 @@ use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
 use syntax::ast::AsmDialect;
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index f4d1f7fb09c..c4f3c03813f 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -1,13 +1,13 @@
 use errors::{Applicability, DiagnosticBuilder};
 
+use rustc_parse::parser::Parser;
 use syntax::ast::{self, *};
-use syntax_expand::base::*;
-use syntax::parse::token::{self, TokenKind};
-use syntax::parse::parser::Parser;
+use syntax::token::{self, TokenKind};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::symbol::{sym, Symbol};
 use syntax::tokenstream::{TokenStream, TokenTree};
+use syntax_expand::base::*;
 use syntax_pos::{Span, DUMMY_SP};
 
 pub fn expand_assert<'cx>(
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 9e693f29c5a..583236d9754 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -8,7 +8,7 @@ use syntax::ast;
 use syntax_expand::base::{self, *};
 use syntax::attr;
 use syntax::tokenstream::TokenStream;
-use syntax::parse::token;
+use syntax::token;
 use syntax_pos::Span;
 
 pub fn expand_cfg(
diff --git a/src/libsyntax_ext/cmdline_attrs.rs b/src/libsyntax_ext/cmdline_attrs.rs
index 2d981526a39..5c3009c432c 100644
--- a/src/libsyntax_ext/cmdline_attrs.rs
+++ b/src/libsyntax_ext/cmdline_attrs.rs
@@ -2,14 +2,14 @@
 
 use syntax::ast::{self, AttrItem, AttrStyle};
 use syntax::attr::mk_attr;
-use syntax::parse::{self, token};
+use syntax::token;
 use syntax::sess::ParseSess;
 use syntax_expand::panictry;
 use syntax_pos::FileName;
 
 pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
     for raw_attr in attrs {
-        let mut parser = parse::new_parser_from_source_str(
+        let mut parser = rustc_parse::new_parser_from_source_str(
             parse_sess,
             FileName::cli_crate_attr_source_code(&raw_attr),
             raw_attr.clone(),
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index 47bade698a8..4bf13f37711 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -21,8 +21,7 @@ pub fn expand_concat(
         match e.kind {
             ast::ExprKind::Lit(ref lit) => match lit.kind {
                 ast::LitKind::Str(ref s, _)
-                | ast::LitKind::Float(ref s, _)
-                | ast::LitKind::FloatUnsuffixed(ref s) => {
+                | ast::LitKind::Float(ref s, _) => {
                     accumulator.push_str(&s.as_str());
                 }
                 ast::LitKind::Char(c) => {
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index a132a4136ea..8a1bc56cf1c 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::thin_vec::ThinVec;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::ptr::P;
 use syntax_pos::Span;
 use syntax_pos::symbol::Symbol;
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index 061afa379c6..c056d03614d 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -3,7 +3,6 @@ use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
 use syntax::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData};
-use syntax::expand::SpecialDerives;
 use syntax_expand::base::{Annotatable, ExtCtxt};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
@@ -37,7 +36,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>,
                 ItemKind::Struct(_, Generics { ref params, .. }) |
                 ItemKind::Enum(_, Generics { ref params, .. }) => {
                     let container_id = cx.current_expansion.id.expn_data().parent;
-                    if cx.resolver.has_derives(container_id, SpecialDerives::COPY) &&
+                    if cx.resolver.has_derive_copy(container_id) &&
                         !params.iter().any(|param| match param.kind {
                             ast::GenericParamKind::Type { .. } => true,
                             _ => false,
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index eddf8eea1db..41189de7fa2 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -3,7 +3,6 @@ use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
 use syntax::ast::{self, Ident, Expr, MetaItem, GenericArg};
-use syntax::expand::SpecialDerives;
 use syntax::ptr::P;
 use syntax::symbol::{sym, Symbol};
 use syntax_expand::base::{Annotatable, ExtCtxt};
@@ -14,8 +13,6 @@ 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.expn_data().parent, SpecialDerives::EQ);
-
     let inline = cx.meta_word(span, sym::inline);
     let hidden = syntax::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
     let doc = syntax::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 2e2be91de8a..19562e350dd 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -3,7 +3,6 @@ use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
 use syntax::ast::{BinOpKind, Expr, MetaItem};
-use syntax::expand::SpecialDerives;
 use syntax::ptr::P;
 use syntax::symbol::sym;
 use syntax_expand::base::{Annotatable, ExtCtxt};
@@ -14,8 +13,6 @@ 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.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
     fn cs_op(cx: &mut ExtCtxt<'_>,
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index c04b65245e1..b24306def74 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -182,11 +182,9 @@ use std::iter;
 use std::vec;
 
 use rustc_data_structures::thin_vec::ThinVec;
-use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
+use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
 use syntax::ast::{VariantData, GenericParamKind, GenericArg};
 use syntax::attr;
-use syntax::expand::SpecialDerives;
 use syntax::source_map::respan;
 use syntax::util::map_in_place::MapInPlace;
 use syntax::ptr::P;
@@ -427,10 +425,8 @@ impl<'a> TraitDef<'a> {
                     }
                 };
                 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;
-                let use_temporaries = is_packed && is_always_copy;
+                let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id);
+                let use_temporaries = is_packed && always_copy;
 
                 let newitem = match item.kind {
                     ast::ItemKind::Struct(ref struct_def, ref generics) => {
@@ -741,7 +737,7 @@ impl<'a> TraitDef<'a> {
                                          self,
                                          type_ident,
                                          generics,
-                                         Abi::Rust,
+                                         sym::Rust,
                                          explicit_self,
                                          tys,
                                          body)
@@ -796,7 +792,7 @@ impl<'a> TraitDef<'a> {
                                          self,
                                          type_ident,
                                          generics,
-                                         Abi::Rust,
+                                         sym::Rust,
                                          explicit_self,
                                          tys,
                                          body)
@@ -922,7 +918,7 @@ impl<'a> MethodDef<'a> {
                      trait_: &TraitDef<'_>,
                      type_ident: Ident,
                      generics: &Generics,
-                     abi: Abi,
+                     abi: Symbol,
                      explicit_self: Option<ast::ExplicitSelf>,
                      arg_types: Vec<(Ident, P<ast::Ty>)>,
                      body: P<Expr>)
@@ -952,23 +948,27 @@ impl<'a> MethodDef<'a> {
             ast::Unsafety::Normal
         };
 
+        let trait_lo_sp = trait_.span.shrink_to_lo();
+
+        let sig = ast::FnSig {
+            header: ast::FnHeader {
+                unsafety,
+                abi: Abi::new(abi, trait_lo_sp),
+                ..ast::FnHeader::default()
+            },
+            decl: fn_decl,
+        };
+
         // Create the method.
         ast::ImplItem {
             id: ast::DUMMY_NODE_ID,
             attrs: self.attributes.clone(),
             generics: fn_generics,
             span: trait_.span,
-            vis: respan(trait_.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
+            vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited),
             defaultness: ast::Defaultness::Final,
             ident: method_ident,
-            kind: ast::ImplItemKind::Method(ast::MethodSig {
-                                                header: ast::FnHeader {
-                                                    unsafety, abi,
-                                                    ..ast::FnHeader::default()
-                                                },
-                                                decl: fn_decl,
-                                            },
-                                            body_block),
+            kind: ast::ImplItemKind::Method(sig, body_block),
             tokens: None,
         }
     }
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 58fe56bd235..6fb48bf8173 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -21,7 +21,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
     };
 
     let sp = cx.with_def_site_ctxt(sp);
-    let e = match env::var(&*var.as_str()) {
+    let e = match env::var(&var.as_str()) {
         Err(..) => {
             let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
             cx.expr_path(cx.path_all(sp,
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 37310f46f7e..25daca9237f 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -5,11 +5,11 @@ use fmt_macros as parse;
 
 use errors::DiagnosticBuilder;
 use errors::Applicability;
-use errors::pluralise;
+use errors::pluralize;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
-use syntax::parse::token;
+use syntax::token;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
 use syntax::tokenstream::TokenStream;
@@ -21,7 +21,7 @@ use std::collections::hash_map::Entry;
 
 #[derive(PartialEq)]
 enum ArgumentType {
-    Placeholder(String),
+    Placeholder(&'static str),
     Count,
 }
 
@@ -244,7 +244,57 @@ impl<'a, 'b> Context<'a, 'b> {
                     parse::ArgumentNamed(s) => Named(s),
                 };
 
-                let ty = Placeholder(arg.format.ty.to_string());
+                let ty = Placeholder(match &arg.format.ty[..] {
+                    "" => "Display",
+                    "?" => "Debug",
+                    "e" => "LowerExp",
+                    "E" => "UpperExp",
+                    "o" => "Octal",
+                    "p" => "Pointer",
+                    "b" => "Binary",
+                    "x" => "LowerHex",
+                    "X" => "UpperHex",
+                    _ => {
+                        let fmtsp = self.fmtsp;
+                        let sp = arg.format.ty_span.map(|sp| fmtsp.from_inner(sp));
+                        let mut err = self.ecx.struct_span_err(
+                            sp.unwrap_or(fmtsp),
+                            &format!("unknown format trait `{}`", arg.format.ty),
+                        );
+                        err.note("the only appropriate formatting traits are:\n\
+                                - ``, which uses the `Display` trait\n\
+                                - `?`, which uses the `Debug` trait\n\
+                                - `e`, which uses the `LowerExp` trait\n\
+                                - `E`, which uses the `UpperExp` trait\n\
+                                - `o`, which uses the `Octal` trait\n\
+                                - `p`, which uses the `Pointer` trait\n\
+                                - `b`, which uses the `Binary` trait\n\
+                                - `x`, which uses the `LowerHex` trait\n\
+                                - `X`, which uses the `UpperHex` trait");
+                        if let Some(sp) = sp {
+                            for (fmt, name) in &[
+                                ("", "Display"),
+                                ("?", "Debug"),
+                                ("e", "LowerExp"),
+                                ("E", "UpperExp"),
+                                ("o", "Octal"),
+                                ("p", "Pointer"),
+                                ("b", "Binary"),
+                                ("x", "LowerHex"),
+                                ("X", "UpperHex"),
+                            ] {
+                                err.tool_only_span_suggestion(
+                                    sp,
+                                    &format!("use the `{}` trait", name),
+                                    fmt.to_string(),
+                                    Applicability::MaybeIncorrect,
+                                );
+                            }
+                        }
+                        err.emit();
+                        "<invalid>"
+                    }
+                });
                 self.verify_arg_type(pos, ty);
                 self.curpiece += 1;
             }
@@ -300,7 +350,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 &format!(
                     "{} positional argument{} in format string, but {}",
                     count,
-                    pluralise!(count),
+                    pluralize!(count),
                     self.describe_num_args(),
                 ),
             );
@@ -374,10 +424,12 @@ impl<'a, 'b> Context<'a, 'b> {
                                 format!("are {} arguments", count)
                             },
                         ));
-                        e.span_label(
-                            self.args[pos].span,
-                            "this parameter corresponds to the precision flag",
-                        );
+                        if let Some(arg) = self.args.get(pos) {
+                            e.span_label(
+                                arg.span,
+                                "this parameter corresponds to the precision flag",
+                            );
+                        }
                         zero_based_note = true;
                     }
                     _ => {}
@@ -588,6 +640,7 @@ impl<'a, 'b> Context<'a, 'b> {
                         width: parse::CountImplied,
                         width_span: None,
                         ty: arg.format.ty,
+                        ty_span: arg.format.ty_span,
                     },
                 };
 
@@ -759,37 +812,8 @@ impl<'a, 'b> Context<'a, 'b> {
         sp = ecx.with_def_site_ctxt(sp);
         let arg = ecx.expr_ident(sp, arg);
         let trait_ = match *ty {
-            Placeholder(ref tyname) => {
-                match &tyname[..] {
-                    "" => "Display",
-                    "?" => "Debug",
-                    "e" => "LowerExp",
-                    "E" => "UpperExp",
-                    "o" => "Octal",
-                    "p" => "Pointer",
-                    "b" => "Binary",
-                    "x" => "LowerHex",
-                    "X" => "UpperHex",
-                    _ => {
-                        let mut err = ecx.struct_span_err(
-                            sp,
-                            &format!("unknown format trait `{}`", *tyname),
-                        );
-                        err.note("the only appropriate formatting traits are:\n\
-                                  - ``, which uses the `Display` trait\n\
-                                  - `?`, which uses the `Debug` trait\n\
-                                  - `e`, which uses the `LowerExp` trait\n\
-                                  - `E`, which uses the `UpperExp` trait\n\
-                                  - `o`, which uses the `Octal` trait\n\
-                                  - `p`, which uses the `Pointer` trait\n\
-                                  - `b`, which uses the `Binary` trait\n\
-                                  - `x`, which uses the `LowerHex` trait\n\
-                                  - `X`, which uses the `UpperHex` trait");
-                        err.emit();
-                        return DummyResult::raw_expr(sp, true);
-                    }
-                }
-            }
+            Placeholder(trait_) if trait_ == "<invalid>" => return DummyResult::raw_expr(sp, true),
+            Placeholder(trait_) => trait_,
             Count => {
                 let path = ecx.std_path(&[sym::fmt, sym::ArgumentV1, sym::from_usize]);
                 return ecx.expr_call_global(macsp, path, vec![arg]);
@@ -992,7 +1016,7 @@ pub fn expand_preparsed_format_args(
         vec![]
     };
 
-    let fmt_str = &*fmt_str.as_str();  // for the suggestions below
+    let fmt_str = &fmt_str.as_str();  // for the suggestions below
     let mut parser = parse::Parser::new(fmt_str, str_style, skips, append_newline);
 
     let mut unverified_pieces = Vec::new();
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index 90d2ea38bc3..dc29e057455 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -1,7 +1,7 @@
 use crate::util::check_builtin_macro_attribute;
 
 use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety};
-use syntax::ast::{self, Param, Attribute, Expr, FnHeader, Generics, Ident};
+use syntax::ast::{self, Param, Attribute, Expr, FnSig, FnHeader, Generics, Ident};
 use syntax::expand::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
@@ -73,15 +73,10 @@ impl AllocFnFactory<'_, '_> {
             .collect();
         let result = self.call_allocator(method.name, args);
         let (output_ty, output_expr) = self.ret_ty(&method.output, result);
-        let kind = ItemKind::Fn(
-            self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)),
-            FnHeader {
-                unsafety: Unsafety::Unsafe,
-                ..FnHeader::default()
-            },
-            Generics::default(),
-            self.cx.block_expr(output_expr),
-        );
+        let decl = self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty));
+        let header = FnHeader { unsafety: Unsafety::Unsafe, ..FnHeader::default() };
+        let sig = FnSig { decl, header };
+        let kind = ItemKind::Fn(sig, Generics::default(), self.cx.block_expr(output_expr));
         let item = self.cx.item(
             self.span,
             self.cx.ident_of(&self.kind.fn_name(method.name), self.span),
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 879ae1e4215..8a8ce9a7f14 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -13,7 +13,7 @@ use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::source_map::respan;
 use syntax_expand::base::{self, *};
-use syntax::parse::token;
+use syntax::token;
 use syntax::ptr::P;
 use syntax_pos::Span;
 use syntax::tokenstream::TokenStream;
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index 1ca9422eb9d..cee1b97af55 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -4,12 +4,12 @@
 use syntax::ast::*;
 use syntax::attr;
 use syntax::edition::Edition;
-use syntax_expand::base::{Resolver, NamedSyntaxExtension};
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::source_map::respan;
 use syntax::symbol::sym;
+use syntax::token;
 use syntax::tokenstream::*;
+use syntax_expand::base::{Resolver, NamedSyntaxExtension};
 use syntax_pos::{Span, DUMMY_SP};
 use syntax_pos::hygiene::{ExpnData, ExpnKind, AstPass};
 
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index fc4a7a0a0fe..fbded7dc130 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -92,10 +92,12 @@ pub fn inject(sess: &ParseSess,
 impl<'a> CollectProcMacros<'a> {
     fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
         if self.is_proc_macro_crate && self.in_root && vis.node.is_pub() {
-            self.handler.span_err(sp,
-                                  "`proc-macro` crate types cannot \
-                                   export any items other than functions \
-                                   tagged with `#[proc_macro_derive]` currently");
+            self.handler.span_err(
+                sp,
+                "`proc-macro` crate types currently cannot export any items other \
+                    than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, \
+                    or `#[proc_macro_attribute]`",
+            );
         }
     }
 
@@ -249,9 +251,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         for attr in &item.attrs {
             if is_proc_macro_attr(&attr) {
                 if let Some(prev_attr) = found_attr {
-                    let path_str = pprust::path_to_string(&attr.path);
-                    let msg = if attr.path.segments[0].ident.name ==
-                                 prev_attr.path.segments[0].ident.name {
+                    let prev_item = prev_attr.get_normal_item();
+                    let item = attr.get_normal_item();
+                    let path_str = pprust::path_to_string(&item.path);
+                    let msg = if item.path.segments[0].ident.name ==
+                                 prev_item.path.segments[0].ident.name {
                         format!(
                             "only one `#[{}]` attribute is allowed on any given function",
                             path_str,
@@ -261,7 +265,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
                             "`#[{}]` and `#[{}]` attributes cannot both be applied
                             to the same function",
                             path_str,
-                            pprust::path_to_string(&prev_attr.path),
+                            pprust::path_to_string(&prev_item.path),
                         )
                     };
 
@@ -290,7 +294,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         if !is_fn {
             let msg = format!(
                 "the `#[{}]` attribute may only be used on bare functions",
-                pprust::path_to_string(&attr.path),
+                pprust::path_to_string(&attr.get_normal_item().path),
             );
 
             self.handler.span_err(attr.span, &msg);
@@ -304,7 +308,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         if !self.is_proc_macro_crate {
             let msg = format!(
                 "the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type",
-                pprust::path_to_string(&attr.path),
+                pprust::path_to_string(&attr.get_normal_item().path),
             );
 
             self.handler.span_err(attr.span, &msg);
diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs
index f6c58fcdfa1..120b533a69b 100644
--- a/src/libsyntax_ext/source_util.rs
+++ b/src/libsyntax_ext/source_util.rs
@@ -1,12 +1,13 @@
-use syntax_expand::panictry;
-use syntax_expand::base::{self, *};
+use rustc_parse::{self, DirectoryOwnership, new_sub_parser_from_file, parser::Parser};
 use syntax::ast;
-use syntax::parse::{self, token, DirectoryOwnership};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
+use syntax::token;
 use syntax::tokenstream::TokenStream;
 use syntax::early_buffered_lints::BufferedEarlyLintId;
+use syntax_expand::panictry;
+use syntax_expand::base::{self, *};
 
 use smallvec::SmallVec;
 use syntax_pos::{self, Pos, Span};
@@ -84,10 +85,10 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
         },
     };
     let directory_ownership = DirectoryOwnership::Owned { relative: None };
-    let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
+    let p = new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
 
     struct ExpandResult<'a> {
-        p: parse::parser::Parser<'a>,
+        p: Parser<'a>,
     }
     impl<'a> base::MacResult for ExpandResult<'a> {
         fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index b0da413d63a..8656100c921 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -310,15 +310,15 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
 fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
     let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
     let ref sd = cx.parse_sess.span_diagnostic;
-    if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.kind {
-        if header.unsafety == ast::Unsafety::Unsafe {
+    if let ast::ItemKind::Fn(ref sig, ref generics, _) = i.kind {
+        if sig.header.unsafety == ast::Unsafety::Unsafe {
             sd.span_err(
                 i.span,
                 "unsafe functions cannot be used for tests"
             );
             return false
         }
-        if header.asyncness.node.is_async() {
+        if sig.header.asyncness.node.is_async() {
             sd.span_err(
                 i.span,
                 "async functions cannot be used for tests"
@@ -329,13 +329,13 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
 
         // If the termination trait is active, the compiler will check that the output
         // type implements the `Termination` trait as `libtest` enforces that.
-        let has_output = match decl.output {
+        let has_output = match sig.decl.output {
             ast::FunctionRetTy::Default(..) => false,
             ast::FunctionRetTy::Ty(ref t) if t.kind.is_unit() => false,
             _ => true
         };
 
-        if !decl.inputs.is_empty() {
+        if !sig.decl.inputs.is_empty() {
             sd.span_err(i.span, "functions used as tests can not have any arguments");
             return false;
         }
@@ -361,10 +361,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
 }
 
 fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
-    let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.kind {
+    let has_sig = if let ast::ItemKind::Fn(ref sig, _, _) = i.kind {
         // N.B., inadequate check, but we're running
         // well before resolve, can't get too deep.
-        decl.inputs.len() == 1
+        sig.decl.inputs.len() == 1
     } else {
         false
     };
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 33d41a7f53e..1492f6f575f 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -306,10 +306,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         ecx.block(sp, vec![call_test_main])
     };
 
-    let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)),
-                           ast::FnHeader::default(),
-                           ast::Generics::default(),
-                           main_body);
+    let decl = ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty));
+    let sig = ast::FnSig { decl, header: ast::FnHeader::default() };
+    let main = ast::ItemKind::Fn(sig, ast::Generics::default(), main_body);
 
     // Honor the reexport_test_harness_main attribute
     let main_id = match cx.reexport_test_harness_main {
diff --git a/src/libsyntax_ext/util.rs b/src/libsyntax_ext/util.rs
index d84fe19b3ea..e59daab1770 100644
--- a/src/libsyntax_ext/util.rs
+++ b/src/libsyntax_ext/util.rs
@@ -1,11 +1,12 @@
+use rustc_parse::validate_attr;
 use syntax_pos::Symbol;
 use syntax::ast::MetaItem;
-use syntax::attr::{check_builtin_attribute, AttributeTemplate};
+use syntax::attr::AttributeTemplate;
 use syntax_expand::base::ExtCtxt;
 
 pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
     // All the built-in macro attributes are "words" at the moment.
     let template = AttributeTemplate::only_word();
     let attr = ecx.attribute(meta_item.clone());
-    check_builtin_attribute(ecx.parse_sess, &attr, name, template);
+    validate_attr::check_builtin_attribute(ecx.parse_sess, &attr, name, template);
 }
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index e28d9326757..2a48f8e44aa 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -28,7 +28,7 @@
 use crate::GLOBALS;
 use crate::{Span, DUMMY_SP};
 use crate::edition::Edition;
-use crate::symbol::{kw, Symbol};
+use crate::symbol::{kw, sym, Symbol};
 
 use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
 use rustc_data_structures::fx::FxHashMap;
@@ -119,6 +119,23 @@ impl ExpnId {
     pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
         HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
     }
+
+    /// Returns span for the macro which originally caused this expansion to happen.
+    ///
+    /// Stops backtracing at include! boundary.
+    pub fn expansion_cause(mut self) -> Option<Span> {
+        let mut last_macro = None;
+        loop {
+            let expn_data = self.expn_data();
+            // Stop going up the backtrace once include! is encountered
+            if expn_data.is_root() || expn_data.kind.descr() == sym::include {
+                break;
+            }
+            self = expn_data.call_site.ctxt().outer_expn();
+            last_macro = Some(expn_data.call_site);
+        }
+        last_macro
+    }
 }
 
 #[derive(Debug)]
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 9034f8c1afd..dc29b189639 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -1512,7 +1512,6 @@ pub type FileLinesResult = Result<FileLines, SpanLinesError>;
 
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub enum SpanLinesError {
-    IllFormedSpan(Span),
     DistinctSources(DistinctSources),
 }
 
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 57131ffe18c..b3e9576f43f 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -148,6 +148,7 @@ symbols! {
         associated_type_bounds,
         associated_type_defaults,
         associated_types,
+        assume_init,
         async_await,
         async_closure,
         attr,
@@ -417,7 +418,10 @@ symbols! {
         match_beginning_vert,
         match_default_bindings,
         may_dangle,
-        mem,
+        maybe_uninit_uninit,
+        maybe_uninit_zeroed,
+        mem_uninitialized,
+        mem_zeroed,
         member_constraints,
         message,
         meta,
@@ -428,6 +432,7 @@ symbols! {
         module,
         module_path,
         more_struct_aliases,
+        move_val_init,
         movbe_target_feature,
         must_use,
         naked,
@@ -542,6 +547,8 @@ symbols! {
         recursion_limit,
         reexport_test_harness_main,
         reflect,
+        register_attr,
+        register_tool,
         relaxed_adts,
         repr,
         repr128,
@@ -563,6 +570,7 @@ symbols! {
         rust_2018_preview,
         rust_begin_unwind,
         rustc,
+        Rust,
         RustcDecodable,
         RustcEncodable,
         rustc_allocator,
@@ -709,7 +717,6 @@ symbols! {
         underscore_imports,
         underscore_lifetimes,
         uniform_paths,
-        uninitialized,
         universal_impl_trait,
         unmarked_api,
         unreachable_code,
@@ -734,14 +741,12 @@ symbols! {
         visible_private_types,
         volatile,
         warn,
-        warn_directory_ownership,
         wasm_import_module,
         wasm_target_feature,
         while_let,
         windows,
         windows_subsystem,
         Yield,
-        zeroed,
     }
 }
 
@@ -806,9 +811,9 @@ impl Ident {
         Ident::new(self.name, self.span.modern_and_legacy())
     }
 
-    /// Convert the name to a `LocalInternedString`. This is a slowish
-    /// operation because it requires locking the symbol interner.
-    pub fn as_str(self) -> LocalInternedString {
+    /// Convert the name to a `SymbolStr`. This is a slowish operation because
+    /// it requires locking the symbol interner.
+    pub fn as_str(self) -> SymbolStr {
         self.name.as_str()
     }
 }
@@ -896,11 +901,11 @@ impl Symbol {
         })
     }
 
-    /// Convert to a `LocalInternedString`. This is a slowish operation because
-    /// it requires locking the symbol interner.
-    pub fn as_str(self) -> LocalInternedString {
+    /// Convert to a `SymbolStr`. This is a slowish operation because it
+    /// requires locking the symbol interner.
+    pub fn as_str(self) -> SymbolStr {
         with_interner(|interner| unsafe {
-            LocalInternedString {
+            SymbolStr {
                 string: std::mem::transmute::<&str, &str>(interner.get(self))
             }
         })
@@ -973,6 +978,7 @@ impl Interner {
         self.names.insert(string, name);
         name
     }
+
     // Get the symbol as a string. `Symbol::as_str()` should be used in
     // preference to this function.
     pub fn get(&self, symbol: Symbol) -> &str {
@@ -1078,7 +1084,6 @@ impl Ident {
     }
 }
 
-// If an interner exists, return it. Otherwise, prepare a fresh one.
 #[inline]
 fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
     GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock()))
@@ -1092,46 +1097,42 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
 /// safely treat `string` which points to interner data, as an immortal string,
 /// as long as this type never crosses between threads.
 //
-// FIXME: ensure that the interner outlives any thread which uses
-// `LocalInternedString`, by creating a new thread right after constructing the
-// interner.
+// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
+// by creating a new thread right after constructing the interner.
 #[derive(Clone, Eq, PartialOrd, Ord)]
-pub struct LocalInternedString {
+pub struct SymbolStr {
     string: &'static str,
 }
 
-impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
-where
-    str: std::convert::AsRef<U>
-{
-    #[inline]
-    fn as_ref(&self) -> &U {
-        self.string.as_ref()
-    }
-}
-
-impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for LocalInternedString {
+// This impl allows a `SymbolStr` to be directly equated with a `String` or
+// `&str`.
+impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
     fn eq(&self, other: &T) -> bool {
         self.string == other.deref()
     }
 }
 
-impl !Send for LocalInternedString {}
-impl !Sync for LocalInternedString {}
+impl !Send for SymbolStr {}
+impl !Sync for SymbolStr {}
 
-impl std::ops::Deref for LocalInternedString {
+/// This impl means that if `ss` is a `SymbolStr`:
+/// - `*ss` is a `str`;
+/// - `&*ss` is a `&str`;
+/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
+///   function expecting a `&str`.
+impl std::ops::Deref for SymbolStr {
     type Target = str;
     #[inline]
     fn deref(&self) -> &str { self.string }
 }
 
-impl fmt::Debug for LocalInternedString {
+impl fmt::Debug for SymbolStr {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(self.string, f)
     }
 }
 
-impl fmt::Display for LocalInternedString {
+impl fmt::Display for SymbolStr {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self.string, f)
     }
diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs
index 9de774555e9..e0e211444cf 100644
--- a/src/libtest/tests.rs
+++ b/src/libtest/tests.rs
@@ -269,7 +269,7 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
 fn test_error_on_exceed() {
     let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest];
 
-    for test_type in types.into_iter() {
+    for test_type in types.iter() {
         let result = time_test_failure_template(*test_type);
 
         assert_eq!(result, TestResult::TrTimedFail);
@@ -320,7 +320,7 @@ fn test_time_options_threshold() {
         (TestType::DocTest, doc.critical.as_millis(), true, true),
     ];
 
-    for (test_type, time, expected_warn, expected_critical) in test_vector.into_iter() {
+    for (test_type, time, expected_warn, expected_critical) in test_vector.iter() {
         let test_desc = typed_test_desc(*test_type);
         let exec_time = test_exec_time(*time as u64);
 
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 14a3b123074e066d64a99886941473058e52197
+Subproject cf9304d6d0c6a66c27a1664dd55d8bcc8be0bf0
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 0cda3465dc0..3451346869d 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -343,7 +343,7 @@ extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
 
 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     const char *TripleStr, const char *CPU, const char *Feature,
-    LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
+    const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
     LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
     bool PositionIndependentExecutable, bool FunctionSections,
     bool DataSections,
@@ -374,6 +374,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   Options.FunctionSections = FunctionSections;
   Options.MCOptions.AsmVerbose = AsmComments;
   Options.MCOptions.PreserveAsmComments = AsmComments;
+  Options.MCOptions.ABIName = ABIStr;
 
   if (TrapUnreachable) {
     // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
@@ -754,6 +755,10 @@ LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
   unwrap(Module)->setDataLayout(Target->createDataLayout());
 }
 
+extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
+  unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
+}
+
 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
   unwrap(M)->setPIELevel(PIELevel::Level::Large);
 }
diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs
index 72adb95e96a..8aeee5859d0 100644
--- a/src/test/codegen/abi-efiapi.rs
+++ b/src/test/codegen/abi-efiapi.rs
@@ -1,14 +1,12 @@
 // Checks if the correct annotation for the efiapi ABI is passed to llvm.
 
-// revisions:x86_64 i686 aarch64 arm riscv
+// revisions:x86_64 i686 arm
 
 // min-llvm-version 9.0
 
 //[x86_64] compile-flags: --target x86_64-unknown-uefi
 //[i686] compile-flags: --target i686-unknown-linux-musl
-//[aarch64] compile-flags: --target aarch64-unknown-none
 //[arm] compile-flags: --target armv7r-none-eabi
-//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
@@ -24,8 +22,6 @@ trait Copy { }
 
 //x86_64: define win64cc void @has_efiapi
 //i686: define void @has_efiapi
-//aarch64: define void @has_efiapi
 //arm: define void @has_efiapi
-//riscv: define void @has_efiapi
 #[no_mangle]
 pub extern "efiapi" fn has_efiapi() {}
diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs
index 456d5e74751..7ae1798c7a2 100644
--- a/src/test/incremental/hashes/struct_constructors.rs
+++ b/src/test/incremental/hashes/struct_constructors.rs
@@ -152,7 +152,7 @@ pub fn change_constructor_path_regular_struct() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,typeck_tables_of")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,typeck_tables_of")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_regular_struct() {
     let _ = RegularStruct2 {
@@ -213,7 +213,7 @@ pub fn change_constructor_path_tuple_struct() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,typeck_tables_of")]
+#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,typeck_tables_of")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_constructor_path_tuple_struct() {
     let _ = TupleStruct2(0, 1, 2);
diff --git a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
index 709e9be663e..fa52ca90b10 100644
--- a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
+++ b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
@@ -5,7 +5,7 @@
 // revisions: cfail1 cfail2
 // build-pass (FIXME(62277): could be check-pass?)
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 #![deny(unused_attributes)]
 
 #[rustc_on_unimplemented = "invalid"]
diff --git a/src/test/mir-opt/const_prop/return_place.rs b/src/test/mir-opt/const_prop/return_place.rs
new file mode 100644
index 00000000000..cc9951b554d
--- /dev/null
+++ b/src/test/mir-opt/const_prop/return_place.rs
@@ -0,0 +1,54 @@
+// compile-flags: -C overflow-checks=on
+
+fn add() -> u32 {
+    2 + 2
+}
+
+fn main() {
+    add();
+}
+
+// END RUST SOURCE
+// START rustc.add.ConstProp.before.mir
+// fn add() -> u32 {
+//     let mut _0: u32;
+//     let mut _1: (u32, bool);
+//     bb0: {
+//         _1 = CheckedAdd(const 2u32, const 2u32);
+//         assert(!move (_1.1: bool), "attempt to add with overflow") -> bb1;
+//     }
+//     bb1: {
+//         _0 = move (_1.0: u32);
+//         return;
+//     }
+//     bb2 (cleanup): {
+//         resume;
+//     }
+// }
+// END rustc.add.ConstProp.before.mir
+// START rustc.add.ConstProp.after.mir
+// fn add() -> u32 {
+//     let mut _0: u32;
+//     let mut _1: (u32, bool);
+//     bb0: {
+//         _1 = (const 4u32, const false);
+//         assert(!const false, "attempt to add with overflow") -> bb1;
+//     }
+//     bb1: {
+//         _0 = const 4u32;
+//         return;
+//     }
+//     bb2 (cleanup): {
+//         resume;
+//     }
+// }
+// END rustc.add.ConstProp.after.mir
+// START rustc.add.PreCodegen.before.mir
+// fn add() -> u32 {
+//     let mut _0: u32;
+//     bb0: {
+//         _0 = const 4u32;
+//         return;
+//     }
+// }
+// END rustc.add.PreCodegen.before.mir
diff --git a/src/test/mir-opt/graphviz.rs b/src/test/mir-opt/graphviz.rs
index fdd4e226c5a..fcbb189c111 100644
--- a/src/test/mir-opt/graphviz.rs
+++ b/src/test/mir-opt/graphviz.rs
@@ -7,14 +7,14 @@ fn main() {}
 
 // END RUST SOURCE
 // START rustc.main.mir_map.0.dot
-// digraph Mir_0_12 { // The name here MUST be an ASCII identifier.
+// digraph Mir_0_3 { // The name here MUST be an ASCII identifier.
 //     graph [fontname="monospace"];
 //     node [fontname="monospace"];
 //     edge [fontname="monospace"];
 //     label=<fn main() -&gt; ()<br align="left"/>>;
-//     bb0__0_12 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
-//     bb1__0_12 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>>];
-//     bb2__0_12 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table>>];
-//     bb0__0_12 -> bb2__0_12 [label=""];
+//     bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>];
+//     bb1__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>>];
+//     bb2__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table>>];
+//     bb0__0_3 -> bb2__0_3 [label=""];
 // }
 // END rustc.main.mir_map.0.dot
diff --git a/src/test/mir-opt/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline-closure-borrows-arg.rs
index 0e1db68f372..491130b7c5d 100644
--- a/src/test/mir-opt/inline-closure-borrows-arg.rs
+++ b/src/test/mir-opt/inline-closure-borrows-arg.rs
@@ -20,7 +20,7 @@ fn foo<T: Copy>(_t: T, q: &i32) -> i32 {
 // ...
 // bb0: {
 //     ...
-//     _3 = [closure@HirId { owner: DefIndex(13), local_id: 31 }];
+//     _3 = [closure@HirId { owner: DefIndex(4), local_id: 31 }];
 //     ...
 //     _4 = &_3;
 //     ...
diff --git a/src/test/mir-opt/inline-closure.rs b/src/test/mir-opt/inline-closure.rs
index fa8557f3b38..7c0259b643a 100644
--- a/src/test/mir-opt/inline-closure.rs
+++ b/src/test/mir-opt/inline-closure.rs
@@ -16,7 +16,7 @@ fn foo<T: Copy>(_t: T, q: i32) -> i32 {
 // ...
 // bb0: {
 //     ...
-//     _3 = [closure@HirId { owner: DefIndex(13), local_id: 15 }];
+//     _3 = [closure@HirId { owner: DefIndex(4), local_id: 15 }];
 //     ...
 //     _4 = &_3;
 //     ...
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs
index b275c06e05c..648856b5523 100644
--- a/src/test/mir-opt/match_false_edges.rs
+++ b/src/test/mir-opt/match_false_edges.rs
@@ -39,7 +39,7 @@ fn main() {
 
 // END RUST SOURCE
 //
-// START rustc.full_tested_match.QualifyAndPromoteConstants.after.mir
+// START rustc.full_tested_match.PromoteTemps.after.mir
 //  bb0: {
 //      ...
 //      _2 = std::option::Option::<i32>::Some(const 42i32,);
@@ -108,9 +108,9 @@ fn main() {
 //      _0 = ();
 //      return;
 //  }
-// END rustc.full_tested_match.QualifyAndPromoteConstants.after.mir
+// END rustc.full_tested_match.PromoteTemps.after.mir
 //
-// START rustc.full_tested_match2.QualifyAndPromoteConstants.before.mir
+// START rustc.full_tested_match2.PromoteTemps.before.mir
 //  bb0: {
 //      ...
 //      _2 = std::option::Option::<i32>::Some(const 42i32,);
@@ -179,9 +179,9 @@ fn main() {
 //      _0 = ();
 //      return;
 //  }
-// END rustc.full_tested_match2.QualifyAndPromoteConstants.before.mir
+// END rustc.full_tested_match2.PromoteTemps.before.mir
 //
-// START rustc.main.QualifyAndPromoteConstants.before.mir
+// START rustc.main.PromoteTemps.before.mir
 //  bb0: {
 //     ...
 //      _2 = std::option::Option::<i32>::Some(const 1i32,);
@@ -276,4 +276,4 @@ fn main() {
 //      _0 = ();
 //      return;
 //  }
-// END rustc.main.QualifyAndPromoteConstants.before.mir
+// END rustc.main.PromoteTemps.before.mir
diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index db36a1fab5f..96b848eb1d4 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -100,7 +100,7 @@ fn main() {
 // }
 // END rustc.main.EraseRegions.after.mir
 // START rustc.main-{{closure}}.EraseRegions.after.mir
-// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(22), local_id: 72 }], _2: &i32) -> &i32 {
+// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(13), local_id: 72 }], _2: &i32) -> &i32 {
 //     ...
 //     bb0: {
 //         Retag([fn entry] _1);
diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs
index 2ed34ecfad2..5dc15286bab 100644
--- a/src/test/mir-opt/storage_live_dead_in_statics.rs
+++ b/src/test/mir-opt/storage_live_dead_in_statics.rs
@@ -36,11 +36,11 @@ fn main() {
 // END RUST SOURCE
 // START rustc.XXX.mir_map.0.mir
 //    let mut _0: &'static Foo;
-//    let mut _1: &'static Foo;
+//    let _1: &'static Foo;
 //    let _2: Foo;
 //    let mut _3: &'static [(u32, u32)];
 //    let mut _4: &'static [(u32, u32); 42];
-//    let mut _5: &'static [(u32, u32); 42];
+//    let _5: &'static [(u32, u32); 42];
 //    let _6: [(u32, u32); 42];
 //    let mut _7: (u32, u32);
 //    let mut _8: (u32, u32);
diff --git a/src/test/mir-opt/uninhabited_enum_branching.rs b/src/test/mir-opt/uninhabited_enum_branching.rs
new file mode 100644
index 00000000000..aa56918a9b8
--- /dev/null
+++ b/src/test/mir-opt/uninhabited_enum_branching.rs
@@ -0,0 +1,224 @@
+enum Empty { }
+
+// test matching an enum with uninhabited variants
+enum Test1 {
+    A(Empty),
+    B(Empty),
+    C
+}
+
+// test an enum where the discriminants don't match the variant indexes
+// (the optimization should do nothing here)
+enum Test2 {
+    D = 4,
+    E = 5,
+}
+
+fn main() {
+    match Test1::C {
+        Test1::A(_) => "A(Empty)",
+        Test1::B(_) => "B(Empty)",
+        Test1::C => "C",
+    };
+
+    match Test2::D {
+        Test2::D => "D",
+        Test2::E => "E",
+    };
+}
+
+// END RUST SOURCE
+//
+// START rustc.main.UninhabitedEnumBranching.before.mir
+// let mut _0: ();
+// let _1: &str;
+// let mut _2: Test1;
+// let mut _3: isize;
+// let _4: &str;
+// let _5: &str;
+// let _6: &str;
+// let mut _7: Test2;
+// let mut _8: isize;
+// let _9: &str;
+// bb0: {
+//   StorageLive(_1);
+//   StorageLive(_2);
+//   _2 = Test1::C;
+//   _3 = discriminant(_2);
+//   switchInt(move _3) -> [0isize: bb3, 1isize: bb4, 2isize: bb1, otherwise: bb2];
+// }
+// bb1: {
+//   StorageLive(_5);
+//   _5 = const "C";
+//   _1 = &(*_5);
+//   StorageDead(_5);
+//   goto -> bb5;
+// }
+// bb2: {
+//   unreachable;
+// }
+// bb3: {
+//   _1 = const "A(Empty)";
+//   goto -> bb5;
+// }
+// bb4: {
+//   StorageLive(_4);
+//   _4 = const "B(Empty)";
+//   _1 = &(*_4);
+//   StorageDead(_4);
+//   goto -> bb5;
+// }
+// bb5: {
+//   StorageDead(_2);
+//   StorageDead(_1);
+//   StorageLive(_6);
+//   StorageLive(_7);
+//   _7 = Test2::D;
+//   _8 = discriminant(_7);
+//   switchInt(move _8) -> [4isize: bb8, 5isize: bb6, otherwise: bb7];
+// }
+// bb6: {
+//   StorageLive(_9);
+//   _9 = const "E";
+//   _6 = &(*_9);
+//   StorageDead(_9);
+//   goto -> bb9;
+// }
+// bb7: {
+//   unreachable;
+// }
+// bb8: {
+//   _6 = const "D";
+//   goto -> bb9;
+// }
+// bb9: {
+//   StorageDead(_7);
+//   StorageDead(_6);
+//   _0 = ();
+//   return;
+// }
+// END rustc.main.UninhabitedEnumBranching.before.mir
+// START rustc.main.UninhabitedEnumBranching.after.mir
+// let mut _0: ();
+// let _1: &str;
+// let mut _2: Test1;
+// let mut _3: isize;
+// let _4: &str;
+// let _5: &str;
+// let _6: &str;
+// let mut _7: Test2;
+// let mut _8: isize;
+// let _9: &str;
+// bb0: {
+//   StorageLive(_1);
+//   StorageLive(_2);
+//   _2 = Test1::C;
+//   _3 = discriminant(_2);
+//   switchInt(move _3) -> [2isize: bb1, otherwise: bb2];
+// }
+// bb1: {
+//   StorageLive(_5);
+//   _5 = const "C";
+//   _1 = &(*_5);
+//   StorageDead(_5);
+//   goto -> bb5;
+// }
+// bb2: {
+//   unreachable;
+// }
+// bb3: {
+//   _1 = const "A(Empty)";
+//   goto -> bb5;
+// }
+// bb4: {
+//   StorageLive(_4);
+//   _4 = const "B(Empty)";
+//   _1 = &(*_4);
+//   StorageDead(_4);
+//   goto -> bb5;
+// }
+// bb5: {
+//   StorageDead(_2);
+//   StorageDead(_1);
+//   StorageLive(_6);
+//   StorageLive(_7);
+//   _7 = Test2::D;
+//   _8 = discriminant(_7);
+//   switchInt(move _8) -> [4isize: bb8, 5isize: bb6, otherwise: bb7];
+// }
+// bb6: {
+//   StorageLive(_9);
+//   _9 = const "E";
+//   _6 = &(*_9);
+//   StorageDead(_9);
+//   goto -> bb9;
+// }
+// bb7: {
+//   unreachable;
+// }
+// bb8: {
+//   _6 = const "D";
+//   goto -> bb9;
+// }
+// bb9: {
+//   StorageDead(_7);
+//   StorageDead(_6);
+//   _0 = ();
+//   return;
+// }
+// END rustc.main.UninhabitedEnumBranching.after.mir
+// START rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
+// let mut _0: ();
+// let _1: &str;
+// let mut _2: Test1;
+// let mut _3: isize;
+// let _4: &str;
+// let _5: &str;
+// let _6: &str;
+// let mut _7: Test2;
+// let mut _8: isize;
+// let _9: &str;
+// bb0: {
+//   StorageLive(_1);
+//   StorageLive(_2);
+//   _2 = Test1::C;
+//   _3 = discriminant(_2);
+//   switchInt(move _3) -> [2isize: bb1, otherwise: bb2];
+// }
+// bb1: {
+//   StorageLive(_5);
+//   _5 = const "C";
+//   _1 = &(*_5);
+//   StorageDead(_5);
+//   StorageDead(_2);
+//   StorageDead(_1);
+//   StorageLive(_6);
+//   StorageLive(_7);
+//   _7 = Test2::D;
+//   _8 = discriminant(_7);
+//   switchInt(move _8) -> [4isize: bb5, 5isize: bb3, otherwise: bb4];
+// }
+// bb2: {
+//   unreachable;
+// }
+// bb3: {
+//   StorageLive(_9);
+//   _9 = const "E";
+//   _6 = &(*_9);
+//   StorageDead(_9);
+//   goto -> bb6;
+// }
+// bb4: {
+//   unreachable;
+// }
+// bb5: {
+//   _6 = const "D";
+//   goto -> bb6;
+// }
+// bb6: {
+//   StorageDead(_7);
+//   StorageDead(_6);
+//   _0 = ();
+//   return;
+// }
+// END rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
index a9f25853350..38d1d5bb848 100644
--- a/src/test/run-make-fulldeps/extern-flag-fun/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
@@ -4,7 +4,6 @@ all:
 	$(RUSTC) bar.rs --crate-type=rlib
 	$(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
 	$(RUSTC) bar-alt.rs --crate-type=rlib
-	$(RUSTC) foo.rs --extern hello && exit 1 || exit 0
 	$(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
 	$(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
 	$(RUSTC) foo.rs \
@@ -15,3 +14,6 @@ all:
 		--extern bar=$(TMPDIR)/libbar.rlib \
 		--extern bar=$(TMPDIR)/libbar-a.rlib
 	$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
+	# Try to be sneaky and load a private crate from with a non-private name.
+	$(RUSTC) rustc.rs -Zforce-unstable-if-unmarked --crate-type=rlib
+	$(RUSTC) gated_unstable.rs --extern alloc=$(TMPDIR)/librustc.rlib 2>&1 | $(CGREP) 'rustc_private'
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs b/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
new file mode 100644
index 00000000000..03600c830ff
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
@@ -0,0 +1,3 @@
+extern crate alloc;
+
+fn main() {}
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
new file mode 100644
index 00000000000..b76b4321d62
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/Makefile b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
new file mode 100644
index 00000000000..4849fc62f4a
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
@@ -0,0 +1,18 @@
+-include ../tools.mk
+
+# Test mixing pathless --extern with paths.
+
+all:
+	$(RUSTC) bar-static.rs --crate-name=bar --crate-type=rlib
+	$(RUSTC) bar-dynamic.rs --crate-name=bar --crate-type=dylib -C prefer-dynamic
+	# rlib preferred over dylib
+	$(RUSTC) foo.rs --extern bar
+	$(call RUN,foo) | $(CGREP) 'static'
+	$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib --extern bar
+	$(call RUN,foo) | $(CGREP) 'static'
+	# explicit --extern overrides pathless
+	$(RUSTC) foo.rs --extern bar=$(call DYLIB,bar) --extern bar
+	$(call RUN,foo) | $(CGREP) 'dynamic'
+	# prefer-dynamic does what it says
+	$(RUSTC) foo.rs --extern bar -C prefer-dynamic
+	$(call RUN,foo) | $(CGREP) 'dynamic'
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs b/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs
new file mode 100644
index 00000000000..e2d68d517ff
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs
@@ -0,0 +1,3 @@
+pub fn f() {
+    println!("dynamic");
+}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs b/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
new file mode 100644
index 00000000000..240d8bde4d1
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
@@ -0,0 +1,3 @@
+pub fn f() {
+    println!("static");
+}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs b/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
new file mode 100644
index 00000000000..1ea64da7dad
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
@@ -0,0 +1,3 @@
+fn main() {
+    bar::f();
+}
diff --git a/src/test/run-make-fulldeps/invalid-library/Makefile b/src/test/run-make-fulldeps/invalid-library/Makefile
index b6fb122d98b..c75713c3ee5 100644
--- a/src/test/run-make-fulldeps/invalid-library/Makefile
+++ b/src/test/run-make-fulldeps/invalid-library/Makefile
@@ -1,6 +1,6 @@
 -include ../tools.mk
 
 all:
-	touch $(TMPDIR)/rust.metadata.bin
-	$(AR) crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/rust.metadata.bin
+	touch $(TMPDIR)/lib.rmeta
+	$(AR) crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/lib.rmeta
 	$(RUSTC) foo.rs 2>&1 | $(CGREP) "can't find crate for"
diff --git a/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
index ac42141365e..96fb16b1fcc 100644
--- a/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
+++ b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
@@ -7,12 +7,43 @@
 // Eventually we should see an argument that looks like `@` as we switch from
 // passing literal arguments to passing everything in the file.
 
+use std::collections::HashSet;
 use std::env;
 use std::fs::{self, File};
-use std::io::{BufWriter, Write, Read};
-use std::path::PathBuf;
+use std::io::{BufWriter, Write};
+use std::path::{Path, PathBuf};
 use std::process::Command;
 
+fn write_test_case(file: &Path, n: usize) -> HashSet<String> {
+    let mut libs = HashSet::new();
+    let mut f = BufWriter::new(File::create(&file).unwrap());
+    let mut prefix = String::new();
+    for _ in 0..n {
+        prefix.push_str("foo");
+    }
+    for i in 0..n {
+        writeln!(f, "#[link(name = \"S{}{}S\")]", prefix, i).unwrap();
+        libs.insert(format!("{}{}", prefix, i));
+    }
+    writeln!(f, "extern {{}}\nfn main() {{}}").unwrap();
+    f.into_inner().unwrap();
+
+    libs
+}
+
+fn read_linker_args(path: &Path) -> String {
+    let contents = fs::read(path).unwrap();
+    if cfg!(target_env = "msvc") {
+        let mut i = contents.chunks(2).map(|c| {
+            c[0] as u16 | ((c[1] as u16) << 8)
+        });
+        assert_eq!(i.next(), Some(0xfeff), "Expected UTF-16 BOM");
+        String::from_utf16(&i.collect::<Vec<u16>>()).unwrap()
+    } else {
+        String::from_utf8(contents).unwrap()
+    }
+}
+
 fn main() {
     let tmpdir = PathBuf::from(env::var_os("TMPDIR").unwrap());
     let ok = tmpdir.join("ok");
@@ -29,16 +60,7 @@ fn main() {
     for i in (1..).map(|i| i * 100) {
         println!("attempt: {}", i);
         let file = tmpdir.join("bar.rs");
-        let mut f = BufWriter::new(File::create(&file).unwrap());
-        let mut lib_name = String::new();
-        for _ in 0..i {
-            lib_name.push_str("foo");
-        }
-        for j in 0..i {
-            writeln!(f, "#[link(name = \"{}{}\")]", lib_name, j).unwrap();
-        }
-        writeln!(f, "extern {{}}\nfn main() {{}}").unwrap();
-        f.into_inner().unwrap();
+        let mut expected_libs = write_test_case(&file, i);
 
         drop(fs::remove_file(&ok));
         let output = Command::new(&rustc)
@@ -67,25 +89,18 @@ fn main() {
             continue
         }
 
-        let mut contents = Vec::new();
-        File::open(&ok).unwrap().read_to_end(&mut contents).unwrap();
-
-        for j in 0..i {
-            let exp = format!("{}{}", lib_name, j);
-            let exp = if cfg!(target_env = "msvc") {
-                let mut out = Vec::with_capacity(exp.len() * 2);
-                for c in exp.encode_utf16() {
-                    // encode in little endian
-                    out.push(c as u8);
-                    out.push((c >> 8) as u8);
-                }
-                out
-            } else {
-                exp.into_bytes()
-            };
-            assert!(contents.windows(exp.len()).any(|w| w == &exp[..]));
+        let linker_args = read_linker_args(&ok);
+        for mut arg in linker_args.split('S') {
+            expected_libs.remove(arg);
         }
 
+        assert!(
+            expected_libs.is_empty(),
+            "expected but missing libraries: {:#?}\nlinker arguments: \n{}",
+            expected_libs,
+            linker_args,
+        );
+
         break
     }
 }
diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
index bf98fcd10cf..36288c4b870 100644
--- a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
+++ b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
@@ -1,8 +1,7 @@
 -include ../tools.mk
 
 all: extern_absolute_paths.rs krate2
-	$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 \
-		-Z unstable-options --extern krate2
+	$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 --extern krate2
 	cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py
 
 krate2: krate2.rs
diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.rs b/src/test/rustdoc-ui/intra-links-warning-crlf.rs
index 67bd9f73eeb..ccd2841ff0b 100644
--- a/src/test/rustdoc-ui/intra-links-warning-crlf.rs
+++ b/src/test/rustdoc-ui/intra-links-warning-crlf.rs
@@ -1,19 +1,21 @@
 // ignore-tidy-cr
-
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 // This file checks the spans of intra-link warnings in a file with CRLF line endings. The
 // .gitattributes file in this directory should enforce it.
 
 /// [error]
 pub struct A;
+//~^^ WARNING `[error]` cannot be resolved
 
 ///
 /// docs [error1]
+//~^ WARNING `[error1]` cannot be resolved
 
 /// docs [error2]
 ///
 pub struct B;
+//~^^^ WARNING `[error2]` cannot be resolved
 
 /**
  * This is a multi-line comment.
@@ -21,3 +23,4 @@ pub struct B;
  * It also has an [error].
  */
 pub struct C;
+//~^^^ WARNING `[error]` cannot be resolved
diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
index 720f2106e3d..b4e11c29ed5 100644
--- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
@@ -1,5 +1,5 @@
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning-crlf.rs:8:6
+  --> $DIR/intra-links-warning-crlf.rs:7:6
    |
 LL | /// [error]
    |      ^^^^^ cannot be resolved, ignoring
@@ -16,7 +16,7 @@ LL | /// docs [error1]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error2]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning-crlf.rs:14:11
+  --> $DIR/intra-links-warning-crlf.rs:15:11
    |
 LL | /// docs [error2]
    |           ^^^^^^ cannot be resolved, ignoring
@@ -24,7 +24,7 @@ LL | /// docs [error2]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning-crlf.rs:21:20
+  --> $DIR/intra-links-warning-crlf.rs:23:20
    |
 LL |  * It also has an [error].
    |                    ^^^^^ cannot be resolved, ignoring
diff --git a/src/test/rustdoc-ui/intra-links-warning.rs b/src/test/rustdoc-ui/intra-links-warning.rs
index 20770efa953..b0c637521f9 100644
--- a/src/test/rustdoc-ui/intra-links-warning.rs
+++ b/src/test/rustdoc-ui/intra-links-warning.rs
@@ -1,30 +1,37 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
        //! Test with [Foo::baz], [Bar::foo], ...
+//~^ WARNING `[Foo::baz]` cannot be resolved
+//~| WARNING `[Bar::foo]` cannot be resolved
      //! , [Uniooon::X] and [Qux::Z].
+//~^ WARNING `[Uniooon::X]` cannot be resolved
+//~| WARNING `[Qux::Z]` cannot be resolved
        //!
       //! , [Uniooon::X] and [Qux::Z].
+//~^ WARNING `[Uniooon::X]` cannot be resolved
+//~| WARNING `[Qux::Z]` cannot be resolved
 
        /// [Qux:Y]
+//~^ WARNING `[Qux:Y]` cannot be resolved
 pub struct Foo {
     pub bar: usize,
 }
 
 /// Foo
-/// bar [BarA] bar
+/// bar [BarA] bar //~ WARNING `[BarA]` cannot be resolved
 /// baz
 pub fn a() {}
 
 /**
  * Foo
- * bar [BarB] bar
+ * bar [BarB] bar //~ WARNING `[BarB]` cannot be resolved
  * baz
  */
 pub fn b() {}
 
 /** Foo
 
-bar [BarC] bar
+bar [BarC] bar //~ WARNING `[BarC]` cannot be resolved
 baz
 
     let bar_c_1 = 0;
@@ -35,12 +42,12 @@ baz
 */
 pub fn c() {}
 
-#[doc = "Foo\nbar [BarD] bar\nbaz"]
+#[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `[BarD]` cannot be resolved
 pub fn d() {}
 
 macro_rules! f {
     ($f:expr) => {
-        #[doc = $f]
+        #[doc = $f] //~ WARNING `[BarF]` cannot be resolved
         pub fn f() {}
     }
 }
@@ -48,30 +55,30 @@ f!("Foo\nbar [BarF] bar\nbaz");
 
 /** # for example,
  *
- * time to introduce a link [error]*/
+ * time to introduce a link [error]*/ //~ WARNING `[error]` cannot be resolved
 pub struct A;
 
 /**
  * # for example,
  *
- * time to introduce a link [error]
+ * time to introduce a link [error] //~ WARNING `[error]` cannot be resolved
  */
 pub struct B;
 
-#[doc = "single line [error]"]
+#[doc = "single line [error]"] //~ WARNING `[error]` cannot be resolved
 pub struct C;
 
-#[doc = "single line with \"escaping\" [error]"]
+#[doc = "single line with \"escaping\" [error]"] //~ WARNING `[error]` cannot be resolved
 pub struct D;
 
-/// Item docs.
+/// Item docs. //~ WARNING `[error]` cannot be resolved
 #[doc="Hello there!"]
 /// [error]
 pub struct E;
 
 ///
-/// docs [error1]
+/// docs [error1] //~ WARNING `[error1]` cannot be resolved
 
-/// docs [error2]
+/// docs [error2] //~ WARNING `[error2]` cannot be resolved
 ///
 pub struct F;
diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr
index dac564b3041..27cc3aeb081 100644
--- a/src/test/rustdoc-ui/intra-links-warning.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning.stderr
@@ -16,7 +16,7 @@ LL |        //! Test with [Foo::baz], [Bar::foo], ...
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Uniooon::X]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:4:13
+  --> $DIR/intra-links-warning.rs:6:13
    |
 LL |      //! , [Uniooon::X] and [Qux::Z].
    |             ^^^^^^^^^^ cannot be resolved, ignoring
@@ -24,7 +24,7 @@ LL |      //! , [Uniooon::X] and [Qux::Z].
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Qux::Z]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:4:30
+  --> $DIR/intra-links-warning.rs:6:30
    |
 LL |      //! , [Uniooon::X] and [Qux::Z].
    |                              ^^^^^^ cannot be resolved, ignoring
@@ -32,7 +32,7 @@ LL |      //! , [Uniooon::X] and [Qux::Z].
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Uniooon::X]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:6:14
+  --> $DIR/intra-links-warning.rs:10:14
    |
 LL |       //! , [Uniooon::X] and [Qux::Z].
    |              ^^^^^^^^^^ cannot be resolved, ignoring
@@ -40,7 +40,7 @@ LL |       //! , [Uniooon::X] and [Qux::Z].
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Qux::Z]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:6:31
+  --> $DIR/intra-links-warning.rs:10:31
    |
 LL |       //! , [Uniooon::X] and [Qux::Z].
    |                               ^^^^^^ cannot be resolved, ignoring
@@ -48,7 +48,7 @@ LL |       //! , [Uniooon::X] and [Qux::Z].
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Qux:Y]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:8:13
+  --> $DIR/intra-links-warning.rs:14:13
    |
 LL |        /// [Qux:Y]
    |             ^^^^^ cannot be resolved, ignoring
@@ -56,7 +56,7 @@ LL |        /// [Qux:Y]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:51:30
+  --> $DIR/intra-links-warning.rs:58:30
    |
 LL |  * time to introduce a link [error]*/
    |                              ^^^^^ cannot be resolved, ignoring
@@ -64,7 +64,7 @@ LL |  * time to introduce a link [error]*/
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:57:30
+  --> $DIR/intra-links-warning.rs:64:30
    |
 LL |  * time to introduce a link [error]
    |                              ^^^^^ cannot be resolved, ignoring
@@ -72,7 +72,7 @@ LL |  * time to introduce a link [error]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:61:1
+  --> $DIR/intra-links-warning.rs:68:1
    |
 LL | #[doc = "single line [error]"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +84,7 @@ LL | #[doc = "single line [error]"]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:64:1
+  --> $DIR/intra-links-warning.rs:71:1
    |
 LL | #[doc = "single line with \"escaping\" [error]"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL | #[doc = "single line with \"escaping\" [error]"]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:67:1
+  --> $DIR/intra-links-warning.rs:74:1
    |
 LL | / /// Item docs.
 LL | | #[doc="Hello there!"]
@@ -110,7 +110,7 @@ LL | | /// [error]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error1]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:73:11
+  --> $DIR/intra-links-warning.rs:80:11
    |
 LL | /// docs [error1]
    |           ^^^^^^ cannot be resolved, ignoring
@@ -118,7 +118,7 @@ LL | /// docs [error1]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error2]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:75:11
+  --> $DIR/intra-links-warning.rs:82:11
    |
 LL | /// docs [error2]
    |           ^^^^^^ cannot be resolved, ignoring
@@ -126,7 +126,7 @@ LL | /// docs [error2]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarA]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:14:10
+  --> $DIR/intra-links-warning.rs:21:10
    |
 LL | /// bar [BarA] bar
    |          ^^^^ cannot be resolved, ignoring
@@ -134,7 +134,7 @@ LL | /// bar [BarA] bar
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarB]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:20:9
+  --> $DIR/intra-links-warning.rs:27:9
    |
 LL |  * bar [BarB] bar
    |         ^^^^ cannot be resolved, ignoring
@@ -142,7 +142,7 @@ LL |  * bar [BarB] bar
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarC]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:27:6
+  --> $DIR/intra-links-warning.rs:34:6
    |
 LL | bar [BarC] bar
    |      ^^^^ cannot be resolved, ignoring
@@ -150,7 +150,7 @@ LL | bar [BarC] bar
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarD]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:38:1
+  --> $DIR/intra-links-warning.rs:45:1
    |
 LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -162,7 +162,7 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
    = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarF]` cannot be resolved, ignoring it...
-  --> $DIR/intra-links-warning.rs:43:9
+  --> $DIR/intra-links-warning.rs:50:9
    |
 LL |         #[doc = $f]
    |         ^^^^^^^^^^^
diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs
index 97a0f4aaec1..34e92c42104 100644
--- a/src/test/rustdoc-ui/invalid-syntax.rs
+++ b/src/test/rustdoc-ui/invalid-syntax.rs
@@ -1,9 +1,10 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 /// ```
 /// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
 /// ```
 pub fn foo() {}
+//~^^^^ WARNING could not parse code block as Rust code
 
 /// ```
 ///    |
@@ -11,6 +12,7 @@ pub fn foo() {}
 ///    |     ^^^^^^ did you mean `baz::foobar`?
 /// ```
 pub fn bar() {}
+//~^^^^^^ WARNING could not parse code block as Rust code
 
 /// ```
 /// valid
@@ -24,6 +26,7 @@ pub fn bar() {}
 /// "invalid
 /// ```
 pub fn valid_and_invalid() {}
+//~^^^^^^^^ WARNING could not parse code block as Rust code
 
 /// This is a normal doc comment, but...
 ///
@@ -35,6 +38,7 @@ pub fn valid_and_invalid() {}
 ///
 /// Good thing we tested it!
 pub fn baz() {}
+//~^^^^^^ WARNING could not parse code block as Rust code
 
 /// Indented block start
 ///
@@ -43,6 +47,7 @@ pub fn baz() {}
 ///
 /// Indented block end
 pub fn quux() {}
+//~^^^^^ could not parse code block as Rust code
 
 /// Unclosed fence
 ///
@@ -54,26 +59,31 @@ pub fn xyzzy() {}
 ///
 ///     ```
 pub fn blah() {}
+//~^^ WARNING could not parse code block as Rust code
 
 /// ```edition2018
 /// \_
 /// ```
 pub fn blargh() {}
+//~^^^^ WARNING could not parse code block as Rust code
 
 #[doc = "```"]
 /// \_
 #[doc = "```"]
 pub fn crazy_attrs() {}
+//~^^^^ WARNING doc comment contains an invalid Rust code block
 
 /// ```rust
 /// ```
 pub fn empty_rust() {}
+//~^^^ WARNING Rust code block is empty
 
 /// ```
 ///
 ///
 /// ```
 pub fn empty_rust_with_whitespace() {}
+//~^^^^^ WARNING Rust code block is empty
 
 /// ```
 /// let x = 1;
@@ -82,3 +92,4 @@ pub fn empty_rust_with_whitespace() {}
 ///     \____/
 ///
 pub fn indent_after_fenced() {}
+//~^^^ WARNING could not parse code block as Rust code
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index 8ec4338e13f..fe5442163ea 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -53,7 +53,7 @@ help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it
   |                                          ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:8:5
+  --> $DIR/invalid-syntax.rs:9:5
    |
 LL |   /// ```
    |  _____^
@@ -75,7 +75,7 @@ error: unknown start of token: \
   | ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:19:5
+  --> $DIR/invalid-syntax.rs:21:5
    |
 LL |   /// ```
    |  _____^
@@ -95,7 +95,7 @@ error: unknown start of token: \
   | ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:32:5
+  --> $DIR/invalid-syntax.rs:35:5
    |
 LL |   /// ```rust
    |  _____^
@@ -110,7 +110,7 @@ error: unknown start of token: \
   |     ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:41:9
+  --> $DIR/invalid-syntax.rs:45:9
    |
 LL |   ///     code with bad syntax
    |  _________^
@@ -151,7 +151,7 @@ help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it
   |   ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:55:9
+  --> $DIR/invalid-syntax.rs:60:9
    |
 LL | ///     ```
    |         ^^^
@@ -163,7 +163,7 @@ error: unknown start of token: \
   | ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:58:5
+  --> $DIR/invalid-syntax.rs:64:5
    |
 LL |   /// ```edition2018
    |  _____^
@@ -178,7 +178,7 @@ error: unknown start of token: \
   | ^
 
 warning: doc comment contains an invalid Rust code block
-  --> $DIR/invalid-syntax.rs:63:1
+  --> $DIR/invalid-syntax.rs:70:1
    |
 LL | / #[doc = "```"]
 LL | | /// \_
@@ -188,7 +188,7 @@ LL | | #[doc = "```"]
    = help: mark blocks that do not contain Rust code as text: ```text
 
 warning: Rust code block is empty
-  --> $DIR/invalid-syntax.rs:68:5
+  --> $DIR/invalid-syntax.rs:76:5
    |
 LL |   /// ```rust
    |  _____^
@@ -196,7 +196,7 @@ LL | | /// ```
    | |_______^
 
 warning: Rust code block is empty
-  --> $DIR/invalid-syntax.rs:72:5
+  --> $DIR/invalid-syntax.rs:81:5
    |
 LL |   /// ```
    |  _____^
@@ -217,72 +217,8 @@ error: unknown start of token: \
   | ^
 
 warning: could not parse code block as Rust code
-  --> $DIR/invalid-syntax.rs:82:9
+  --> $DIR/invalid-syntax.rs:92:9
    |
 LL | ///     \____/
    |         ^^^^^^
 
-error: unknown start of token: \
- --> <rustdoc-highlighting>:1:1
-  |
-1 | \____/
-  | ^
-
-error: unknown start of token: \
- --> <rustdoc-highlighting>:1:1
-  |
-1 | \_
-  | ^
-
-error: unknown start of token: \
- --> <rustdoc-highlighting>:1:1
-  |
-1 | \_
-  | ^
-
-error: unknown start of token: `
- --> <rustdoc-highlighting>:1:1
-  |
-1 | ```
-  | ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-1 | '``
-  | ^
-
-error: unknown start of token: \
- --> <rustdoc-highlighting>:2:1
-  |
-2 | \_
-  | ^
-
-error: unknown start of token: \
- --> <rustdoc-highlighting>:1:1
-  |
-1 | \_
-  | ^
-
-error: unknown start of token: \
- --> <rustdoc-highlighting>:1:1
-  |
-1 | \_
-  | ^
-
-error: unknown start of token: `
- --> <rustdoc-highlighting>:3:30
-  |
-3 |    |     ^^^^^^ did you mean `baz::foobar`?
-  |                              ^
-  |
-help: Unicode character '`' (Grave Accent) looks like ''' (Single Quote), but it is not
-  |
-3 |    |     ^^^^^^ did you mean 'baz::foobar`?
-  |                              ^
-
-error: unknown start of token: \
- --> <rustdoc-highlighting>:1:1
-  |
-1 | \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
-  | ^
-
diff --git a/src/test/rustdoc/inline_cross/use_crate.rs b/src/test/rustdoc/inline_cross/use_crate.rs
index f678ba0a46c..00e0f041c56 100644
--- a/src/test/rustdoc/inline_cross/use_crate.rs
+++ b/src/test/rustdoc/inline_cross/use_crate.rs
@@ -2,7 +2,7 @@
 // aux-build:use_crate_2.rs
 // build-aux-docs
 // edition:2018
-// compile-flags:--extern use_crate --extern use_crate_2 -Z unstable-options
+// compile-flags:--extern use_crate --extern use_crate_2
 
 // During the buildup to Rust 2018, rustdoc would eagerly inline `pub use some_crate;` as if it
 // were a module, so we changed it to make `pub use`ing crate roots remain as a `pub use` statement
diff --git a/src/test/ui-fulldeps/ast_stmt_expr_attr.rs b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
index 927e2c0820e..0bf17302b06 100644
--- a/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
+++ b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
@@ -6,20 +6,23 @@
 #![feature(rustc_private)]
 
 extern crate syntax;
-
+extern crate syntax_expand;
+extern crate rustc_parse;
+extern crate rustc_errors;
+
+use rustc_errors::PResult;
+use rustc_parse::parser::attr::*;
+use rustc_parse::new_parser_from_source_str;
+use rustc_parse::parser::Parser;
 use syntax::ast::*;
 use syntax::attr::*;
 use syntax::ast;
 use syntax::sess::ParseSess;
 use syntax::source_map::{FilePathMapping, FileName};
-use syntax::parse;
-use syntax::parse::PResult;
-use syntax::parse::new_parser_from_source_str;
-use syntax::parse::parser::Parser;
-use syntax::parse::token;
 use syntax::ptr::P;
-use syntax::parse::parser::attr::*;
 use syntax::print::pprust;
+use syntax::token;
+use syntax_expand::config::process_configure_mod;
 use std::fmt;
 
 // Copied out of syntax::util::parser_testing
@@ -71,8 +74,12 @@ fn str_compare<T, F: Fn(&T) -> String>(e: &str, expected: &[T], actual: &[T], f:
     }
 }
 
+fn sess() -> ParseSess {
+    ParseSess::new(FilePathMapping::empty(), process_configure_mod)
+}
+
 fn check_expr_attrs(es: &str, expected: &[&str]) {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = sess();
     let e = expr(es, &ps).expect("parse error");
     let actual = &e.attrs;
     str_compare(es,
@@ -82,7 +89,7 @@ fn check_expr_attrs(es: &str, expected: &[&str]) {
 }
 
 fn check_stmt_attrs(es: &str, expected: &[&str]) {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = sess();
     let e = stmt(es, &ps).expect("parse error");
     let actual = e.kind.attrs();
     str_compare(es,
@@ -92,7 +99,7 @@ fn check_stmt_attrs(es: &str, expected: &[&str]) {
 }
 
 fn reject_expr_parse(es: &str) {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = sess();
     match expr(es, &ps) {
         Ok(_) => panic!("parser did not reject `{}`", es),
         Err(mut e) => e.cancel(),
@@ -100,7 +107,7 @@ fn reject_expr_parse(es: &str) {
 }
 
 fn reject_stmt_parse(es: &str) {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = sess();
     match stmt(es, &ps) {
         Ok(_) => panic!("parser did not reject `{}`", es),
         Err(mut e) => e.cancel(),
diff --git a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
index 3524f449c74..520347faa15 100644
--- a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
+++ b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
@@ -15,7 +15,7 @@ extern crate syntax_pos;
 extern crate rustc;
 extern crate rustc_driver;
 
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::tokenstream::{TokenTree, TokenStream};
 use syntax_expand::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax_pos::Span;
diff --git a/src/test/ui-fulldeps/issue-15778-pass.rs b/src/test/ui-fulldeps/issue-15778-pass.rs
index b93630d56b0..4b3cf07e283 100644
--- a/src/test/ui-fulldeps/issue-15778-pass.rs
+++ b/src/test/ui-fulldeps/issue-15778-pass.rs
@@ -3,9 +3,17 @@
 // ignore-stage1
 // compile-flags: -D crate-not-okay
 
-#![feature(plugin, custom_attribute, custom_inner_attributes, rustc_attrs)]
+#![feature(plugin, register_attr, custom_inner_attributes, rustc_attrs)]
 
-#![plugin(lint_for_crate_rpass)]
+#![register_attr(
+    rustc_crate_okay,
+    rustc_crate_blue,
+    rustc_crate_red,
+    rustc_crate_grey,
+    rustc_crate_green,
+)]
+
+#![plugin(lint_for_crate_rpass)] //~ WARNING compiler plugins are deprecated
 #![rustc_crate_okay]
 #![rustc_crate_blue]
 #![rustc_crate_red]
diff --git a/src/test/ui-fulldeps/issue-15778-pass.stderr b/src/test/ui-fulldeps/issue-15778-pass.stderr
index 0c30d2cdcbf..48b42958489 100644
--- a/src/test/ui-fulldeps/issue-15778-pass.stderr
+++ b/src/test/ui-fulldeps/issue-15778-pass.stderr
@@ -1,5 +1,5 @@
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/issue-15778-pass.rs:8:1
+  --> $DIR/issue-15778-pass.rs:16:1
    |
 LL | #![plugin(lint_for_crate_rpass)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
diff --git a/src/test/ui-fulldeps/issue-40001.rs b/src/test/ui-fulldeps/issue-40001.rs
index 65e188ed1b6..e0dc3d6a45b 100644
--- a/src/test/ui-fulldeps/issue-40001.rs
+++ b/src/test/ui-fulldeps/issue-40001.rs
@@ -3,7 +3,7 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(issue_40001_plugin)]
+#![plugin(issue_40001_plugin)] //~ WARNING compiler plugins are deprecated
 
 #[whitelisted_attr]
 fn main() {}
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs
index 8017379ab3d..1cc16e2fd1c 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.rs
@@ -1,11 +1,10 @@
-// run-pass
+// check-pass
 // aux-build:lint-plugin-test.rs
 // ignore-stage1
 // compile-flags: -A test-lint
 
 #![feature(plugin)]
-#![warn(unused)]
-#![plugin(lint_plugin_test)]
+#![plugin(lint_plugin_test)] //~ WARNING compiler plugins are deprecated
 
 fn lintme() { }
 
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr
index c6d198dc458..77265782fa3 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr
@@ -1,21 +1,8 @@
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-plugin-cmdline-allow.rs:8:1
+  --> $DIR/lint-plugin-cmdline-allow.rs:7:1
    |
 LL | #![plugin(lint_plugin_test)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
    |
    = note: `#[warn(deprecated)]` on by default
 
-warning: function is never used: `lintme`
-  --> $DIR/lint-plugin-cmdline-allow.rs:10:1
-   |
-LL | fn lintme() { }
-   | ^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/lint-plugin-cmdline-allow.rs:7:9
-   |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
-
diff --git a/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs
index 529f04c6fc4..83a8b3e1a7e 100644
--- a/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.rs
@@ -1,12 +1,12 @@
-// run-pass
+// check-pass
 // aux-build:lint-tool-test.rs
 // ignore-stage1
 // compile-flags: -A test-lint
 
 #![feature(plugin)]
-#![warn(unused)]
-#![plugin(lint_tool_test)]
+#![plugin(lint_tool_test)] //~ WARNING compiler plugins are deprecated
 
 fn lintme() {}
+//~^ WARNING item is named 'lintme' [clippy::test_lint]
 
 pub fn main() {}
diff --git a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
index 239732521d5..825a341c5d3 100644
--- a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
@@ -3,7 +3,7 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore
    = note: requested on the command line with `-A test_lint`
 
 warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
-  --> $DIR/lint-tool-cmdline-allow.rs:8:1
+  --> $DIR/lint-tool-cmdline-allow.rs:7:1
    |
 LL | #![plugin(lint_tool_test)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
@@ -11,23 +11,10 @@ LL | #![plugin(lint_tool_test)]
    = note: `#[warn(deprecated)]` on by default
 
 warning: item is named 'lintme'
-  --> $DIR/lint-tool-cmdline-allow.rs:10:1
+  --> $DIR/lint-tool-cmdline-allow.rs:9:1
    |
 LL | fn lintme() {}
    | ^^^^^^^^^^^^^^
    |
    = note: `#[warn(clippy::test_lint)]` on by default
 
-warning: function is never used: `lintme`
-  --> $DIR/lint-tool-cmdline-allow.rs:10:1
-   |
-LL | fn lintme() {}
-   | ^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/lint-tool-cmdline-allow.rs:7:9
-   |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
-
diff --git a/src/test/ui-fulldeps/llvm-pass-plugin.rs b/src/test/ui-fulldeps/llvm-pass-plugin.rs
index a9b53fa8c74..fa5cbc1e808 100644
--- a/src/test/ui-fulldeps/llvm-pass-plugin.rs
+++ b/src/test/ui-fulldeps/llvm-pass-plugin.rs
@@ -3,6 +3,6 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(llvm_pass_plugin)]
+#![plugin(llvm_pass_plugin)] //~ WARNING compiler plugins are deprecated
 
 pub fn main() { }
diff --git a/src/test/ui-fulldeps/lto-syntax-extension.rs b/src/test/ui-fulldeps/lto-syntax-extension.rs
index 135861dd772..5964e70f195 100644
--- a/src/test/ui-fulldeps/lto-syntax-extension.rs
+++ b/src/test/ui-fulldeps/lto-syntax-extension.rs
@@ -6,7 +6,7 @@
 // no-prefer-dynamic
 
 #![feature(plugin)]
-#![plugin(lto_syntax_extension_plugin)]
+#![plugin(lto_syntax_extension_plugin)] //~ WARNING compiler plugins are deprecated
 
 extern crate lto_syntax_extension_lib;
 
diff --git a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
index ac97ec70be2..2411b9634c3 100644
--- a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -5,11 +5,14 @@
 #![feature(rustc_private)]
 
 extern crate syntax;
+extern crate syntax_expand;
+extern crate rustc_parse;
 
+use rustc_parse::new_parser_from_file;
 use std::path::Path;
 use syntax::sess::ParseSess;
 use syntax::source_map::FilePathMapping;
-use syntax::parse;
+use syntax_expand::config::process_configure_mod;
 
 #[path = "mod_dir_simple/test.rs"]
 mod gravy;
@@ -21,10 +24,10 @@ pub fn main() {
 }
 
 fn parse() {
-    let parse_session = ParseSess::new(FilePathMapping::empty());
+    let parse_session = ParseSess::new(FilePathMapping::empty(), process_configure_mod);
 
     let path = Path::new(file!());
     let path = path.canonicalize().unwrap();
-    let mut parser = parse::new_parser_from_file(&parse_session, &path);
+    let mut parser = new_parser_from_file(&parse_session, &path);
     let _ = parser.parse_crate_mod();
 }
diff --git a/src/test/ui-fulldeps/outlive-expansion-phase.rs b/src/test/ui-fulldeps/outlive-expansion-phase.rs
index 752f1da7377..fb22888d98a 100644
--- a/src/test/ui-fulldeps/outlive-expansion-phase.rs
+++ b/src/test/ui-fulldeps/outlive-expansion-phase.rs
@@ -3,6 +3,6 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(outlive_expansion_phase)]
+#![plugin(outlive_expansion_phase)] //~ WARNING compiler plugins are deprecated
 
 pub fn main() {}
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.rs b/src/test/ui-fulldeps/pathless-extern-unstable.rs
new file mode 100644
index 00000000000..00b3ec5409f
--- /dev/null
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.rs
@@ -0,0 +1,10 @@
+// ignore-stage1
+// edition:2018
+// compile-flags:--extern rustc
+
+// Test that `--extern rustc` fails with `rustc_private`.
+
+pub use rustc;
+//~^ ERROR use of unstable library feature 'rustc_private'
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.stderr b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
new file mode 100644
index 00000000000..edc3b1c58be
--- /dev/null
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+  --> $DIR/pathless-extern-unstable.rs:7:9
+   |
+LL | pub use rustc;
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/27812
+   = help: add `#![feature(rustc_private)]` 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-fulldeps/plugin-args-1.rs b/src/test/ui-fulldeps/plugin-args-1.rs
index d6437146775..739b6e74b8a 100644
--- a/src/test/ui-fulldeps/plugin-args-1.rs
+++ b/src/test/ui-fulldeps/plugin-args-1.rs
@@ -3,7 +3,7 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(plugin_args)]
+#![plugin(plugin_args)] //~ WARNING compiler plugins are deprecated
 
 fn main() {
     assert_eq!(plugin_args!(), "");
diff --git a/src/test/ui-fulldeps/plugin-args-2.rs b/src/test/ui-fulldeps/plugin-args-2.rs
index 949f8440379..5c8be3d2f50 100644
--- a/src/test/ui-fulldeps/plugin-args-2.rs
+++ b/src/test/ui-fulldeps/plugin-args-2.rs
@@ -3,7 +3,7 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(plugin_args())]
+#![plugin(plugin_args())] //~ WARNING compiler plugins are deprecated
 
 fn main() {
     assert_eq!(plugin_args!(), "");
diff --git a/src/test/ui-fulldeps/plugin-args-3.rs b/src/test/ui-fulldeps/plugin-args-3.rs
index efdbcd0bf0d..2d72bdf0b1b 100644
--- a/src/test/ui-fulldeps/plugin-args-3.rs
+++ b/src/test/ui-fulldeps/plugin-args-3.rs
@@ -3,7 +3,7 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(plugin_args(hello(there), how(are="you")))]
+#![plugin(plugin_args(hello(there), how(are="you")))] //~ WARNING compiler plugins are deprecated
 
 fn main() {
     assert_eq!(plugin_args!(), "hello(there), how(are = \"you\")");
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 932a173bc67..5da0297f645 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -21,21 +21,24 @@
 
 extern crate rustc_data_structures;
 extern crate syntax;
+extern crate syntax_expand;
+extern crate rustc_parse;
 
 use rustc_data_structures::thin_vec::ThinVec;
+use rustc_parse::new_parser_from_source_str;
 use syntax::ast::*;
 use syntax::sess::ParseSess;
 use syntax::source_map::{Spanned, DUMMY_SP, FileName};
 use syntax::source_map::FilePathMapping;
 use syntax::mut_visit::{self, MutVisitor, visit_clobber};
-use syntax::parse;
 use syntax::print::pprust;
 use syntax::ptr::P;
+use syntax_expand::config::process_configure_mod;
 
 fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
 
-    let mut p = parse::new_parser_from_source_str(
+    let mut p = new_parser_from_source_str(
         ps,
         FileName::Custom(src_as_string.clone()),
         src_as_string,
@@ -202,7 +205,7 @@ fn main() {
 }
 
 fn run() {
-    let ps = ParseSess::new(FilePathMapping::empty());
+    let ps = ParseSess::new(FilePathMapping::empty(), process_configure_mod);
 
     iter_exprs(2, &mut |mut e| {
         // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`,
diff --git a/src/test/ui-fulldeps/roman-numerals-macro.rs b/src/test/ui-fulldeps/roman-numerals-macro.rs
index 5c4ba3158db..b5823ea3047 100644
--- a/src/test/ui-fulldeps/roman-numerals-macro.rs
+++ b/src/test/ui-fulldeps/roman-numerals-macro.rs
@@ -3,7 +3,7 @@
 // ignore-stage1
 
 #![feature(plugin)]
-#![plugin(roman_numerals)]
+#![plugin(roman_numerals)] //~ WARNING compiler plugins are deprecated
 
 pub fn main() {
     assert_eq!(rn!(MMXV), 2015);
diff --git a/src/test/ui/abi/abi-sysv64-register-usage.rs b/src/test/ui/abi/abi-sysv64-register-usage.rs
index 0c7e2d906b7..88d89fba260 100644
--- a/src/test/ui/abi/abi-sysv64-register-usage.rs
+++ b/src/test/ui/abi/abi-sysv64-register-usage.rs
@@ -33,6 +33,7 @@ pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
 
 // this struct contains 8 i64's, while only 6 can be passed in registers.
 #[cfg(target_arch = "x86_64")]
+#[repr(C)]
 #[derive(PartialEq, Eq, Debug)]
 pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
 
diff --git a/src/test/ui/align-with-extern-c-fn.rs b/src/test/ui/align-with-extern-c-fn.rs
index 09abe4fbf7e..8ba90225c6c 100644
--- a/src/test/ui/align-with-extern-c-fn.rs
+++ b/src/test/ui/align-with-extern-c-fn.rs
@@ -7,7 +7,7 @@
 
 #![feature(repr_align)]
 
-#[repr(align(16))]
+#[repr(align(16), C)]
 pub struct A(i64);
 
 pub extern "C" fn foo(x: A) {}
diff --git a/src/test/ui/anon-params-denied-2018.stderr b/src/test/ui/anon-params-denied-2018.stderr
index 3fcf41a9a60..e7a806a8468 100644
--- a/src/test/ui/anon-params-denied-2018.stderr
+++ b/src/test/ui/anon-params-denied-2018.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/anon-params-denied-2018.rs:6:15
    |
 LL |     fn foo(i32);
-   |               ^ expected one of `:`, `@`, or `|` here
+   |               ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a `self` type, give it a parameter name
@@ -22,7 +22,7 @@ error: expected one of `:`, `@`, or `|`, found `,`
   --> $DIR/anon-params-denied-2018.rs:8:36
    |
 LL |     fn bar_with_default_impl(String, String) {}
-   |                                    ^ expected one of `:`, `@`, or `|` here
+   |                                    ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a `self` type, give it a parameter name
@@ -42,7 +42,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/anon-params-denied-2018.rs:8:44
    |
 LL |     fn bar_with_default_impl(String, String) {}
-   |                                            ^ expected one of `:`, `@`, or `|` here
+   |                                            ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -58,7 +58,7 @@ error: expected one of `:`, `@`, or `|`, found `,`
   --> $DIR/anon-params-denied-2018.rs:13:22
    |
 LL |     fn baz(a:usize, b, c: usize) -> usize {
-   |                      ^ expected one of `:`, `@`, or `|` here
+   |                      ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.rs b/src/test/ui/associated-type-bounds/dyn-lcsit.rs
index 439304fd309..c936fe0550a 100644
--- a/src/test/ui/associated-type-bounds/dyn-lcsit.rs
+++ b/src/test/ui/associated-type-bounds/dyn-lcsit.rs
@@ -2,7 +2,7 @@
 
 #![feature(associated_type_bounds)]
 #![feature(impl_trait_in_bindings)]
-
+//~^ WARNING `impl_trait_in_bindings` is incomplete
 #![allow(non_upper_case_globals)]
 
 use std::ops::Add;
diff --git a/src/test/ui/associated-type-bounds/lcsit.rs b/src/test/ui/associated-type-bounds/lcsit.rs
index 85b6e804b4e..497205f9f18 100644
--- a/src/test/ui/associated-type-bounds/lcsit.rs
+++ b/src/test/ui/associated-type-bounds/lcsit.rs
@@ -2,7 +2,7 @@
 
 #![feature(associated_type_bounds)]
 #![feature(impl_trait_in_bindings)]
-
+//~^ WARNING `impl_trait_in_bindings` is incomplete
 #![allow(non_upper_case_globals)]
 
 use std::ops::Add;
diff --git a/src/test/ui/associated-type-bounds/type-alias.rs b/src/test/ui/associated-type-bounds/type-alias.rs
index 34bc0c9acbf..f74c5ff1edd 100644
--- a/src/test/ui/associated-type-bounds/type-alias.rs
+++ b/src/test/ui/associated-type-bounds/type-alias.rs
@@ -1,19 +1,19 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(associated_type_bounds)]
 
-type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
-type _TaWhere2<T> where T: Iterator<Item: 'static> = T;
-type _TaWhere3<T> where T: Iterator<Item: 'static> = T;
-type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T;
-type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T;
-type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T;
+type _TaWhere1<T> where T: Iterator<Item: Copy> = T; //~ WARNING type_alias_bounds
+type _TaWhere2<T> where T: Iterator<Item: 'static> = T; //~ WARNING type_alias_bounds
+type _TaWhere3<T> where T: Iterator<Item: 'static> = T; //~ WARNING type_alias_bounds
+type _TaWhere4<T> where T: Iterator<Item: 'static + Copy + Send> = T; //~ WARNING type_alias_bounds
+type _TaWhere5<T> where T: Iterator<Item: for<'a> Into<&'a u8>> = T; //~ WARNING type_alias_bounds
+type _TaWhere6<T> where T: Iterator<Item: Iterator<Item: Copy>> = T; //~ WARNING type_alias_bounds
 
-type _TaInline1<T: Iterator<Item: Copy>> = T;
-type _TaInline2<T: Iterator<Item: 'static>> = T;
-type _TaInline3<T: Iterator<Item: 'static>> = T;
-type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T;
-type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T;
-type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T;
+type _TaInline1<T: Iterator<Item: Copy>> = T; //~ WARNING type_alias_bounds
+type _TaInline2<T: Iterator<Item: 'static>> = T; //~ WARNING type_alias_bounds
+type _TaInline3<T: Iterator<Item: 'static>> = T; //~ WARNING type_alias_bounds
+type _TaInline4<T: Iterator<Item: 'static + Copy + Send>> = T; //~ WARNING type_alias_bounds
+type _TaInline5<T: Iterator<Item: for<'a> Into<&'a u8>>> = T; //~ WARNING type_alias_bounds
+type _TaInline6<T: Iterator<Item: Iterator<Item: Copy>>> = T; //~ WARNING type_alias_bounds
 
 fn main() {}
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
index b763b82d540..f5053f6a1c0 100644
--- a/src/test/ui/associated-types/associated-types-issue-20346.stderr
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -4,8 +4,11 @@ error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == std::op
 LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
    |    --------------                ------ required by this bound in `is_iterator_of`
 ...
+LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
+   |                 - this type parameter
+...
 LL |     is_iterator_of::<Option<T>, _>(&adapter);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found type parameter `T`
    |
    = note: expected type `std::option::Option<T>`
               found type `T`
diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs
index 9360d96f05e..67b7c78071c 100644
--- a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs
+++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.rs
@@ -8,4 +8,20 @@ impl Foo for () {
     type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
 }
 
+trait Baz where Self::Assoc: Bar {
+    type Assoc;
+}
+
+impl Baz for () {
+    type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
+}
+
+trait Bat where <Self as Bat>::Assoc: Bar {
+    type Assoc;
+}
+
+impl Bat for () {
+    type Assoc = bool; //~ ERROR the trait bound `bool: Bar` is not satisfied
+}
+
 fn main() {}
diff --git a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
index f1a2e343a7e..072e9dad062 100644
--- a/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
+++ b/src/test/ui/associated-types/point-at-type-on-obligation-failure-2.stderr
@@ -9,6 +9,32 @@ LL | impl Foo for () {
 LL |     type Assoc = bool;
    |     ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
 
-error: aborting due to previous error
+error[E0277]: the trait bound `bool: Bar` is not satisfied
+  --> $DIR/point-at-type-on-obligation-failure-2.rs:16:5
+   |
+LL | trait Baz where Self::Assoc: Bar {
+   |                 ---------------- restricted in this bound
+LL |     type Assoc;
+   |          ----- associated type defined here
+...
+LL | impl Baz for () {
+   | --------------- in this `impl` item
+LL |     type Assoc = bool;
+   |     ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
+
+error[E0277]: the trait bound `bool: Bar` is not satisfied
+  --> $DIR/point-at-type-on-obligation-failure-2.rs:24:5
+   |
+LL | trait Bat where <Self as Bat>::Assoc: Bar {
+   |                 ------------------------- restricted in this bound
+LL |     type Assoc;
+   |          ----- associated type defined here
+...
+LL | impl Bat for () {
+   | --------------- in this `impl` item
+LL |     type Assoc = bool;
+   |     ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
index 4b5e2d59e38..92cef80c193 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
@@ -130,7 +130,7 @@ error: expected one of `.`, `?`, `{`, or an operator, found `}`
   --> $DIR/incorrect-syntax-suggestions.rs:134:1
    |
 LL |     match await { await => () }
-   |     -----                      - expected one of `.`, `?`, `{`, or an operator here
+   |     -----                      - expected one of `.`, `?`, `{`, or an operator
    |     |
    |     while parsing this match expression
 ...
diff --git a/src/test/ui/async-await/issue-61793.rs b/src/test/ui/async-await/issue-61793.rs
index f6084be9167..9180e1d811a 100644
--- a/src/test/ui/async-await/issue-61793.rs
+++ b/src/test/ui/async-await/issue-61793.rs
@@ -3,7 +3,7 @@
 // while those two fields were at the same offset (which is impossible).
 // That is, memory ordering of `(X, ())`, but offsets of `((), X)`.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // edition:2018
 
 async fn foo<F>(_: &(), _: F) {}
diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs
index 5cae0704444..e9079bfdd85 100644
--- a/src/test/ui/async-await/issues/issue-53249.rs
+++ b/src/test/ui/async-await/issues/issue-53249.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 #![feature(arbitrary_self_types)]
diff --git a/src/test/ui/async-await/issues/issue-54752-async-block.rs b/src/test/ui/async-await/issues/issue-54752-async-block.rs
index 64f260cfe01..c2840d7386f 100644
--- a/src/test/ui/async-await/issues/issue-54752-async-block.rs
+++ b/src/test/ui/async-await/issues/issue-54752-async-block.rs
@@ -4,3 +4,4 @@
 // pp-exact
 
 fn main() { let _a = (async  { }); }
+//~^ WARNING unnecessary parentheses around assigned value
diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs
index 9adc0a82323..b602ef153e6 100644
--- a/src/test/ui/async-await/issues/issue-54974.rs
+++ b/src/test/ui/async-await/issues/issue-54974.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 use std::sync::Arc;
diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs
index 1ca05160751..69bbdd0e83a 100644
--- a/src/test/ui/async-await/issues/issue-60518.rs
+++ b/src/test/ui/async-await/issues/issue-60518.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 // This is a regression test to ensure that simple bindings (where replacement arguments aren't
diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
index 788474365c9..e95f7df388c 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -1,6 +1,5 @@
 // edition:2018
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 
 async fn print_dur() {}
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 538430290d2..6c8e0d0a5c4 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:8:5
+  --> $DIR/issue-62009-1.rs:7:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -7,7 +7,7 @@ LL |     async { let (); }.await;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:10:5
+  --> $DIR/issue-62009-1.rs:9:5
    |
 LL |   fn main() {
    |      ---- this is not `async`
@@ -19,7 +19,7 @@ LL | |     }.await;
    | |___________^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:14:5
+  --> $DIR/issue-62009-1.rs:13:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -27,11 +27,11 @@ LL | fn main() {
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied
-  --> $DIR/issue-62009-1.rs:14:5
+error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:13:5: 13:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:13:5
    |
 LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]`
+   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:13:5: 13:15]`
    | 
   ::: $SRC_DIR/libstd/future.rs:LL:COL
    |
diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr
index f89d1810ba4..05cdbff0bf0 100644
--- a/src/test/ui/async-await/no-async-const.stderr
+++ b/src/test/ui/async-await/no-async-const.stderr
@@ -2,7 +2,7 @@ error: expected one of `fn` or `unsafe`, found keyword `const`
   --> $DIR/no-async-const.rs:5:11
    |
 LL | pub async const fn x() {}
-   |           ^^^^^ expected one of `fn` or `unsafe` here
+   |           ^^^^^ expected one of `fn` or `unsafe`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/no-unsafe-async.stderr b/src/test/ui/async-await/no-unsafe-async.stderr
index 79d9f1befd6..bbeb3427849 100644
--- a/src/test/ui/async-await/no-unsafe-async.stderr
+++ b/src/test/ui/async-await/no-unsafe-async.stderr
@@ -2,13 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `async`
   --> $DIR/no-unsafe-async.rs:7:12
    |
 LL |     unsafe async fn g() {}
-   |            ^^^^^ expected one of `extern` or `fn` here
+   |            ^^^^^ expected one of `extern` or `fn`
 
 error: expected one of `extern`, `fn`, or `{`, found keyword `async`
   --> $DIR/no-unsafe-async.rs:11:8
    |
 LL | unsafe async fn f() {}
-   |        ^^^^^ expected one of `extern`, `fn`, or `{` here
+   |        ^^^^^ expected one of `extern`, `fn`, or `{`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/attributes/register-attr-tool-fail.rs b/src/test/ui/attributes/register-attr-tool-fail.rs
new file mode 100644
index 00000000000..84736be844b
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-fail.rs
@@ -0,0 +1,13 @@
+#![feature(register_attr)]
+#![feature(register_tool)]
+
+#![register_attr] //~ ERROR malformed `register_attr` attribute input
+#![register_tool] //~ ERROR malformed `register_tool` attribute input
+
+#![register_attr(a::b)] //~ ERROR `register_attr` only accepts identifiers
+#![register_tool(a::b)] //~ ERROR `register_tool` only accepts identifiers
+
+#![register_attr(attr, attr)] //~ ERROR attribute `attr` was already registered
+#![register_tool(tool, tool)] //~ ERROR tool `tool` was already registered
+
+fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-fail.stderr b/src/test/ui/attributes/register-attr-tool-fail.stderr
new file mode 100644
index 00000000000..77acfcd87cf
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-fail.stderr
@@ -0,0 +1,42 @@
+error: `register_attr` only accepts identifiers
+  --> $DIR/register-attr-tool-fail.rs:7:18
+   |
+LL | #![register_attr(a::b)]
+   |                  ^^^^ not an identifier
+
+error: attribute `attr` was already registered
+  --> $DIR/register-attr-tool-fail.rs:10:24
+   |
+LL | #![register_attr(attr, attr)]
+   |                  ----  ^^^^
+   |                  |
+   |                  already registered here
+
+error: `register_tool` only accepts identifiers
+  --> $DIR/register-attr-tool-fail.rs:8:18
+   |
+LL | #![register_tool(a::b)]
+   |                  ^^^^ not an identifier
+
+error: tool `tool` was already registered
+  --> $DIR/register-attr-tool-fail.rs:11:24
+   |
+LL | #![register_tool(tool, tool)]
+   |                  ----  ^^^^
+   |                  |
+   |                  already registered here
+
+error: malformed `register_attr` attribute input
+  --> $DIR/register-attr-tool-fail.rs:4:1
+   |
+LL | #![register_attr]
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[register_attr(attr1, attr2, ...)]`
+
+error: malformed `register_tool` attribute input
+  --> $DIR/register-attr-tool-fail.rs:5:1
+   |
+LL | #![register_tool]
+   | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[register_tool(tool1, tool2, ...)]`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/attributes/register-attr-tool-import.rs b/src/test/ui/attributes/register-attr-tool-import.rs
new file mode 100644
index 00000000000..3d0cf9154fb
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-import.rs
@@ -0,0 +1,14 @@
+// edition:2018
+
+#![feature(register_attr)]
+#![feature(register_tool)]
+
+#![register_attr(attr)]
+#![register_tool(tool)]
+
+use attr as renamed_attr; // OK
+use tool as renamed_tool; // OK
+
+#[renamed_attr] //~ ERROR cannot use an explicitly registered attribute through an import
+#[renamed_tool::attr] //~ ERROR cannot use a tool module through an import
+fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-import.stderr b/src/test/ui/attributes/register-attr-tool-import.stderr
new file mode 100644
index 00000000000..6f280c8e0d9
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-import.stderr
@@ -0,0 +1,26 @@
+error: cannot use an explicitly registered attribute through an import
+  --> $DIR/register-attr-tool-import.rs:12:3
+   |
+LL | #[renamed_attr]
+   |   ^^^^^^^^^^^^
+   |
+note: the explicitly registered attribute imported here
+  --> $DIR/register-attr-tool-import.rs:9:5
+   |
+LL | use attr as renamed_attr; // OK
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: cannot use a tool module through an import
+  --> $DIR/register-attr-tool-import.rs:13:3
+   |
+LL | #[renamed_tool::attr]
+   |   ^^^^^^^^^^^^
+   |
+note: the tool module imported here
+  --> $DIR/register-attr-tool-import.rs:10:5
+   |
+LL | use tool as renamed_tool; // OK
+   |     ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/attributes/register-attr-tool-prelude.rs b/src/test/ui/attributes/register-attr-tool-prelude.rs
new file mode 100644
index 00000000000..a491773f5eb
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-prelude.rs
@@ -0,0 +1,14 @@
+#![feature(register_attr)]
+#![feature(register_tool)]
+
+#![register_attr(attr)]
+#![register_tool(tool)]
+
+#[no_implicit_prelude]
+mod m {
+    #[attr] //~ ERROR cannot find attribute `attr` in this scope
+    #[tool::attr] //~ ERROR failed to resolve: use of undeclared type or module `tool`
+    fn check() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-prelude.stderr b/src/test/ui/attributes/register-attr-tool-prelude.stderr
new file mode 100644
index 00000000000..66a4eeb6aa4
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-prelude.stderr
@@ -0,0 +1,15 @@
+error[E0433]: failed to resolve: use of undeclared type or module `tool`
+  --> $DIR/register-attr-tool-prelude.rs:10:7
+   |
+LL |     #[tool::attr]
+   |       ^^^^ use of undeclared type or module `tool`
+
+error: cannot find attribute `attr` in this scope
+  --> $DIR/register-attr-tool-prelude.rs:9:7
+   |
+LL |     #[attr]
+   |       ^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/attributes/register-attr-tool-unused.rs b/src/test/ui/attributes/register-attr-tool-unused.rs
new file mode 100644
index 00000000000..546e372f5e3
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-unused.rs
@@ -0,0 +1,10 @@
+#![deny(unused)]
+
+#![feature(register_attr)]
+#![feature(register_tool)]
+
+#[register_attr(attr)] //~ ERROR crate-level attribute should be an inner attribute
+                       //~| ERROR unused attribute
+#[register_tool(tool)] //~ ERROR crate-level attribute should be an inner attribute
+                       //~| ERROR unused attribute
+fn main() {}
diff --git a/src/test/ui/attributes/register-attr-tool-unused.stderr b/src/test/ui/attributes/register-attr-tool-unused.stderr
new file mode 100644
index 00000000000..0756c572c35
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool-unused.stderr
@@ -0,0 +1,33 @@
+error: unused attribute
+  --> $DIR/register-attr-tool-unused.rs:6:1
+   |
+LL | #[register_attr(attr)]
+   | ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/register-attr-tool-unused.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]`
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
+  --> $DIR/register-attr-tool-unused.rs:6:1
+   |
+LL | #[register_attr(attr)]
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: unused attribute
+  --> $DIR/register-attr-tool-unused.rs:8:1
+   |
+LL | #[register_tool(tool)]
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
+  --> $DIR/register-attr-tool-unused.rs:8:1
+   |
+LL | #[register_tool(tool)]
+   | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/attributes/register-attr-tool.rs b/src/test/ui/attributes/register-attr-tool.rs
new file mode 100644
index 00000000000..ee9da74d4fb
--- /dev/null
+++ b/src/test/ui/attributes/register-attr-tool.rs
@@ -0,0 +1,19 @@
+// check-pass
+// compile-flags: --cfg foo
+
+#![feature(register_attr)]
+#![feature(register_tool)]
+
+#![register_attr(attr)]
+#![register_tool(tool)]
+#![register_tool(rustfmt, clippy)] // OK
+#![cfg_attr(foo, register_attr(conditional_attr))]
+#![cfg_attr(foo, register_tool(conditional_tool))]
+
+#[attr]
+#[tool::attr]
+#[rustfmt::attr]
+#[clippy::attr]
+#[conditional_attr]
+#[conditional_tool::attr]
+fn main() {}
diff --git a/src/test/ui/block-expr-precedence.rs b/src/test/ui/block-expr-precedence.rs
index d31eecda9bb..13b2fe9c3d1 100644
--- a/src/test/ui/block-expr-precedence.rs
+++ b/src/test/ui/block-expr-precedence.rs
@@ -58,4 +58,5 @@ pub fn main() {
   if (true) { 12; } {-num};
   if (true) { 12; }; {-num};
   if (true) { 12; };;; -num;
+  //~^ WARNING unnecessary trailing semicolons
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.stderr b/src/test/ui/borrowck/borrowck-init-in-fru.stderr
index a4c042d1c12..f01afe1466a 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fru.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-fru.stderr
@@ -1,8 +1,8 @@
 error[E0381]: use of possibly-uninitialized variable: `origin`
-  --> $DIR/borrowck-init-in-fru.rs:9:5
+  --> $DIR/borrowck-init-in-fru.rs:9:14
    |
 LL |     origin = Point { x: 10, ..origin };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `origin.y`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `origin.y`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
index 1d98067ce73..b87ef3baa4a 100644
--- a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
+++ b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274
 // (for ensuring that NLL respects user-provided lifetime annotations)
diff --git a/src/test/ui/borrowck/slice-index-bounds-check-invalidation.rs b/src/test/ui/borrowck/slice-index-bounds-check-invalidation.rs
new file mode 100644
index 00000000000..0e0e3cda6e2
--- /dev/null
+++ b/src/test/ui/borrowck/slice-index-bounds-check-invalidation.rs
@@ -0,0 +1,82 @@
+// Test that we error if a slice is modified after it has been bounds checked
+// and before we actually index it.
+
+fn modify_before_assert_slice_slice(x: &[&[i32]]) -> i32 {
+    let mut x = x;
+    let z: &[i32] = &[1, 2, 3];
+    let y: &[&[i32]] = &[z];
+    x[{ x = y; 0 }][2]              // OK we haven't checked any bounds before we index `x`.
+}
+
+fn modify_before_assert_array_slice(x: &[&[i32]; 3]) -> i32 {
+    let mut x = x;
+    let z: &[i32] = &[1, 2, 3];
+    let y: &[&[i32]; 3] = &[z, z, z];
+    x[{ x = y; 0 }][2]              // OK we haven't checked any bounds before we index `x`.
+}
+
+fn modify_before_assert_slice_array(x: &[&[i32; 3]]) -> i32 {
+    let mut x = x;
+    let z: &[i32; 3] = &[1, 2, 3];
+    let y: &[&[i32; 3]] = &[z];
+    x[{ x = y; 0 }][2]              // OK we haven't checked any bounds before we index `x`.
+}
+
+fn modify_before_assert_array_array(x: &[&[i32; 3]; 3]) -> i32 {
+    let mut x = x;
+    let z: &[i32; 3] = &[1, 2, 3];
+    let y: &[&[i32; 3]; 3] = &[z, z, z];
+    x[{ x = y; 0 }][2]              // OK we haven't checked any bounds before we index `x`.
+}
+
+fn modify_after_assert_slice_slice(x: &[&[i32]]) -> i32 {
+    let mut x = x;
+    let z: &[i32] = &[1, 2, 3];
+    let y: &[&[i32]] = &[&z];
+    x[1][{ x = y; 2}]               //~ ERROR cannot assign `x` in indexing expression
+}
+
+fn modify_after_assert_array_slice(x: &[&[i32]; 1]) -> i32 {
+    let mut x = x;
+    let z: &[i32] = &[1, 2, 3];
+    let y: &[&[i32]; 1] = &[&z];
+    x[0][{ x = y; 2}]               // OK cannot invalidate a fixed-size array bounds check
+}
+
+fn modify_after_assert_slice_array(x: &[&[i32; 3]]) -> i32 {
+    let mut x = x;
+    let z: &[i32; 3] = &[1, 2, 3];
+    let y: &[&[i32; 3]] = &[&z];
+    x[1][{ x = y; 2}]               //~ ERROR cannot assign `x` in indexing expression
+}
+
+fn modify_after_assert_array_array(x: &[&[i32; 3]; 1]) -> i32 {
+    let mut x = x;
+    let z: &[i32; 3] = &[1, 2, 3];
+    let y: &[&[i32; 3]; 1] = &[&z];
+    x[0][{ x = y; 2}]               // OK cannot invalidate a fixed-size array bounds check
+}
+
+fn modify_after_assert_slice_slice_array(x: &[&[[i32; 1]]]) -> i32 {
+    let mut x = x;
+    let z: &[[i32; 1]] = &[[1], [2], [3]];
+    let y: &[&[[i32; 1]]] = &[&z];
+    x[1][{ x = y; 2}][0]            //~ ERROR cannot assign `x` in indexing expression
+}
+
+fn modify_after_assert_slice_slice_slice(x: &[&[&[i32]]]) -> i32 {
+    let mut x = x;
+    let z: &[&[i32]] = &[&[1], &[2], &[3]];
+    let y: &[&[&[i32]]] = &[z];
+    x[1][{ x = y; 2}][0]            //~ ERROR cannot assign `x` in indexing expression
+}
+
+
+fn main() {
+    println!("{}", modify_after_assert_slice_array(&[&[4, 5, 6], &[9, 10, 11]]));
+    println!("{}", modify_after_assert_slice_slice(&[&[4, 5, 6], &[9, 10, 11]]));
+    println!("{}", modify_after_assert_slice_slice_array(&[&[[4], [5], [6]], &[[9], [10], [11]]]));
+    println!("{}", modify_after_assert_slice_slice_slice(
+        &[&[&[4], &[5], &[6]], &[&[9], &[10], &[11]]]),
+    );
+}
diff --git a/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr b/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr
new file mode 100644
index 00000000000..f9ed16f19cd
--- /dev/null
+++ b/src/test/ui/borrowck/slice-index-bounds-check-invalidation.stderr
@@ -0,0 +1,35 @@
+error[E0510]: cannot assign `x` in indexing expression
+  --> $DIR/slice-index-bounds-check-invalidation.rs:36:12
+   |
+LL |     x[1][{ x = y; 2}]
+   |     ----   ^^^^^ cannot assign
+   |     |
+   |     value is immutable in indexing expression
+
+error[E0510]: cannot assign `x` in indexing expression
+  --> $DIR/slice-index-bounds-check-invalidation.rs:50:12
+   |
+LL |     x[1][{ x = y; 2}]
+   |     ----   ^^^^^ cannot assign
+   |     |
+   |     value is immutable in indexing expression
+
+error[E0510]: cannot assign `x` in indexing expression
+  --> $DIR/slice-index-bounds-check-invalidation.rs:64:12
+   |
+LL |     x[1][{ x = y; 2}][0]
+   |     ----   ^^^^^ cannot assign
+   |     |
+   |     value is immutable in indexing expression
+
+error[E0510]: cannot assign `x` in indexing expression
+  --> $DIR/slice-index-bounds-check-invalidation.rs:71:12
+   |
+LL |     x[1][{ x = y; 2}][0]
+   |     ----   ^^^^^ cannot assign
+   |     |
+   |     value is immutable in indexing expression
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0510`.
diff --git a/src/test/ui/can-begin-expr-check.stderr b/src/test/ui/can-begin-expr-check.stderr
index 0e03e9915fc..d674fc36bc2 100644
--- a/src/test/ui/can-begin-expr-check.stderr
+++ b/src/test/ui/can-begin-expr-check.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `enum`
   --> $DIR/can-begin-expr-check.rs:19:12
    |
 LL |     return enum;
-   |            ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator here
+   |            ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs
index f7b4f2b2454..2e104b599bd 100644
--- a/src/test/ui/closure-expected-type/issue-24421.rs
+++ b/src/test/ui/closure-expected-type/issue-24421.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn test<F: Fn(&u64, &u64)>(f: F) {}
 
diff --git a/src/test/ui/closures/closure-move-sync.rs b/src/test/ui/closures/closure-move-sync.rs
index 951a3bcb5f4..2f1e6c81ae5 100644
--- a/src/test/ui/closures/closure-move-sync.rs
+++ b/src/test/ui/closures/closure-move-sync.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::thread;
 use std::sync::mpsc::channel;
 
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index f676df9c559..ac5e3ccb421 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:8:13
+  --> $DIR/closure-move-sync.rs:7:13
    |
 LL |     let t = thread::spawn(|| {
    |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
@@ -11,10 +11,10 @@ LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:8:27: 11:6 recv:&std::sync::mpsc::Receiver<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:7:27: 10:6 recv:&std::sync::mpsc::Receiver<()>]`
 
 error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:20:5
+  --> $DIR/closure-move-sync.rs:19:5
    |
 LL |     thread::spawn(|| tx.send(()).unwrap());
    |     ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
@@ -26,7 +26,7 @@ LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:20:19: 20:42 tx:&std::sync::mpsc::Sender<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:19:19: 19:42 tx:&std::sync::mpsc::Sender<()>]`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr
index 3372ef6dea1..17d4df2a223 100644
--- a/src/test/ui/codemap_tests/bad-format-args.stderr
+++ b/src/test/ui/codemap_tests/bad-format-args.stderr
@@ -16,7 +16,7 @@ error: expected one of `,`, `.`, `?`, or an operator, found `1`
   --> $DIR/bad-format-args.rs:4:19
    |
 LL |     format!("", 1 1);
-   |                   ^ expected one of `,`, `.`, `?`, or an operator here
+   |                   ^ expected one of `,`, `.`, `?`, or an operator
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/codemap_tests/unicode_3.rs b/src/test/ui/codemap_tests/unicode_3.rs
index b9bcc1b88a3..3994d318681 100644
--- a/src/test/ui/codemap_tests/unicode_3.rs
+++ b/src/test/ui/codemap_tests/unicode_3.rs
@@ -1,6 +1,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 
 fn main() {
-    let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; }
+    let s = "ZͨA͑ͦ͒͋ͤ͑̚L̄͑͋Ĝͨͥ̿͒̽̈́Oͥ͛ͭ!̏"; while true { break; } //~ WARNING while_true
     println!("{}", s);
 }
diff --git a/src/test/ui/coherence/coherence-all-remote.re.stderr b/src/test/ui/coherence/coherence-all-remote.re.stderr
deleted file mode 100644
index 0541db2b850..00000000000
--- a/src/test/ui/coherence/coherence-all-remote.re.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-all-remote.rs:9:6
-   |
-LL | impl<T> Remote1<T> for isize { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-all-remote.rs b/src/test/ui/coherence/coherence-all-remote.rs
index 68c924ee274..5c3bfee822f 100644
--- a/src/test/ui/coherence/coherence-all-remote.rs
+++ b/src/test/ui/coherence/coherence-all-remote.rs
@@ -1,13 +1,9 @@
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
 
 impl<T> Remote1<T> for isize { }
-//[old]~^ ERROR E0210
-//[re]~^^ ERROR E0210
+//~^ ERROR E0210
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-all-remote.old.stderr b/src/test/ui/coherence/coherence-all-remote.stderr
index 0541db2b850..b35ae46f888 100644
--- a/src/test/ui/coherence/coherence-all-remote.old.stderr
+++ b/src/test/ui/coherence/coherence-all-remote.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-all-remote.rs:9:6
+  --> $DIR/coherence-all-remote.rs:6:6
    |
 LL | impl<T> Remote1<T> for isize { }
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/coherence-bigint-int.rs b/src/test/ui/coherence/coherence-bigint-int.rs
index 0c9abdc15e6..02945e9dade 100644
--- a/src/test/ui/coherence/coherence-bigint-int.rs
+++ b/src/test/ui/coherence/coherence-bigint-int.rs
@@ -1,8 +1,5 @@
 // run-pass
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/coherence/coherence-bigint-param.old.stderr b/src/test/ui/coherence/coherence-bigint-param.old.stderr
deleted file mode 100644
index 816ad949a2b..00000000000
--- a/src/test/ui/coherence/coherence-bigint-param.old.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-bigint-param.rs:11:6
-   |
-LL | impl<T> Remote1<BigInt> for T { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-bigint-param.rs b/src/test/ui/coherence/coherence-bigint-param.rs
index 24106b4b348..c6543aaf67d 100644
--- a/src/test/ui/coherence/coherence-bigint-param.rs
+++ b/src/test/ui/coherence/coherence-bigint-param.rs
@@ -1,7 +1,4 @@
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::Remote1;
@@ -9,7 +6,6 @@ use lib::Remote1;
 pub struct BigInt;
 
 impl<T> Remote1<BigInt> for T { }
-//[old]~^ ERROR type parameter `T` must be used as the type parameter for some local type
-//[re]~^^ ERROR E0210
+//~^ ERROR E0210
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-bigint-param.re.stderr b/src/test/ui/coherence/coherence-bigint-param.stderr
index 816ad949a2b..bb81d7adea2 100644
--- a/src/test/ui/coherence/coherence-bigint-param.re.stderr
+++ b/src/test/ui/coherence/coherence-bigint-param.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-bigint-param.rs:11:6
+  --> $DIR/coherence-bigint-param.rs:8:6
    |
 LL | impl<T> Remote1<BigInt> for T { }
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/coherence-bigint-vecint.rs b/src/test/ui/coherence/coherence-bigint-vecint.rs
index 38e0be0aa9a..a5dba90be5c 100644
--- a/src/test/ui/coherence/coherence-bigint-vecint.rs
+++ b/src/test/ui/coherence/coherence-bigint-vecint.rs
@@ -1,8 +1,5 @@
 // run-pass
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.re.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.re.stderr
deleted file mode 100644
index a6d29048b4d..00000000000
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/coherence-blanket-conflicts-with-blanket-implemented.rs:28:1
-   |
-LL | impl<T:Even> MyTrait for T {
-   | -------------------------- first implementation here
-...
-LL | impl<T:Odd> MyTrait for T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs
index 098a13e54bf..93a4bc5fe78 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.rs
@@ -1,7 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::fmt::Debug;
 use std::default::Default;
 
@@ -26,8 +22,7 @@ impl<T:Even> MyTrait for T {
 }
 
 impl<T:Odd> MyTrait for T {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
     fn get(&self) -> usize { 0 }
 }
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.old.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr
index a6d29048b4d..e95826ed4d5 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.old.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-implemented.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/coherence-blanket-conflicts-with-blanket-implemented.rs:28:1
+  --> $DIR/coherence-blanket-conflicts-with-blanket-implemented.rs:24:1
    |
 LL | impl<T:Even> MyTrait for T {
    | -------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.re.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.re.stderr
deleted file mode 100644
index 1f3ddd1dc42..00000000000
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/coherence-blanket-conflicts-with-blanket-unimplemented.rs:24:1
-   |
-LL | impl<T:Even> MyTrait for T {
-   | -------------------------- first implementation here
-...
-LL | impl<T:Odd> MyTrait for T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs
index 5b76fc0174b..950a08ff224 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.rs
@@ -1,7 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::fmt::Debug;
 use std::default::Default;
 
@@ -22,8 +18,7 @@ impl<T:Even> MyTrait for T {
 }
 
 impl<T:Odd> MyTrait for T {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
     fn get(&self) -> usize { 0 }
 }
 
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.old.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr
index 1f3ddd1dc42..ea9838b4520 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.old.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-blanket-unimplemented.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/coherence-blanket-conflicts-with-blanket-unimplemented.rs:24:1
+  --> $DIR/coherence-blanket-conflicts-with-blanket-unimplemented.rs:20:1
    |
 LL | impl<T:Even> MyTrait for T {
    | -------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.re.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.re.stderr
deleted file mode 100644
index 298ac6d1f21..00000000000
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.re.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy`:
-  --> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:18:1
-   |
-LL | impl GoMut for MyThingy {
-   | ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `go_trait`:
-           - impl<G> go_trait::GoMut for G
-             where G: go_trait::Go;
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs
index b0aaf57e2a9..bccbac2ff16 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.rs
@@ -1,7 +1,4 @@
 // aux-build:go_trait.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate go_trait;
 
@@ -16,8 +13,7 @@ impl Go for MyThingy {
 }
 
 impl GoMut for MyThingy {
-//[old]~^ ERROR conflicting implementations
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
     fn go_mut(&mut self, arg: isize) { }
 }
 
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.old.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
index 298ac6d1f21..91cf925e680 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.old.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy`:
-  --> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:18:1
+  --> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1
    |
 LL | impl GoMut for MyThingy {
    | ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.re.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.re.stderr
deleted file mode 100644
index 94bbbdbe0a4..00000000000
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait<MyType>` for type `MyType`:
-  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:26:1
-   |
-LL | impl<T> MyTrait<T> for T {
-   | ------------------------ first implementation here
-...
-LL | impl MyTrait<MyType> for MyType {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
index 9192d123514..6a9db217373 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
@@ -1,7 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::fmt::Debug;
 use std::default::Default;
 
@@ -24,8 +20,7 @@ struct MyType {
 }
 
 impl MyTrait<MyType> for MyType {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
     fn get(&self) -> usize { (*self).clone() }
 }
 
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.old.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
index 94bbbdbe0a4..af4f4d09d7a 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.old.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait<MyType>` for type `MyType`:
-  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:26:1
+  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:22:1
    |
 LL | impl<T> MyTrait<T> for T {
    | ------------------------ first implementation here
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.re.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.re.stderr
deleted file mode 100644
index cf799c20cb4..00000000000
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType`:
-  --> $DIR/coherence-blanket-conflicts-with-specific-trait.rs:24:1
-   |
-LL | impl<T:OtherTrait> MyTrait for T {
-   | -------------------------------- first implementation here
-...
-LL | impl MyTrait for MyType {
-   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs
index 51cb10e6185..02f9217da68 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.rs
@@ -1,10 +1,6 @@
 // Test that a blank impl for all T:PartialEq conflicts with an impl for some
 // specific T when T:PartialEq.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait OtherTrait {
     fn noop(&self);
 }
@@ -22,8 +18,7 @@ struct MyType {
 }
 
 impl MyTrait for MyType {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
     fn get(&self) -> usize { self.dummy }
 }
 
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.old.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr
index cf799c20cb4..6922f3ebffa 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.old.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific-trait.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType`:
-  --> $DIR/coherence-blanket-conflicts-with-specific-trait.rs:24:1
+  --> $DIR/coherence-blanket-conflicts-with-specific-trait.rs:20:1
    |
 LL | impl<T:OtherTrait> MyTrait for T {
    | -------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.re.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.re.stderr
deleted file mode 100644
index 0807b11a434..00000000000
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType`:
-  --> $DIR/coherence-blanket-conflicts-with-specific.rs:23:1
-   |
-LL | impl<T> MyTrait for T {
-   | --------------------- first implementation here
-...
-LL | impl MyTrait for MyType {
-   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs
index 3ecb613188a..5a562ff6ab9 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.rs
@@ -1,7 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::fmt::Debug;
 use std::default::Default;
 
@@ -21,8 +17,7 @@ struct MyType {
 }
 
 impl MyTrait for MyType {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
     fn get(&self) -> usize { self.dummy }
 }
 
diff --git a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.old.stderr b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.stderr
index 0807b11a434..4bc28276479 100644
--- a/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.old.stderr
+++ b/src/test/ui/coherence/coherence-blanket-conflicts-with-specific.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `MyType`:
-  --> $DIR/coherence-blanket-conflicts-with-specific.rs:23:1
+  --> $DIR/coherence-blanket-conflicts-with-specific.rs:19:1
    |
 LL | impl<T> MyTrait for T {
    | --------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-blanket.rs b/src/test/ui/coherence/coherence-blanket.rs
index 5d310cc2c6a..55fa89d7507 100644
--- a/src/test/ui/coherence/coherence-blanket.rs
+++ b/src/test/ui/coherence/coherence-blanket.rs
@@ -1,9 +1,6 @@
 // run-pass
 #![allow(unused_imports)]
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.old.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.old.stderr
deleted file mode 100644
index bb3641f2247..00000000000
--- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.old.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
-  --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
-   |
-LL | unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
-   | ---------------------------------------------------- first implementation here
-LL | 
-LL | impl<T: MyTrait> !Send for TestType<T> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
-
-error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<i32>`:
-  --> $DIR/coherence-conflicting-negative-trait-impl.rs:19:1
-   |
-LL | unsafe impl<T:'static> Send for TestType<T> {}
-   | ------------------------------------------- first implementation here
-LL | 
-LL | impl !Send for TestType<i32> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<i32>`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs
index e05fecb11ed..66d0958e4c9 100644
--- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs
+++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.rs
@@ -1,6 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 #![feature(overlapping_marker_traits)]
 
@@ -11,13 +8,11 @@ struct TestType<T>(::std::marker::PhantomData<T>);
 unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
 
 impl<T: MyTrait> !Send for TestType<T> {}
-//[old]~^ ERROR conflicting implementations of trait `std::marker::Send`
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 unsafe impl<T:'static> Send for TestType<T> {}
 
 impl !Send for TestType<i32> {}
-//[old]~^ ERROR conflicting implementations of trait `std::marker::Send`
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.re.stderr b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
index bb3641f2247..0a8bbc4bc50 100644
--- a/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.re.stderr
+++ b/src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
-  --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:10:1
    |
 LL | unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
    | ---------------------------------------------------- first implementation here
@@ -8,7 +8,7 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
 
 error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<i32>`:
-  --> $DIR/coherence-conflicting-negative-trait-impl.rs:19:1
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1
    |
 LL | unsafe impl<T:'static> Send for TestType<T> {}
    | ------------------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-covered-type-parameter.rs b/src/test/ui/coherence/coherence-covered-type-parameter.rs
index 1cf039f0831..bb95c59d183 100644
--- a/src/test/ui/coherence/coherence-covered-type-parameter.rs
+++ b/src/test/ui/coherence/coherence-covered-type-parameter.rs
@@ -1,9 +1,6 @@
 // run-pass
 #![allow(dead_code)]
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/coherence/coherence-cow.a.stderr b/src/test/ui/coherence/coherence-cow.a.stderr
deleted file mode 100644
index d3f8ba63f07..00000000000
--- a/src/test/ui/coherence/coherence-cow.a.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-cow.rs:18:6
-   |
-LL | impl<T> Remote for Pair<T,Cover<T>> { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-cow.b.stderr b/src/test/ui/coherence/coherence-cow.b.stderr
deleted file mode 100644
index d8db025cbcf..00000000000
--- a/src/test/ui/coherence/coherence-cow.b.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-cow.rs:23:6
-   |
-LL | impl<T> Remote for Pair<Cover<T>,T> { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-cow.c.stderr b/src/test/ui/coherence/coherence-cow.c.stderr
deleted file mode 100644
index ff46d7ea280..00000000000
--- a/src/test/ui/coherence/coherence-cow.c.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-cow.rs:28:6
-   |
-LL | impl<T,U> Remote for Pair<Cover<T>,U> { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-cow.re_b.stderr b/src/test/ui/coherence/coherence-cow.re_b.stderr
index 146232ac02b..39f211eff36 100644
--- a/src/test/ui/coherence/coherence-cow.re_b.stderr
+++ b/src/test/ui/coherence/coherence-cow.re_b.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-cow.rs:23:1
+  --> $DIR/coherence-cow.rs:22:1
    |
 LL | impl<T> Remote for Pair<Cover<T>,T> { }
    | ^^^^^^^^^^^^^^^^^^^----------------
diff --git a/src/test/ui/coherence/coherence-cow.re_c.stderr b/src/test/ui/coherence/coherence-cow.re_c.stderr
index e0cf6aab7bb..94bb0d2166c 100644
--- a/src/test/ui/coherence/coherence-cow.re_c.stderr
+++ b/src/test/ui/coherence/coherence-cow.re_c.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-cow.rs:28:1
+  --> $DIR/coherence-cow.rs:26:1
    |
 LL | impl<T,U> Remote for Pair<Cover<T>,U> { }
    | ^^^^^^^^^^^^^^^^^^^^^----------------
diff --git a/src/test/ui/coherence/coherence-cow.rs b/src/test/ui/coherence/coherence-cow.rs
index 956b0734148..86a8d0963b8 100644
--- a/src/test/ui/coherence/coherence-cow.rs
+++ b/src/test/ui/coherence/coherence-cow.rs
@@ -1,6 +1,6 @@
-// revisions: a b c re_a re_b re_c
+// revisions: re_a re_b re_c
 
-#![cfg_attr(any(re_a, re_b, re_c), feature(re_rebalance_coherence))]
+#![cfg_attr(any(), re_a, re_b, re_c)]
 
 // aux-build:coherence_lib.rs
 
@@ -14,19 +14,16 @@ use lib::{Remote,Pair};
 
 pub struct Cover<T>(T);
 
-#[cfg(any(a, re_a))]
+#[cfg(any(re_a))]
 impl<T> Remote for Pair<T,Cover<T>> { }
-//[a]~^ ERROR E0210
-//[re_a]~^^ ERROR E0117
+//[re_a]~^ ERROR E0117
 
-#[cfg(any(b, re_b))]
+#[cfg(any(re_b))]
 impl<T> Remote for Pair<Cover<T>,T> { }
-//[b]~^ ERROR E0210
-//[re_b]~^^ ERROR E0117
+//[re_b]~^ ERROR E0117
 
-#[cfg(any(c, re_c))]
+#[cfg(any(re_c))]
 impl<T,U> Remote for Pair<Cover<T>,U> { }
-//[c]~^ ERROR type parameter `T` must be used as the type parameter for some local type
-//[re_c]~^^ ERROR E0117
+//[re_c]~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.re.stderr b/src/test/ui/coherence/coherence-cross-crate-conflict.re.stderr
deleted file mode 100644
index 971abe29639..00000000000
--- a/src/test/ui/coherence/coherence-cross-crate-conflict.re.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0119]: conflicting implementations of trait `trait_impl_conflict::Foo` for type `isize`:
-  --> $DIR/coherence-cross-crate-conflict.rs:12:1
-   |
-LL | impl<A> Foo for A {
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `trait_impl_conflict`:
-           - impl trait_impl_conflict::Foo for isize;
-
-error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
-  --> $DIR/coherence-cross-crate-conflict.rs:12:6
-   |
-LL | impl<A> Foo for A {
-   |      ^ type parameter `A` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0119, E0210.
-For more information about an error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.rs b/src/test/ui/coherence/coherence-cross-crate-conflict.rs
index 9643ab643df..648e290a4b8 100644
--- a/src/test/ui/coherence/coherence-cross-crate-conflict.rs
+++ b/src/test/ui/coherence/coherence-cross-crate-conflict.rs
@@ -2,18 +2,13 @@
 // generalizes the one upstream
 
 // aux-build:trait_impl_conflict.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate trait_impl_conflict;
 use trait_impl_conflict::Foo;
 
 impl<A> Foo for A {
-    //[old]~^ ERROR type parameter `A` must be used as the type parameter for some local type
-    //[old]~| ERROR conflicting implementations of trait `trait_impl_conflict::Foo` for type `isize`
-    //[re]~^^^ ERROR E0119
-    //[re]~| ERROR E0210
+    //~^ ERROR E0119
+    //~| ERROR E0210
 }
 
 fn main() {
diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.old.stderr b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr
index 971abe29639..cb66f9b0c7f 100644
--- a/src/test/ui/coherence/coherence-cross-crate-conflict.old.stderr
+++ b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `trait_impl_conflict::Foo` for type `isize`:
-  --> $DIR/coherence-cross-crate-conflict.rs:12:1
+  --> $DIR/coherence-cross-crate-conflict.rs:9:1
    |
 LL | impl<A> Foo for A {
    | ^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | impl<A> Foo for A {
            - impl trait_impl_conflict::Foo for isize;
 
 error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
-  --> $DIR/coherence-cross-crate-conflict.rs:12:6
+  --> $DIR/coherence-cross-crate-conflict.rs:9:6
    |
 LL | impl<A> Foo for A {
    |      ^ type parameter `A` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/coherence-default-trait-impl.re.stderr b/src/test/ui/coherence/coherence-default-trait-impl.re.stderr
deleted file mode 100644
index 3f644e3a6e7..00000000000
--- a/src/test/ui/coherence/coherence-default-trait-impl.re.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0199]: implementing the trait `MySafeTrait` is not unsafe
-  --> $DIR/coherence-default-trait-impl.rs:10:1
-   |
-LL | unsafe impl MySafeTrait for Foo {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
-  --> $DIR/coherence-default-trait-impl.rs:16:1
-   |
-LL | impl MyUnsafeTrait for Foo {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0199, E0200.
-For more information about an error, try `rustc --explain E0199`.
diff --git a/src/test/ui/coherence/coherence-default-trait-impl.rs b/src/test/ui/coherence/coherence-default-trait-impl.rs
index 606b4947b5f..db24662e2d5 100644
--- a/src/test/ui/coherence/coherence-default-trait-impl.rs
+++ b/src/test/ui/coherence/coherence-default-trait-impl.rs
@@ -1,6 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 
 auto trait MySafeTrait {}
@@ -8,13 +5,11 @@ auto trait MySafeTrait {}
 struct Foo;
 
 unsafe impl MySafeTrait for Foo {}
-//[old]~^ ERROR implementing the trait `MySafeTrait` is not unsafe
-//[re]~^^ ERROR E0199
+//~^ ERROR E0199
 
 unsafe auto trait MyUnsafeTrait {}
 
 impl MyUnsafeTrait for Foo {}
-//[old]~^ ERROR the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
-//[re]~^^ ERROR E0200
+//~^ ERROR E0200
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-default-trait-impl.old.stderr b/src/test/ui/coherence/coherence-default-trait-impl.stderr
index 3f644e3a6e7..f6a163268a1 100644
--- a/src/test/ui/coherence/coherence-default-trait-impl.old.stderr
+++ b/src/test/ui/coherence/coherence-default-trait-impl.stderr
@@ -1,11 +1,11 @@
 error[E0199]: implementing the trait `MySafeTrait` is not unsafe
-  --> $DIR/coherence-default-trait-impl.rs:10:1
+  --> $DIR/coherence-default-trait-impl.rs:7:1
    |
 LL | unsafe impl MySafeTrait for Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
-  --> $DIR/coherence-default-trait-impl.rs:16:1
+  --> $DIR/coherence-default-trait-impl.rs:12:1
    |
 LL | impl MyUnsafeTrait for Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/coherence/coherence-error-suppression.re.stderr b/src/test/ui/coherence/coherence-error-suppression.re.stderr
deleted file mode 100644
index b81f7553317..00000000000
--- a/src/test/ui/coherence/coherence-error-suppression.re.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0412]: cannot find type `DoesNotExist` in this scope
-  --> $DIR/coherence-error-suppression.rs:13:14
-   |
-LL | impl Foo for DoesNotExist {}
-   |              ^^^^^^^^^^^^ not found in this scope
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/coherence/coherence-error-suppression.rs b/src/test/ui/coherence/coherence-error-suppression.rs
index 60b88fb80e4..909214c1b6e 100644
--- a/src/test/ui/coherence/coherence-error-suppression.rs
+++ b/src/test/ui/coherence/coherence-error-suppression.rs
@@ -1,9 +1,5 @@
 // check that error types in coherence do not cause error cascades.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait Foo {}
 
 impl Foo for i8 {}
@@ -11,8 +7,7 @@ impl Foo for i16 {}
 impl Foo for i32 {}
 impl Foo for i64 {}
 impl Foo for DoesNotExist {}
-//[old]~^ ERROR cannot find type `DoesNotExist` in this scope
-//[re]~^^ ERROR E0412
+//~^ ERROR E0412
 impl Foo for u8 {}
 impl Foo for u16 {}
 impl Foo for u32 {}
diff --git a/src/test/ui/coherence/coherence-error-suppression.old.stderr b/src/test/ui/coherence/coherence-error-suppression.stderr
index b81f7553317..aadc80cb1c3 100644
--- a/src/test/ui/coherence/coherence-error-suppression.old.stderr
+++ b/src/test/ui/coherence/coherence-error-suppression.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `DoesNotExist` in this scope
-  --> $DIR/coherence-error-suppression.rs:13:14
+  --> $DIR/coherence-error-suppression.rs:9:14
    |
 LL | impl Foo for DoesNotExist {}
    |              ^^^^^^^^^^^^ not found in this scope
diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr b/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr
deleted file mode 100644
index a3da52fe484..00000000000
--- a/src/test/ui/coherence/coherence-fundamental-trait-objects.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-fundamental-trait-objects.rs:15:1
-   |
-LL | impl Misc for dyn Fundamental<Local> {}
-   | ^^^^^^^^^^^^^^----------------------
-   | |             |
-   | |             `dyn coherence_fundamental_trait_lib::Fundamental<Local>` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.rs b/src/test/ui/coherence/coherence-fundamental-trait-objects.rs
index 0c7d54425dd..dd127bf7f4b 100644
--- a/src/test/ui/coherence/coherence-fundamental-trait-objects.rs
+++ b/src/test/ui/coherence/coherence-fundamental-trait-objects.rs
@@ -3,9 +3,6 @@
 // are distinct.
 
 // aux-build:coherence_fundamental_trait_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_fundamental_trait_lib;
 
@@ -13,7 +10,6 @@ use coherence_fundamental_trait_lib::{Fundamental, Misc};
 
 pub struct Local;
 impl Misc for dyn Fundamental<Local> {}
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr b/src/test/ui/coherence/coherence-fundamental-trait-objects.stderr
index a3da52fe484..06cfdeb3907 100644
--- a/src/test/ui/coherence/coherence-fundamental-trait-objects.old.stderr
+++ b/src/test/ui/coherence/coherence-fundamental-trait-objects.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-fundamental-trait-objects.rs:15:1
+  --> $DIR/coherence-fundamental-trait-objects.rs:12:1
    |
 LL | impl Misc for dyn Fundamental<Local> {}
    | ^^^^^^^^^^^^^^----------------------
diff --git a/src/test/ui/coherence/coherence-impl-in-fn.rs b/src/test/ui/coherence/coherence-impl-in-fn.rs
index 09e2c1e5a4e..b9719731748 100644
--- a/src/test/ui/coherence/coherence-impl-in-fn.rs
+++ b/src/test/ui/coherence/coherence-impl-in-fn.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
deleted file mode 100644
index 18a7cea95bd..00000000000
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0038]: the trait `NotObjectSafe` cannot be made into an object
-  --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
-   |
-LL | trait NotObjectSafe { fn eq(&self, other: Self); }
-   |                          -- method `eq` references the `Self` type in its parameters or return type
-LL | impl NotObjectSafe for dyn NotObjectSafe { }
-   |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs
index b4c88e93783..20ff875491f 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.rs
@@ -1,15 +1,10 @@
 // Test that we give suitable error messages when the user attempts to
 // impl a trait `Trait` for its own object type.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 // If the trait is not object-safe, we give a more tailored message
 // because we're such schnuckels:
 trait NotObjectSafe { fn eq(&self, other: Self); }
 impl NotObjectSafe for dyn NotObjectSafe { }
-//[old]~^ ERROR E0038
-//[re]~^^ ERROR E0038
+//~^ ERROR E0038
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
index 18a7cea95bd..ed6be60de46 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
-  --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
+  --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6
    |
 LL | trait NotObjectSafe { fn eq(&self, other: Self); }
    |                          -- method `eq` references the `Self` type in its parameters or return type
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait.re.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait.re.stderr
deleted file mode 100644
index 4819ce9260e..00000000000
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait.re.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Foo`
-  --> $DIR/coherence-impl-trait-for-trait.rs:13:1
-   |
-LL | impl Foo for dyn Baz { }
-   | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Foo`
-
-error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Bar`
-  --> $DIR/coherence-impl-trait-for-trait.rs:16:1
-   |
-LL | impl Bar for dyn Baz { }
-   | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Bar`
-
-error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Baz`
-  --> $DIR/coherence-impl-trait-for-trait.rs:19:1
-   |
-LL | impl Baz for dyn Baz { }
-   | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Baz`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0371`.
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait.rs b/src/test/ui/coherence/coherence-impl-trait-for-trait.rs
index 3ce3dca0660..195a37f15a4 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait.rs
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait.rs
@@ -1,24 +1,17 @@
 // Test that we give suitable error messages when the user attempts to
 // impl a trait `Trait` for its own object type.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait Foo { fn dummy(&self) { } }
 trait Bar: Foo { }
 trait Baz: Bar { }
 
 // Supertraits of Baz are not legal:
 impl Foo for dyn Baz { }
-//[old]~^ ERROR E0371
-//[re]~^^ ERROR E0371
+//~^ ERROR E0371
 impl Bar for dyn Baz { }
-//[old]~^ ERROR E0371
-//[re]~^^ ERROR E0371
+//~^ ERROR E0371
 impl Baz for dyn Baz { }
-//[old]~^ ERROR E0371
-//[re]~^^ ERROR E0371
+//~^ ERROR E0371
 
 // But other random traits are:
 trait Other { }
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait.old.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait.stderr
index 4819ce9260e..cf0b38c5bb8 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait.old.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait.stderr
@@ -1,17 +1,17 @@
 error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Foo`
-  --> $DIR/coherence-impl-trait-for-trait.rs:13:1
+  --> $DIR/coherence-impl-trait-for-trait.rs:9:1
    |
 LL | impl Foo for dyn Baz { }
    | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Foo`
 
 error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Bar`
-  --> $DIR/coherence-impl-trait-for-trait.rs:16:1
+  --> $DIR/coherence-impl-trait-for-trait.rs:11:1
    |
 LL | impl Bar for dyn Baz { }
    | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Bar`
 
 error[E0371]: the object type `(dyn Baz + 'static)` automatically implements the trait `Baz`
-  --> $DIR/coherence-impl-trait-for-trait.rs:19:1
+  --> $DIR/coherence-impl-trait-for-trait.rs:13:1
    |
 LL | impl Baz for dyn Baz { }
    | ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` automatically implements trait `Baz`
diff --git a/src/test/ui/coherence/coherence-impls-copy.re.stderr b/src/test/ui/coherence/coherence-impls-copy.re.stderr
deleted file mode 100644
index 742845b1907..00000000000
--- a/src/test/ui/coherence/coherence-impls-copy.re.stderr
+++ /dev/null
@@ -1,95 +0,0 @@
-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `i32`:
-  --> $DIR/coherence-impls-copy.rs:8:1
-   |
-LL | impl Copy for i32 {}
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl std::marker::Copy for i32;
-
-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`:
-  --> $DIR/coherence-impls-copy.rs:37:1
-   |
-LL | impl Copy for &'static NotSync {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T> std::marker::Copy for &T
-             where T: ?Sized;
-
-error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
-  --> $DIR/coherence-impls-copy.rs:45:1
-   |
-LL | impl Copy for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: conflicting implementation in crate `core`:
-           - impl<T> std::marker::Copy for &T
-             where T: ?Sized;
-
-error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:27:15
-   |
-LL | impl Copy for &'static mut MyType {}
-   |               ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration
-
-error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:32:15
-   |
-LL | impl Copy for (MyType, MyType) {}
-   |               ^^^^^^^^^^^^^^^^ type is not a structure or enumeration
-
-error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:40:15
-   |
-LL | impl Copy for [MyType] {}
-   |               ^^^^^^^^ type is not a structure or enumeration
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:8:1
-   |
-LL | impl Copy for i32 {}
-   | ^^^^^^^^^^^^^^---
-   | |             |
-   | |             `i32` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:32:1
-   |
-LL | impl Copy for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^----------------
-   | |             |
-   | |             this is not defined in the current crate because tuples are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:40:1
-   |
-LL | impl Copy for [MyType] {}
-   | ^^^^^^^^^^^^^^--------
-   | |             |
-   | |             this is not defined in the current crate because slices are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:45:1
-   |
-LL | impl Copy for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^------------------
-   | |             |
-   | |             this is not defined in the current crate because slices are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to 10 previous errors
-
-Some errors have detailed explanations: E0117, E0119, E0206.
-For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-impls-copy.rs b/src/test/ui/coherence/coherence-impls-copy.rs
index 97133bc33ce..dec40f9dd40 100644
--- a/src/test/ui/coherence/coherence-impls-copy.rs
+++ b/src/test/ui/coherence/coherence-impls-copy.rs
@@ -1,15 +1,10 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 
 use std::marker::Copy;
 
 impl Copy for i32 {}
-//[old]~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `i32`:
-//[old]~| ERROR only traits defined in the current crate can be implemented for arbitrary types
-//[re]~^^^ ERROR E0119
-//[re]~| ERROR E0117
+//~^ ERROR E0119
+//~| ERROR E0117
 enum TestE {
   A
 }
@@ -25,27 +20,19 @@ impl Clone for TestE { fn clone(&self) -> Self { *self } }
 impl Copy for MyType {}
 
 impl Copy for &'static mut MyType {}
-//[old]~^ ERROR the trait `Copy` may not be implemented for this type
-//[re]~^^ ERROR E0206
+//~^ ERROR E0206
 impl Clone for MyType { fn clone(&self) -> Self { *self } }
 
 impl Copy for (MyType, MyType) {}
-//[old]~^ ERROR the trait `Copy` may not be implemented for this type
-//[old]~| ERROR only traits defined in the current crate can be implemented for arbitrary types
-//[re]~^^^ ERROR E0206
-//[re]~| ERROR E0117
+//~^ ERROR E0206
+//~| ERROR E0117
 impl Copy for &'static NotSync {}
-//[old]~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `&NotSync`:
-//[re]~^^  ERROR E0119
+//~^  ERROR E0119
 impl Copy for [MyType] {}
-//[old]~^ ERROR the trait `Copy` may not be implemented for this type
-//[old]~| ERROR only traits defined in the current crate can be implemented for arbitrary types
-//[re]~^^^ ERROR E0206
-//[re]~| ERROR E0117
+//~^ ERROR E0206
+//~| ERROR E0117
 impl Copy for &'static [NotSync] {}
-//[old]~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
-//[old]~| ERROR only traits defined in the current crate can be implemented for arbitrary types
-//[re]~^^^ ERROR E0119
-//[re]~| ERROR E0117
+//~^ ERROR E0119
+//~| ERROR E0117
 fn main() {
 }
diff --git a/src/test/ui/coherence/coherence-impls-copy.old.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr
index 742845b1907..be040b38d6b 100644
--- a/src/test/ui/coherence/coherence-impls-copy.old.stderr
+++ b/src/test/ui/coherence/coherence-impls-copy.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `i32`:
-  --> $DIR/coherence-impls-copy.rs:8:1
+  --> $DIR/coherence-impls-copy.rs:5:1
    |
 LL | impl Copy for i32 {}
    | ^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | impl Copy for i32 {}
            - impl std::marker::Copy for i32;
 
 error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`:
-  --> $DIR/coherence-impls-copy.rs:37:1
+  --> $DIR/coherence-impls-copy.rs:29:1
    |
 LL | impl Copy for &'static NotSync {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL | impl Copy for &'static NotSync {}
              where T: ?Sized;
 
 error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`:
-  --> $DIR/coherence-impls-copy.rs:45:1
+  --> $DIR/coherence-impls-copy.rs:34:1
    |
 LL | impl Copy for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -28,25 +28,25 @@ LL | impl Copy for &'static [NotSync] {}
              where T: ?Sized;
 
 error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:27:15
+  --> $DIR/coherence-impls-copy.rs:22:15
    |
 LL | impl Copy for &'static mut MyType {}
    |               ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
 error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:32:15
+  --> $DIR/coherence-impls-copy.rs:26:15
    |
 LL | impl Copy for (MyType, MyType) {}
    |               ^^^^^^^^^^^^^^^^ type is not a structure or enumeration
 
 error[E0206]: the trait `Copy` may not be implemented for this type
-  --> $DIR/coherence-impls-copy.rs:40:15
+  --> $DIR/coherence-impls-copy.rs:31:15
    |
 LL | impl Copy for [MyType] {}
    |               ^^^^^^^^ type is not a structure or enumeration
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:8:1
+  --> $DIR/coherence-impls-copy.rs:5:1
    |
 LL | impl Copy for i32 {}
    | ^^^^^^^^^^^^^^---
@@ -57,7 +57,7 @@ LL | impl Copy for i32 {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:32:1
+  --> $DIR/coherence-impls-copy.rs:26:1
    |
 LL | impl Copy for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^----------------
@@ -68,7 +68,7 @@ LL | impl Copy for (MyType, MyType) {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:40:1
+  --> $DIR/coherence-impls-copy.rs:31:1
    |
 LL | impl Copy for [MyType] {}
    | ^^^^^^^^^^^^^^--------
@@ -79,7 +79,7 @@ LL | impl Copy for [MyType] {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-copy.rs:45:1
+  --> $DIR/coherence-impls-copy.rs:34:1
    |
 LL | impl Copy for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^------------------
diff --git a/src/test/ui/coherence/coherence-impls-send.re.stderr b/src/test/ui/coherence/coherence-impls-send.re.stderr
deleted file mode 100644
index 7584b01ca89..00000000000
--- a/src/test/ui/coherence/coherence-impls-send.re.stderr
+++ /dev/null
@@ -1,43 +0,0 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-send.rs:20:1
-   |
-LL | unsafe impl Send for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^^^^^^^^----------------
-   | |                    |
-   | |                    this is not defined in the current crate because tuples are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync`
-  --> $DIR/coherence-impls-send.rs:24:1
-   |
-LL | unsafe impl Send for &'static NotSync {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-send.rs:28:1
-   |
-LL | unsafe impl Send for [MyType] {}
-   | ^^^^^^^^^^^^^^^^^^^^^--------
-   | |                    |
-   | |                    this is not defined in the current crate because slices are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-send.rs:32:1
-   |
-LL | unsafe impl Send for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^^^^^^^^------------------
-   | |                    |
-   | |                    this is not defined in the current crate because slices are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0117, E0321.
-For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-impls-send.rs b/src/test/ui/coherence/coherence-impls-send.rs
index ef13e9caa66..b2a9c5be658 100644
--- a/src/test/ui/coherence/coherence-impls-send.rs
+++ b/src/test/ui/coherence/coherence-impls-send.rs
@@ -1,6 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 #![feature(overlapping_marker_traits)]
 
@@ -18,20 +15,16 @@ impl !Sync for NotSync {}
 unsafe impl Send for TestE {}
 unsafe impl Send for MyType {}
 unsafe impl Send for (MyType, MyType) {}
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 unsafe impl Send for &'static NotSync {}
-//[old]~^ ERROR E0321
-//[re]~^^ ERROR E0321
+//~^ ERROR E0321
 
 unsafe impl Send for [MyType] {}
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 unsafe impl Send for &'static [NotSync] {}
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() {
 }
diff --git a/src/test/ui/coherence/coherence-impls-send.old.stderr b/src/test/ui/coherence/coherence-impls-send.stderr
index 7584b01ca89..a5b3c7657bd 100644
--- a/src/test/ui/coherence/coherence-impls-send.old.stderr
+++ b/src/test/ui/coherence/coherence-impls-send.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-send.rs:20:1
+  --> $DIR/coherence-impls-send.rs:17:1
    |
 LL | unsafe impl Send for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^----------------
@@ -10,13 +10,13 @@ LL | unsafe impl Send for (MyType, MyType) {}
    = note: define and implement a trait or new type instead
 
 error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `&'static NotSync`
-  --> $DIR/coherence-impls-send.rs:24:1
+  --> $DIR/coherence-impls-send.rs:20:1
    |
 LL | unsafe impl Send for &'static NotSync {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-send.rs:28:1
+  --> $DIR/coherence-impls-send.rs:23:1
    |
 LL | unsafe impl Send for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^--------
@@ -27,7 +27,7 @@ LL | unsafe impl Send for [MyType] {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-send.rs:32:1
+  --> $DIR/coherence-impls-send.rs:26:1
    |
 LL | unsafe impl Send for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^------------------
diff --git a/src/test/ui/coherence/coherence-impls-sized.re.stderr b/src/test/ui/coherence/coherence-impls-sized.re.stderr
deleted file mode 100644
index ef999bcf461..00000000000
--- a/src/test/ui/coherence/coherence-impls-sized.re.stderr
+++ /dev/null
@@ -1,73 +0,0 @@
-error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:17:1
-   |
-LL | impl Sized for TestE {}
-   | ^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
-
-error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:22:1
-   |
-LL | impl Sized for MyType {}
-   | ^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
-
-error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:27:1
-   |
-LL | impl Sized for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
-
-error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:34:1
-   |
-LL | impl Sized for &'static NotSync {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
-
-error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:39:1
-   |
-LL | impl Sized for [MyType] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
-
-error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:46:1
-   |
-LL | impl Sized for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-sized.rs:27:1
-   |
-LL | impl Sized for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^^----------------
-   | |              |
-   | |              this is not defined in the current crate because tuples are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-sized.rs:39:1
-   |
-LL | impl Sized for [MyType] {}
-   | ^^^^^^^^^^^^^^^--------
-   | |              |
-   | |              this is not defined in the current crate because slices are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-sized.rs:46:1
-   |
-LL | impl Sized for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^^------------------
-   | |              |
-   | |              this is not defined in the current crate because slices are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to 9 previous errors
-
-Some errors have detailed explanations: E0117, E0322.
-For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-impls-sized.rs b/src/test/ui/coherence/coherence-impls-sized.rs
index 84ae2dd291b..19e7349c507 100644
--- a/src/test/ui/coherence/coherence-impls-sized.rs
+++ b/src/test/ui/coherence/coherence-impls-sized.rs
@@ -1,6 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 
 use std::marker::Copy;
@@ -15,40 +12,25 @@ struct NotSync;
 impl !Sync for NotSync {}
 
 impl Sized for TestE {}
-//[old]~^ ERROR E0322
-//[old]~| impl of 'Sized' not allowed
-//[re]~^^^ ERROR E0322
+//~^ ERROR E0322
 
 impl Sized for MyType {}
-//[old]~^ ERROR E0322
-//[old]~| impl of 'Sized' not allowed
-//[re]~^^^ ERROR E0322
+//~^ ERROR E0322
 
 impl Sized for (MyType, MyType) {}
-//[old]~^ ERROR E0322
-//[old]~| impl of 'Sized' not allowed
-//[old]~| ERROR E0117
-//[re]~^^^^ ERROR E0322
-//[re]~| ERROR E0117
+//~^ ERROR E0322
+//~| ERROR E0117
 
 impl Sized for &'static NotSync {}
-//[old]~^ ERROR E0322
-//[old]~| impl of 'Sized' not allowed
-//[re]~^^^ ERROR E0322
+//~^ ERROR E0322
 
 impl Sized for [MyType] {}
-//[old]~^ ERROR E0322
-//[old]~| impl of 'Sized' not allowed
-//[old]~| ERROR E0117
-//[re]~^^^^ ERROR E0322
-//[re]~| ERROR E0117
+//~^ ERROR E0322
+//~| ERROR E0117
 
 impl Sized for &'static [NotSync] {}
-//[old]~^ ERROR E0322
-//[old]~| impl of 'Sized' not allowed
-//[old]~| ERROR E0117
-//[re]~^^^^ ERROR E0322
-//[re]~| ERROR E0117
+//~^ ERROR E0322
+//~| ERROR E0117
 
 fn main() {
 }
diff --git a/src/test/ui/coherence/coherence-impls-sized.old.stderr b/src/test/ui/coherence/coherence-impls-sized.stderr
index ef999bcf461..3b0a9fc60a2 100644
--- a/src/test/ui/coherence/coherence-impls-sized.old.stderr
+++ b/src/test/ui/coherence/coherence-impls-sized.stderr
@@ -1,41 +1,41 @@
 error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:17:1
+  --> $DIR/coherence-impls-sized.rs:14:1
    |
 LL | impl Sized for TestE {}
    | ^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:22:1
+  --> $DIR/coherence-impls-sized.rs:17:1
    |
 LL | impl Sized for MyType {}
    | ^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:27:1
+  --> $DIR/coherence-impls-sized.rs:20:1
    |
 LL | impl Sized for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:34:1
+  --> $DIR/coherence-impls-sized.rs:24:1
    |
 LL | impl Sized for &'static NotSync {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:39:1
+  --> $DIR/coherence-impls-sized.rs:27:1
    |
 LL | impl Sized for [MyType] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
 
 error[E0322]: explicit impls for the `Sized` trait are not permitted
-  --> $DIR/coherence-impls-sized.rs:46:1
+  --> $DIR/coherence-impls-sized.rs:31:1
    |
 LL | impl Sized for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of 'Sized' not allowed
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-sized.rs:27:1
+  --> $DIR/coherence-impls-sized.rs:20:1
    |
 LL | impl Sized for (MyType, MyType) {}
    | ^^^^^^^^^^^^^^^----------------
@@ -46,7 +46,7 @@ LL | impl Sized for (MyType, MyType) {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-sized.rs:39:1
+  --> $DIR/coherence-impls-sized.rs:27:1
    |
 LL | impl Sized for [MyType] {}
    | ^^^^^^^^^^^^^^^--------
@@ -57,7 +57,7 @@ LL | impl Sized for [MyType] {}
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-impls-sized.rs:46:1
+  --> $DIR/coherence-impls-sized.rs:31:1
    |
 LL | impl Sized for &'static [NotSync] {}
    | ^^^^^^^^^^^^^^^------------------
diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.re.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.re.stderr
deleted file mode 100644
index a2fa49acd2c..00000000000
--- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.re.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0391]: cycle detected when processing `Trait`
-  --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:12:1
-   |
-LL | trait Trait<T> { type Assoc; }
-   | ^^^^^^^^^^^^^^
-   |
-   = note: ...which again requires processing `Trait`, completing the cycle
-note: cycle used when coherence checking all impls of trait `Trait`
-  --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:12:1
-   |
-LL | trait Trait<T> { type Assoc; }
-   | ^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs
index 5a6b8fb7316..7f0e5472c3c 100644
--- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs
+++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.rs
@@ -3,15 +3,10 @@
 // which is currently not supported.
 //
 // No we expect to run into a more user-friendly cycle error instead.
-
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(specialization)]
 
 trait Trait<T> { type Assoc; }
-//[old]~^ cycle detected
-//[re]~^^ ERROR E0391
+//~^ ERROR E0391
 
 impl<T> Trait<T> for Vec<T> {
     type Assoc = ();
diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.old.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
index a2fa49acd2c..e5cc298a435 100644
--- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.old.stderr
+++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr
@@ -1,12 +1,12 @@
 error[E0391]: cycle detected when processing `Trait`
-  --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:12:1
+  --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:8:1
    |
 LL | trait Trait<T> { type Assoc; }
    | ^^^^^^^^^^^^^^
    |
    = note: ...which again requires processing `Trait`, completing the cycle
 note: cycle used when coherence checking all impls of trait `Trait`
-  --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:12:1
+  --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:8:1
    |
 LL | trait Trait<T> { type Assoc; }
    | ^^^^^^^^^^^^^^
diff --git a/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs
index 051cc280b2d..43a0a5c4277 100644
--- a/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs
+++ b/src/test/ui/coherence/coherence-iterator-vec-any-elem.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/coherence-iterator-vec.rs b/src/test/ui/coherence/coherence-iterator-vec.rs
index df6e808f7de..386fe40ac3c 100644
--- a/src/test/ui/coherence/coherence-iterator-vec.rs
+++ b/src/test/ui/coherence/coherence-iterator-vec.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.re.stderr b/src/test/ui/coherence/coherence-lone-type-parameter.re.stderr
deleted file mode 100644
index 731752045cd..00000000000
--- a/src/test/ui/coherence/coherence-lone-type-parameter.re.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-lone-type-parameter.rs:9:6
-   |
-LL | impl<T> Remote for T { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.rs b/src/test/ui/coherence/coherence-lone-type-parameter.rs
index 63b38bf1cc1..5368fef76d0 100644
--- a/src/test/ui/coherence/coherence-lone-type-parameter.rs
+++ b/src/test/ui/coherence/coherence-lone-type-parameter.rs
@@ -1,14 +1,10 @@
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::Remote;
 
 impl<T> Remote for T { }
-//[old]~^ ERROR type parameter `T` must be used as the type parameter for some local type
-//[re]~^^ ERROR E0210
+//~^ ERROR E0210
 
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-lone-type-parameter.old.stderr b/src/test/ui/coherence/coherence-lone-type-parameter.stderr
index 731752045cd..3791d96302b 100644
--- a/src/test/ui/coherence/coherence-lone-type-parameter.old.stderr
+++ b/src/test/ui/coherence/coherence-lone-type-parameter.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-lone-type-parameter.rs:9:6
+  --> $DIR/coherence-lone-type-parameter.rs:6:6
    |
 LL | impl<T> Remote for T { }
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/coherence-multidispatch-tuple.rs b/src/test/ui/coherence/coherence-multidispatch-tuple.rs
index 6a816664c48..fa1d4bbb496 100644
--- a/src/test/ui/coherence/coherence-multidispatch-tuple.rs
+++ b/src/test/ui/coherence/coherence-multidispatch-tuple.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(unused_imports)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs
index 98b04489ac4..695a71cbd2d 100644
--- a/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs
+++ b/src/test/ui/coherence/coherence-negative-impls-safe-rpass.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.re.stderr b/src/test/ui/coherence/coherence-negative-impls-safe.re.stderr
deleted file mode 100644
index 7ed47dca497..00000000000
--- a/src/test/ui/coherence/coherence-negative-impls-safe.re.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0198]: negative impls cannot be unsafe
-  --> $DIR/coherence-negative-impls-safe.rs:10:1
-   |
-LL | unsafe impl !Send for TestType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0198`.
diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.rs b/src/test/ui/coherence/coherence-negative-impls-safe.rs
index b6658d5bfa4..45c478ecc03 100644
--- a/src/test/ui/coherence/coherence-negative-impls-safe.rs
+++ b/src/test/ui/coherence/coherence-negative-impls-safe.rs
@@ -1,6 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 
 use std::marker::Send;
@@ -8,7 +5,6 @@ use std::marker::Send;
 struct TestType;
 
 unsafe impl !Send for TestType {}
-//[old]~^ ERROR negative impls cannot be unsafe
-//[re]~^^ ERROR E0198
+//~^ ERROR E0198
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.old.stderr b/src/test/ui/coherence/coherence-negative-impls-safe.stderr
index 7ed47dca497..c47c9d25e36 100644
--- a/src/test/ui/coherence/coherence-negative-impls-safe.old.stderr
+++ b/src/test/ui/coherence/coherence-negative-impls-safe.stderr
@@ -1,5 +1,5 @@
 error[E0198]: negative impls cannot be unsafe
-  --> $DIR/coherence-negative-impls-safe.rs:10:1
+  --> $DIR/coherence-negative-impls-safe.rs:7:1
    |
 LL | unsafe impl !Send for TestType {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.re.stderr b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.re.stderr
deleted file mode 100644
index 81465e71856..00000000000
--- a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.re.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/coherence-no-direct-lifetime-dispatch.rs:10:1
-   |
-LL | impl<T> MyTrait for T {}
-   | --------------------- first implementation here
-LL | impl<T: 'static> MyTrait for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs
index 9717f1ed051..d466dcac1c4 100644
--- a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs
+++ b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.rs
@@ -1,14 +1,9 @@
 // Test that you cannot *directly* dispatch on lifetime requirements
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait MyTrait { fn foo() {} }
 
 impl<T> MyTrait for T {}
 impl<T: 'static> MyTrait for T {}
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.old.stderr b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr
index 81465e71856..a74ffbb3afd 100644
--- a/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.old.stderr
+++ b/src/test/ui/coherence/coherence-no-direct-lifetime-dispatch.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait`:
-  --> $DIR/coherence-no-direct-lifetime-dispatch.rs:10:1
+  --> $DIR/coherence-no-direct-lifetime-dispatch.rs:6:1
    |
 LL | impl<T> MyTrait for T {}
    | --------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-orphan.re.stderr b/src/test/ui/coherence/coherence-orphan.re.stderr
deleted file mode 100644
index a353acf0679..00000000000
--- a/src/test/ui/coherence/coherence-orphan.re.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-orphan.rs:13:1
-   |
-LL | impl TheTrait<usize> for isize { }
-   | ^^^^^---------------^^^^^-----
-   | |    |                   |
-   | |    |                   `isize` is not defined in the current crate
-   | |    `usize` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-orphan.rs:21:1
-   |
-LL | impl !Send for Vec<isize> { }
-   | ^^^^^^^^^^^^^^^----------
-   | |              |
-   | |              `std::vec::Vec` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-orphan.rs b/src/test/ui/coherence/coherence-orphan.rs
index 18f50e46021..a7b48825d7c 100644
--- a/src/test/ui/coherence/coherence-orphan.rs
+++ b/src/test/ui/coherence/coherence-orphan.rs
@@ -1,7 +1,4 @@
 // aux-build:coherence_orphan_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(optin_builtin_traits)]
 
 extern crate coherence_orphan_lib as lib;
@@ -11,15 +8,13 @@ use lib::TheTrait;
 struct TheType;
 
 impl TheTrait<usize> for isize { }
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 impl TheTrait<TheType> for isize { }
 
 impl TheTrait<isize> for TheType { }
 
 impl !Send for Vec<isize> { }
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-orphan.old.stderr b/src/test/ui/coherence/coherence-orphan.stderr
index a353acf0679..fb518f8ecba 100644
--- a/src/test/ui/coherence/coherence-orphan.old.stderr
+++ b/src/test/ui/coherence/coherence-orphan.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-orphan.rs:13:1
+  --> $DIR/coherence-orphan.rs:10:1
    |
 LL | impl TheTrait<usize> for isize { }
    | ^^^^^---------------^^^^^-----
@@ -11,7 +11,7 @@ LL | impl TheTrait<usize> for isize { }
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-orphan.rs:21:1
+  --> $DIR/coherence-orphan.rs:17:1
    |
 LL | impl !Send for Vec<isize> { }
    | ^^^^^^^^^^^^^^^----------
diff --git a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.re.stderr b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.re.stderr
deleted file mode 100644
index c7f85b0b590..00000000000
--- a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `From<(_,)>` for type `(_,)`:
-  --> $DIR/coherence-overlap-all-t-and-tuple.rs:20:1
-   |
-LL | impl <T> From<T> for T {
-   | ---------------------- first implementation here
-...
-LL | impl <T11, U11> From<(U11,)> for (T11,) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_,)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs
index bf3ce89f70b..574a16a1911 100644
--- a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs
+++ b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.rs
@@ -6,10 +6,6 @@
 //
 // Seems pretty basic, but then there was issue #24241. :)
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait From<U> {
     fn foo() {}
 }
@@ -18,8 +14,7 @@ impl <T> From<T> for T {
 }
 
 impl <T11, U11> From<(U11,)> for (T11,) {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 }
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.old.stderr b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.stderr
index c7f85b0b590..5e8bfbcc3ca 100644
--- a/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-all-t-and-tuple.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `From<(_,)>` for type `(_,)`:
-  --> $DIR/coherence-overlap-all-t-and-tuple.rs:20:1
+  --> $DIR/coherence-overlap-all-t-and-tuple.rs:16:1
    |
 LL | impl <T> From<T> for T {
    | ---------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-overlap-downstream-inherent.re.stderr b/src/test/ui/coherence/coherence-overlap-downstream-inherent.re.stderr
deleted file mode 100644
index dcfc017f1b0..00000000000
--- a/src/test/ui/coherence/coherence-overlap-downstream-inherent.re.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:11:26
-   |
-LL | impl<T:Sugar> Sweet<T> { fn dummy(&self) { } }
-   |                          ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-...
-LL | impl<T:Fruit> Sweet<T> { fn dummy(&self) { } }
-   |                          ------------------- other definition for `dummy`
-
-error[E0592]: duplicate definitions with name `f`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:18:38
-   |
-LL | impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
-   |                                      ^^^^^^^^^^^^^^ duplicate definitions for `f`
-...
-LL | impl<X> A<i32, X> { fn f(&self) {} }
-   |                     -------------- other definition for `f`
-   |
-   = note: downstream crates may implement trait `Bar<_>` for type `i32`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0592`.
diff --git a/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs b/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs
index ad54d247f91..5dea33e330b 100644
--- a/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs
+++ b/src/test/ui/coherence/coherence-overlap-downstream-inherent.rs
@@ -1,23 +1,17 @@
 // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even
 // though no impls are found.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 struct Sweet<X>(X);
 pub trait Sugar {}
 pub trait Fruit {}
 impl<T:Sugar> Sweet<T> { fn dummy(&self) { } }
-//[old]~^ ERROR E0592
-//[re]~^^ ERROR E0592
+//~^ ERROR E0592
 impl<T:Fruit> Sweet<T> { fn dummy(&self) { } }
 
 trait Bar<X> {}
 struct A<T, X>(T, X);
 impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
-//[old]~^ ERROR E0592
-//[re]~^^ ERROR E0592
+//~^ ERROR E0592
 impl<X> A<i32, X> { fn f(&self) {} }
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-overlap-downstream-inherent.old.stderr b/src/test/ui/coherence/coherence-overlap-downstream-inherent.stderr
index dcfc017f1b0..4cb7390453c 100644
--- a/src/test/ui/coherence/coherence-overlap-downstream-inherent.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-downstream-inherent.stderr
@@ -1,18 +1,18 @@
 error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:11:26
+  --> $DIR/coherence-overlap-downstream-inherent.rs:7:26
    |
 LL | impl<T:Sugar> Sweet<T> { fn dummy(&self) { } }
    |                          ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-...
+LL |
 LL | impl<T:Fruit> Sweet<T> { fn dummy(&self) { } }
    |                          ------------------- other definition for `dummy`
 
 error[E0592]: duplicate definitions with name `f`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:18:38
+  --> $DIR/coherence-overlap-downstream-inherent.rs:13:38
    |
 LL | impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
    |                                      ^^^^^^^^^^^^^^ duplicate definitions for `f`
-...
+LL |
 LL | impl<X> A<i32, X> { fn f(&self) {} }
    |                     -------------- other definition for `f`
    |
diff --git a/src/test/ui/coherence/coherence-overlap-downstream.re.stderr b/src/test/ui/coherence/coherence-overlap-downstream.re.stderr
deleted file mode 100644
index b4847c03d41..00000000000
--- a/src/test/ui/coherence/coherence-overlap-downstream.re.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0119]: conflicting implementations of trait `Sweet`:
-  --> $DIR/coherence-overlap-downstream.rs:12:1
-   |
-LL | impl<T:Sugar> Sweet for T { }
-   | ------------------------- first implementation here
-LL | impl<T:Fruit> Sweet for T { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32`:
-  --> $DIR/coherence-overlap-downstream.rs:19:1
-   |
-LL | impl<X, T> Foo<X> for T where T: Bar<X> {}
-   | --------------------------------------- first implementation here
-LL | impl<X> Foo<X> for i32 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
-   |
-   = note: downstream crates may implement trait `Bar<_>` for type `i32`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-overlap-downstream.rs b/src/test/ui/coherence/coherence-overlap-downstream.rs
index c6ced7b80fd..738ec0e3d45 100644
--- a/src/test/ui/coherence/coherence-overlap-downstream.rs
+++ b/src/test/ui/coherence/coherence-overlap-downstream.rs
@@ -1,23 +1,17 @@
 // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even
 // though no impls are found.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 pub trait Sugar {}
 pub trait Fruit {}
 pub trait Sweet {}
 impl<T:Sugar> Sweet for T { }
 impl<T:Fruit> Sweet for T { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 pub trait Foo<X> {}
 pub trait Bar<X> {}
 impl<X, T> Foo<X> for T where T: Bar<X> {}
 impl<X> Foo<X> for i32 {}
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-overlap-downstream.old.stderr b/src/test/ui/coherence/coherence-overlap-downstream.stderr
index b4847c03d41..6fb398562d6 100644
--- a/src/test/ui/coherence/coherence-overlap-downstream.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-downstream.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Sweet`:
-  --> $DIR/coherence-overlap-downstream.rs:12:1
+  --> $DIR/coherence-overlap-downstream.rs:8:1
    |
 LL | impl<T:Sugar> Sweet for T { }
    | ------------------------- first implementation here
@@ -7,7 +7,7 @@ LL | impl<T:Fruit> Sweet for T { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32`:
-  --> $DIR/coherence-overlap-downstream.rs:19:1
+  --> $DIR/coherence-overlap-downstream.rs:14:1
    |
 LL | impl<X, T> Foo<X> for T where T: Bar<X> {}
    | --------------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.re.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.re.stderr
deleted file mode 100644
index 6fd93077540..00000000000
--- a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-issue-23516-inherent.rs:13:25
-   |
-LL | impl<T:Sugar> Cake<T> { fn dummy(&self) { } }
-   |                         ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-...
-LL | impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } }
-   |                              ------------------- other definition for `dummy`
-   |
-   = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0592`.
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs
index 969366e29cc..a272e620fca 100644
--- a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs
+++ b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.rs
@@ -2,17 +2,12 @@
 // though we see no impl of `Sugar` for `Box`. Therefore, an overlap
 // error is reported for the following pair of impls (#23516).
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 pub trait Sugar {}
 
 struct Cake<X>(X);
 
 impl<T:Sugar> Cake<T> { fn dummy(&self) { } }
-//[old]~^ ERROR E0592
-//[re]~^^ ERROR E0592
+//~^ ERROR E0592
 impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } }
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.stderr
index 6fd93077540..e63f8a997af 100644
--- a/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-issue-23516-inherent.stderr
@@ -1,9 +1,9 @@
 error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-issue-23516-inherent.rs:13:25
+  --> $DIR/coherence-overlap-issue-23516-inherent.rs:9:25
    |
 LL | impl<T:Sugar> Cake<T> { fn dummy(&self) { } }
    |                         ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-...
+LL |
 LL | impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } }
    |                              ------------------- other definition for `dummy`
    |
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.re.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516.re.stderr
deleted file mode 100644
index d17d67adf0e..00000000000
--- a/src/test/ui/coherence/coherence-overlap-issue-23516.re.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `Sweet` for type `std::boxed::Box<_>`:
-  --> $DIR/coherence-overlap-issue-23516.rs:12:1
-   |
-LL | impl<T:Sugar> Sweet for T { }
-   | ------------------------- first implementation here
-LL | impl<U:Sugar> Sweet for Box<U> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::boxed::Box<_>`
-   |
-   = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.rs b/src/test/ui/coherence/coherence-overlap-issue-23516.rs
index e3c15e149f8..63e42e8f412 100644
--- a/src/test/ui/coherence/coherence-overlap-issue-23516.rs
+++ b/src/test/ui/coherence/coherence-overlap-issue-23516.rs
@@ -2,15 +2,10 @@
 // though we see no impl of `Sugar` for `Box`. Therefore, an overlap
 // error is reported for the following pair of impls (#23516).
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 pub trait Sugar { fn dummy(&self) { } }
 pub trait Sweet { fn dummy(&self) { } }
 impl<T:Sugar> Sweet for T { }
 impl<U:Sugar> Sweet for Box<U> { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-overlap-issue-23516.old.stderr b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
index d17d67adf0e..fe4c5cf3490 100644
--- a/src/test/ui/coherence/coherence-overlap-issue-23516.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-issue-23516.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Sweet` for type `std::boxed::Box<_>`:
-  --> $DIR/coherence-overlap-issue-23516.rs:12:1
+  --> $DIR/coherence-overlap-issue-23516.rs:8:1
    |
 LL | impl<T:Sugar> Sweet for T { }
    | ------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-overlap-messages.re.stderr b/src/test/ui/coherence/coherence-overlap-messages.re.stderr
deleted file mode 100644
index 429e67573b5..00000000000
--- a/src/test/ui/coherence/coherence-overlap-messages.re.stderr
+++ /dev/null
@@ -1,44 +0,0 @@
-error[E0119]: conflicting implementations of trait `Foo`:
-  --> $DIR/coherence-overlap-messages.rs:8:1
-   |
-LL | impl<T> Foo for T {}
-   | ----------------- first implementation here
-LL | impl<U> Foo for U {}
-   | ^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)`:
-  --> $DIR/coherence-overlap-messages.rs:16:1
-   |
-LL | impl<T> Bar for (T, u8) {}
-   | ----------------------- first implementation here
-LL | impl<T> Bar for (u8, T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(u8, u8)`
-
-error[E0119]: conflicting implementations of trait `Baz<u8>` for type `u8`:
-  --> $DIR/coherence-overlap-messages.rs:23:1
-   |
-LL | impl<T> Baz<u8> for T {}
-   | --------------------- first implementation here
-LL | impl<T> Baz<T> for u8 {}
-   | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
-
-error[E0119]: conflicting implementations of trait `Quux<_, _>`:
-  --> $DIR/coherence-overlap-messages.rs:30:1
-   |
-LL | impl<T, U, V> Quux<U, V> for T {}
-   | ------------------------------ first implementation here
-LL | impl<T, U> Quux<U, U> for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error[E0119]: conflicting implementations of trait `Quux<_, _>`:
-  --> $DIR/coherence-overlap-messages.rs:33:1
-   |
-LL | impl<T, U, V> Quux<U, V> for T {}
-   | ------------------------------ first implementation here
-...
-LL | impl<T, V> Quux<T, V> for T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-overlap-messages.rs b/src/test/ui/coherence/coherence-overlap-messages.rs
index e0e2e672e98..1258a237114 100644
--- a/src/test/ui/coherence/coherence-overlap-messages.rs
+++ b/src/test/ui/coherence/coherence-overlap-messages.rs
@@ -1,37 +1,28 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait Foo { fn foo() {} }
 
 impl<T> Foo for T {}
 impl<U> Foo for U {}
-//[old]~^ ERROR conflicting implementations of trait `Foo`:
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 
 trait Bar { fn bar() {} }
 
 impl<T> Bar for (T, u8) {}
 impl<T> Bar for (u8, T) {}
-//[old]~^ ERROR conflicting implementations of trait `Bar` for type `(u8, u8)`:
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 trait Baz<T> { fn baz() {} }
 
 impl<T> Baz<u8> for T {}
 impl<T> Baz<T> for u8 {}
-//[old]~^ ERROR conflicting implementations of trait `Baz<u8>` for type `u8`:
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 trait Quux<U, V> { fn quux() {} }
 
 impl<T, U, V> Quux<U, V> for T {}
 impl<T, U> Quux<U, U> for T {}
-//[old]~^ ERROR conflicting implementations of trait `Quux<_, _>`:
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 impl<T, V> Quux<T, V> for T {}
-//[old]~^ ERROR conflicting implementations of trait `Quux<_, _>`:
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-overlap-messages.old.stderr b/src/test/ui/coherence/coherence-overlap-messages.stderr
index 429e67573b5..28147f52fa6 100644
--- a/src/test/ui/coherence/coherence-overlap-messages.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-messages.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo`:
-  --> $DIR/coherence-overlap-messages.rs:8:1
+  --> $DIR/coherence-overlap-messages.rs:4:1
    |
 LL | impl<T> Foo for T {}
    | ----------------- first implementation here
@@ -7,7 +7,7 @@ LL | impl<U> Foo for U {}
    | ^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0119]: conflicting implementations of trait `Bar` for type `(u8, u8)`:
-  --> $DIR/coherence-overlap-messages.rs:16:1
+  --> $DIR/coherence-overlap-messages.rs:11:1
    |
 LL | impl<T> Bar for (T, u8) {}
    | ----------------------- first implementation here
@@ -15,7 +15,7 @@ LL | impl<T> Bar for (u8, T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(u8, u8)`
 
 error[E0119]: conflicting implementations of trait `Baz<u8>` for type `u8`:
-  --> $DIR/coherence-overlap-messages.rs:23:1
+  --> $DIR/coherence-overlap-messages.rs:17:1
    |
 LL | impl<T> Baz<u8> for T {}
    | --------------------- first implementation here
@@ -23,7 +23,7 @@ LL | impl<T> Baz<T> for u8 {}
    | ^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
 
 error[E0119]: conflicting implementations of trait `Quux<_, _>`:
-  --> $DIR/coherence-overlap-messages.rs:30:1
+  --> $DIR/coherence-overlap-messages.rs:23:1
    |
 LL | impl<T, U, V> Quux<U, V> for T {}
    | ------------------------------ first implementation here
@@ -31,7 +31,7 @@ LL | impl<T, U> Quux<U, U> for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0119]: conflicting implementations of trait `Quux<_, _>`:
-  --> $DIR/coherence-overlap-messages.rs:33:1
+  --> $DIR/coherence-overlap-messages.rs:25:1
    |
 LL | impl<T, U, V> Quux<U, V> for T {}
    | ------------------------------ first implementation here
diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr b/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr
deleted file mode 100644
index 3a3e1a4afc3..00000000000
--- a/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-upstream-inherent.rs:15:32
-   |
-LL | impl<T> A<T> where T: Remote { fn dummy(&self) { } }
-   |                                ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-...
-LL | impl A<i16> { fn dummy(&self) { } }
-   |               ------------------- other definition for `dummy`
-   |
-   = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0592`.
diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs b/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs
index 92b619af076..082d753debb 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs
+++ b/src/test/ui/coherence/coherence-overlap-upstream-inherent.rs
@@ -2,9 +2,6 @@
 // though the upstream crate doesn't implement it for now.
 
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 
 extern crate coherence_lib;
@@ -13,8 +10,7 @@ use coherence_lib::Remote;
 
 struct A<X>(X);
 impl<T> A<T> where T: Remote { fn dummy(&self) { } }
-//[old]~^ ERROR E0592
-//[re]~^^ ERROR E0592
+//~^ ERROR E0592
 impl A<i16> { fn dummy(&self) { } }
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr b/src/test/ui/coherence/coherence-overlap-upstream-inherent.stderr
index 3a3e1a4afc3..51316f24975 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream-inherent.stderr
@@ -1,9 +1,9 @@
 error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-upstream-inherent.rs:15:32
+  --> $DIR/coherence-overlap-upstream-inherent.rs:12:32
    |
 LL | impl<T> A<T> where T: Remote { fn dummy(&self) { } }
    |                                ^^^^^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-...
+LL |
 LL | impl A<i16> { fn dummy(&self) { } }
    |               ------------------- other definition for `dummy`
    |
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.re.stderr b/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
deleted file mode 100644
index bd6f59f346b..00000000000
--- a/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `Foo` for type `i16`:
-  --> $DIR/coherence-overlap-upstream.rs:16:1
-   |
-LL | impl<T> Foo for T where T: Remote {}
-   | --------------------------------- first implementation here
-LL | impl Foo for i16 {}
-   | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
-   |
-   = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.rs b/src/test/ui/coherence/coherence-overlap-upstream.rs
index 62f675003f9..8f1e6558b15 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream.rs
+++ b/src/test/ui/coherence/coherence-overlap-upstream.rs
@@ -2,9 +2,6 @@
 // though the upstream crate doesn't implement it for now.
 
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 
 extern crate coherence_lib;
@@ -14,7 +11,6 @@ use coherence_lib::Remote;
 trait Foo {}
 impl<T> Foo for T where T: Remote {}
 impl Foo for i16 {}
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.old.stderr b/src/test/ui/coherence/coherence-overlap-upstream.stderr
index bd6f59f346b..8d3de9a243e 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo` for type `i16`:
-  --> $DIR/coherence-overlap-upstream.rs:16:1
+  --> $DIR/coherence-overlap-upstream.rs:13:1
    |
 LL | impl<T> Foo for T where T: Remote {}
    | --------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.old.stderr b/src/test/ui/coherence/coherence-overlapping-pairs.old.stderr
deleted file mode 100644
index 7c62716f705..00000000000
--- a/src/test/ui/coherence/coherence-overlapping-pairs.old.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-overlapping-pairs.rs:11:6
-   |
-LL | impl<T> Remote for lib::Pair<T,Foo> { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.rs b/src/test/ui/coherence/coherence-overlapping-pairs.rs
index de31a083940..d5d18217bd6 100644
--- a/src/test/ui/coherence/coherence-overlapping-pairs.rs
+++ b/src/test/ui/coherence/coherence-overlapping-pairs.rs
@@ -1,7 +1,4 @@
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::Remote;
@@ -9,7 +6,6 @@ use lib::Remote;
 struct Foo;
 
 impl<T> Remote for lib::Pair<T,Foo> { }
-//[old]~^ ERROR type parameter `T` must be used as the type parameter for some local type
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.re.stderr b/src/test/ui/coherence/coherence-overlapping-pairs.stderr
index 2277b33fceb..69a4627a7b8 100644
--- a/src/test/ui/coherence/coherence-overlapping-pairs.re.stderr
+++ b/src/test/ui/coherence/coherence-overlapping-pairs.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-overlapping-pairs.rs:11:1
+  --> $DIR/coherence-overlapping-pairs.rs:8:1
    |
 LL | impl<T> Remote for lib::Pair<T,Foo> { }
    | ^^^^^^^^^^^^^^^^^^^----------------
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.old.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.old.stderr
deleted file mode 100644
index 9f55df4c974..00000000000
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.old.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-pair-covered-uncovered-1.rs:15:6
-   |
-LL | impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs
index 91794b7999b..15868ca8686 100644
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs
+++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.rs
@@ -2,9 +2,6 @@
 // list of type parameters, not the self type.
 
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 
 extern crate coherence_lib as lib;
@@ -13,7 +10,6 @@ use lib::{Remote1, Pair};
 pub struct Local<T>(T);
 
 impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { }
-//[old]~^ ERROR type parameter `T` must be used as the type parameter for some local type
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr
index f6e755b6662..f6b9869e177 100644
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.re.stderr
+++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-pair-covered-uncovered-1.rs:15:1
+  --> $DIR/coherence-pair-covered-uncovered-1.rs:12:1
    |
 LL | impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { }
    | ^^^^^^^^^^^--------------------------^^^^^---
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.old.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered.old.stderr
deleted file mode 100644
index 4084061eb4a..00000000000
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered.old.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-pair-covered-uncovered.rs:11:6
-   |
-LL | impl<T,U> Remote for Pair<T,Local<U>> { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.rs b/src/test/ui/coherence/coherence-pair-covered-uncovered.rs
index 49a91412bec..da970572fde 100644
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered.rs
+++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.rs
@@ -1,7 +1,4 @@
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::{Remote, Pair};
@@ -9,7 +6,6 @@ use lib::{Remote, Pair};
 struct Local<T>(T);
 
 impl<T,U> Remote for Pair<T,Local<U>> { }
-//[old]~^ ERROR type parameter `T` must be used as the type parameter for some local type
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr
index 9fa860cb584..d1a4993e0f2 100644
--- a/src/test/ui/coherence/coherence-pair-covered-uncovered.re.stderr
+++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-pair-covered-uncovered.rs:11:1
+  --> $DIR/coherence-pair-covered-uncovered.rs:8:1
    |
 LL | impl<T,U> Remote for Pair<T,Local<U>> { }
    | ^^^^^^^^^^^^^^^^^^^^^----------------
diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
deleted file mode 100644
index 728eae5e547..00000000000
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
-  --> $DIR/coherence-projection-conflict-orphan.rs:19:1
-   |
-LL | impl Foo<i32> for i32 { }
-   | --------------------- first implementation here
-LL | 
-LL | impl<A:Iterator> Foo<A::Item> for A { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
-   |
-   = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.rs b/src/test/ui/coherence/coherence-projection-conflict-orphan.rs
index 4f7fc71536b..637dd250638 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.rs
+++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.rs
@@ -1,6 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![feature(rustc_attrs)]
 
 // Here we expect a coherence conflict because, even though `i32` does
@@ -17,7 +14,6 @@ pub trait Bar {
 impl Foo<i32> for i32 { }
 
 impl<A:Iterator> Foo<A::Item> for A { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr
index 728eae5e547..06a840255bd 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
-  --> $DIR/coherence-projection-conflict-orphan.rs:19:1
+  --> $DIR/coherence-projection-conflict-orphan.rs:16:1
    |
 LL | impl Foo<i32> for i32 { }
    | --------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.re.stderr b/src/test/ui/coherence/coherence-projection-conflict-ty-param.re.stderr
deleted file mode 100644
index b53a4c973ed..00000000000
--- a/src/test/ui/coherence/coherence-projection-conflict-ty-param.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `Foo<_>` for type `std::option::Option<_>`:
-  --> $DIR/coherence-projection-conflict-ty-param.rs:14:1
-   |
-LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {}
-   | ---------------------------------------- first implementation here
-LL | 
-LL | impl<T, U> Foo<T> for Option<U> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::option::Option<_>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs b/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs
index 819947fa547..3e4141fa8cb 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs
+++ b/src/test/ui/coherence/coherence-projection-conflict-ty-param.rs
@@ -1,10 +1,6 @@
 // Coherence error results because we do not know whether `T: Foo<P>` or not
 // for the second impl.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::marker::PhantomData;
 
 pub trait Foo<P> { fn foo() {} }
@@ -12,7 +8,6 @@ pub trait Foo<P> { fn foo() {} }
 impl <P, T: Foo<P>> Foo<P> for Option<T> {}
 
 impl<T, U> Foo<T> for Option<U> { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-projection-conflict-ty-param.old.stderr b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
index b53a4c973ed..c5c9b0ac33c 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-ty-param.old.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-ty-param.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo<_>` for type `std::option::Option<_>`:
-  --> $DIR/coherence-projection-conflict-ty-param.rs:14:1
+  --> $DIR/coherence-projection-conflict-ty-param.rs:10:1
    |
 LL | impl <P, T: Foo<P>> Foo<P> for Option<T> {}
    | ---------------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-projection-conflict.re.stderr b/src/test/ui/coherence/coherence-projection-conflict.re.stderr
deleted file mode 100644
index c2e5fc86175..00000000000
--- a/src/test/ui/coherence/coherence-projection-conflict.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
-  --> $DIR/coherence-projection-conflict.rs:15:1
-   |
-LL | impl Foo<i32> for i32 { }
-   | --------------------- first implementation here
-LL | 
-LL | impl<A:Bar> Foo<A::Output> for A { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-projection-conflict.rs b/src/test/ui/coherence/coherence-projection-conflict.rs
index 4086aeef8c0..daab2a2f8b4 100644
--- a/src/test/ui/coherence/coherence-projection-conflict.rs
+++ b/src/test/ui/coherence/coherence-projection-conflict.rs
@@ -1,7 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::marker::PhantomData;
 
 pub trait Foo<P> { fn foo() {} }
@@ -13,8 +9,7 @@ pub trait Bar {
 impl Foo<i32> for i32 { }
 
 impl<A:Bar> Foo<A::Output> for A { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 impl Bar for i32 {
     type Output = i32;
diff --git a/src/test/ui/coherence/coherence-projection-conflict.old.stderr b/src/test/ui/coherence/coherence-projection-conflict.stderr
index c2e5fc86175..aed6910b529 100644
--- a/src/test/ui/coherence/coherence-projection-conflict.old.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
-  --> $DIR/coherence-projection-conflict.rs:15:1
+  --> $DIR/coherence-projection-conflict.rs:11:1
    |
 LL | impl Foo<i32> for i32 { }
    | --------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-projection-ok-orphan.rs b/src/test/ui/coherence/coherence-projection-ok-orphan.rs
index b34c31dcddb..42b4b1912e2 100644
--- a/src/test/ui/coherence/coherence-projection-ok-orphan.rs
+++ b/src/test/ui/coherence/coherence-projection-ok-orphan.rs
@@ -2,9 +2,6 @@
 // does not hold and (due to the orphan rules), we can rely on that.
 
 // check-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 pub trait Foo<P> {}
 
diff --git a/src/test/ui/coherence/coherence-projection-ok.rs b/src/test/ui/coherence/coherence-projection-ok.rs
index f4f5ca64de7..44fc02a5c20 100644
--- a/src/test/ui/coherence/coherence-projection-ok.rs
+++ b/src/test/ui/coherence/coherence-projection-ok.rs
@@ -1,7 +1,4 @@
 // check-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 pub trait Foo<P> {}
 
diff --git a/src/test/ui/coherence/coherence-rfc447-constrained.rs b/src/test/ui/coherence/coherence-rfc447-constrained.rs
index 4da54d386fd..9d1d8688325 100644
--- a/src/test/ui/coherence/coherence-rfc447-constrained.rs
+++ b/src/test/ui/coherence/coherence-rfc447-constrained.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 // check that trait matching can handle impls whose types are only
 // constrained by a projection.
 
diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs
index a0ff580671a..a742bf2884e 100644
--- a/src/test/ui/coherence/coherence-subtyping.rs
+++ b/src/test/ui/coherence/coherence-subtyping.rs
@@ -7,8 +7,6 @@
 // revisions: old re
 // build-pass (FIXME(62277): could be check-pass?)
 
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 trait TheTrait {
     fn foo(&self) { }
 }
diff --git a/src/test/ui/coherence/coherence-tuple-conflict.re.stderr b/src/test/ui/coherence/coherence-tuple-conflict.re.stderr
deleted file mode 100644
index e832bdebbdd..00000000000
--- a/src/test/ui/coherence/coherence-tuple-conflict.re.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `(_, _)`:
-  --> $DIR/coherence-tuple-conflict.rs:19:1
-   |
-LL | impl<T> MyTrait for (T,T) {
-   | ------------------------- first implementation here
-...
-LL | impl<A,B> MyTrait for (A,B) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(_, _)`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence-tuple-conflict.rs b/src/test/ui/coherence/coherence-tuple-conflict.rs
index 130867b2242..8cc82972668 100644
--- a/src/test/ui/coherence/coherence-tuple-conflict.rs
+++ b/src/test/ui/coherence/coherence-tuple-conflict.rs
@@ -1,7 +1,3 @@
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 use std::fmt::Debug;
 use std::default::Default;
 
@@ -17,8 +13,7 @@ impl<T> MyTrait for (T,T) {
 }
 
 impl<A,B> MyTrait for (A,B) {
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
     fn get(&self) -> usize { self.dummy }
 }
 
diff --git a/src/test/ui/coherence/coherence-tuple-conflict.old.stderr b/src/test/ui/coherence/coherence-tuple-conflict.stderr
index e832bdebbdd..f6c2bc32aa8 100644
--- a/src/test/ui/coherence/coherence-tuple-conflict.old.stderr
+++ b/src/test/ui/coherence/coherence-tuple-conflict.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `(_, _)`:
-  --> $DIR/coherence-tuple-conflict.rs:19:1
+  --> $DIR/coherence-tuple-conflict.rs:15:1
    |
 LL | impl<T> MyTrait for (T,T) {
    | ------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence-vec-local-2.old.stderr b/src/test/ui/coherence/coherence-vec-local-2.old.stderr
deleted file mode 100644
index fbcf8fb762a..00000000000
--- a/src/test/ui/coherence/coherence-vec-local-2.old.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/coherence-vec-local-2.rs:14:6
-   |
-LL | impl<T> Remote for Vec<Local<T>> { }
-   |      ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/coherence/coherence-vec-local-2.rs b/src/test/ui/coherence/coherence-vec-local-2.rs
index 423543964c2..47df06bac6c 100644
--- a/src/test/ui/coherence/coherence-vec-local-2.rs
+++ b/src/test/ui/coherence/coherence-vec-local-2.rs
@@ -2,9 +2,6 @@
 // *non-fundamental* remote type like `Vec` is not considered local.
 
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::Remote;
@@ -12,7 +9,6 @@ use lib::Remote;
 struct Local<T>(T);
 
 impl<T> Remote for Vec<Local<T>> { }
-//[old]~^ ERROR E0210
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-vec-local-2.re.stderr b/src/test/ui/coherence/coherence-vec-local-2.stderr
index 48a2848c55f..198314d5ce5 100644
--- a/src/test/ui/coherence/coherence-vec-local-2.re.stderr
+++ b/src/test/ui/coherence/coherence-vec-local-2.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-vec-local-2.rs:14:1
+  --> $DIR/coherence-vec-local-2.rs:11:1
    |
 LL | impl<T> Remote for Vec<Local<T>> { }
    | ^^^^^^^^^^^^^^^^^^^-------------
diff --git a/src/test/ui/coherence/coherence-vec-local.old.stderr b/src/test/ui/coherence/coherence-vec-local.old.stderr
deleted file mode 100644
index 4b199dd9142..00000000000
--- a/src/test/ui/coherence/coherence-vec-local.old.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-vec-local.rs:14:1
-   |
-LL | impl Remote for Vec<Local> { }
-   | ^^^^^^^^^^^^^^^^----------
-   | |               |
-   | |               `std::vec::Vec` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence-vec-local.rs b/src/test/ui/coherence/coherence-vec-local.rs
index 351ddd2aa67..130cc39d0af 100644
--- a/src/test/ui/coherence/coherence-vec-local.rs
+++ b/src/test/ui/coherence/coherence-vec-local.rs
@@ -2,9 +2,6 @@
 // *non-fundamental* remote type like `Vec` is not considered local.
 
 // aux-build:coherence_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_lib as lib;
 use lib::Remote;
@@ -12,7 +9,6 @@ use lib::Remote;
 struct Local;
 
 impl Remote for Vec<Local> { }
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence-vec-local.re.stderr b/src/test/ui/coherence/coherence-vec-local.stderr
index 4b199dd9142..dc5a0a68959 100644
--- a/src/test/ui/coherence/coherence-vec-local.re.stderr
+++ b/src/test/ui/coherence/coherence-vec-local.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence-vec-local.rs:14:1
+  --> $DIR/coherence-vec-local.rs:11:1
    |
 LL | impl Remote for Vec<Local> { }
    | ^^^^^^^^^^^^^^^^----------
diff --git a/src/test/ui/coherence/coherence-where-clause.rs b/src/test/ui/coherence/coherence-where-clause.rs
index 28397420385..5c40def86bb 100644
--- a/src/test/ui/coherence/coherence-where-clause.rs
+++ b/src/test/ui/coherence/coherence-where-clause.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 use std::fmt::Debug;
 use std::default::Default;
diff --git a/src/test/ui/coherence/coherence_copy_like.rs b/src/test/ui/coherence/coherence_copy_like.rs
index 653f76264c1..92af341ccb5 100644
--- a/src/test/ui/coherence/coherence_copy_like.rs
+++ b/src/test/ui/coherence/coherence_copy_like.rs
@@ -1,7 +1,4 @@
 // run-pass
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 // Test that we are able to introduce a negative constraint that
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs
index 22517f9da2e..edee6cd7b6c 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct.rs
@@ -4,9 +4,6 @@
 // aux-build:coherence_copy_like_lib.rs
 // build-pass (FIXME(62277): could be check-pass?)
 // skip-codgen
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 
 extern crate coherence_copy_like_lib as lib;
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs
index 0d677800f79..599c804d213 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_ref.rs
@@ -3,9 +3,6 @@
 
 // check-pass
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_copy_like_lib as lib;
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
deleted file mode 100644
index 4d9f55c1215..00000000000
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyFundamentalStruct<(MyType,)>`:
-  --> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:19:1
-   |
-LL | impl<T: lib::MyCopy> MyTrait for T { }
-   | ---------------------------------- first implementation here
-...
-LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
-   |
-   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs
index 2a61042c6a0..7d851b52884 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.rs
@@ -2,9 +2,6 @@
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
 
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 
 extern crate coherence_copy_like_lib as lib;
@@ -17,8 +14,7 @@ impl<T: lib::MyCopy> MyTrait for T { }
 
 // Tuples are not fundamental.
 impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
index 4d9f55c1215..cf6c6fb8c7a 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyFundamentalStruct<(MyType,)>`:
-  --> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:19:1
+  --> $DIR/coherence_copy_like_err_fundamental_struct_tuple.rs:16:1
    |
 LL | impl<T: lib::MyCopy> MyTrait for T { }
    | ---------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
deleted file mode 100644
index f0bcf659bb6..00000000000
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyStruct<MyType>`:
-  --> $DIR/coherence_copy_like_err_struct.rs:22:1
-   |
-LL | impl<T: lib::MyCopy> MyTrait for T { }
-   | ---------------------------------- first implementation here
-...
-LL | impl MyTrait for lib::MyStruct<MyType> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
-   |
-   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.rs b/src/test/ui/coherence/coherence_copy_like_err_struct.rs
index 38fc2e662d7..fe39370c901 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.rs
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.rs
@@ -1,7 +1,4 @@
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 // Test that we are able to introduce a negative constraint that
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
@@ -20,7 +17,6 @@ impl<T: lib::MyCopy> MyTrait for T { }
 //
 // which we cannot approve.
 impl MyTrait for lib::MyStruct<MyType> { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
index f0bcf659bb6..cf79e851bf4 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `lib::MyStruct<MyType>`:
-  --> $DIR/coherence_copy_like_err_struct.rs:22:1
+  --> $DIR/coherence_copy_like_err_struct.rs:19:1
    |
 LL | impl<T: lib::MyCopy> MyTrait for T { }
    | ---------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
deleted file mode 100644
index a40153af2cf..00000000000
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait` for type `(MyType,)`:
-  --> $DIR/coherence_copy_like_err_tuple.rs:21:1
-   |
-LL | impl<T: lib::MyCopy> MyTrait for T { }
-   | ---------------------------------- first implementation here
-...
-LL | impl MyTrait for (MyType,) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
-   |
-   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.rs b/src/test/ui/coherence/coherence_copy_like_err_tuple.rs
index 7234bed1ba0..f63e205c9f8 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.rs
+++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.rs
@@ -2,9 +2,6 @@
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
 
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_copy_like_lib as lib;
 
@@ -19,7 +16,6 @@ impl<T: lib::MyCopy> MyTrait for T { }
 //
 // which we cannot approve.
 impl MyTrait for (MyType,) { }
-//[old]~^ ERROR E0119
-//[re]~^^ ERROR E0119
+//~^ ERROR E0119
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.stderr
index a40153af2cf..52f66427dfa 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait` for type `(MyType,)`:
-  --> $DIR/coherence_copy_like_err_tuple.rs:21:1
+  --> $DIR/coherence_copy_like_err_tuple.rs:18:1
    |
 LL | impl<T: lib::MyCopy> MyTrait for T { }
    | ---------------------------------- first implementation here
diff --git a/src/test/ui/coherence/coherence_inherent.re.stderr b/src/test/ui/coherence/coherence_inherent.re.stderr
deleted file mode 100644
index e71547cb89f..00000000000
--- a/src/test/ui/coherence/coherence_inherent.re.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0599]: no method named `the_fn` found for type `&Lib::TheStruct` in the current scope
-  --> $DIR/coherence_inherent.rs:35:11
-   |
-LL |         s.the_fn();
-   |           ^^^^^^ method not found in `&Lib::TheStruct`
-   |
-   = help: items from traits can only be used if the trait is in scope
-   = note: the following trait is implemented but not in scope; perhaps add a `use` for it:
-           `use Lib::TheTrait;`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/coherence/coherence_inherent.rs b/src/test/ui/coherence/coherence_inherent.rs
index f0d3682adb8..f3ebf000386 100644
--- a/src/test/ui/coherence/coherence_inherent.rs
+++ b/src/test/ui/coherence/coherence_inherent.rs
@@ -1,10 +1,6 @@
 // Tests that methods that implement a trait cannot be invoked
 // unless the trait is imported.
 
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
-
 mod Lib {
     pub trait TheTrait {
         fn the_fn(&self);
@@ -33,8 +29,7 @@ mod NoImport {
 
     fn call_the_fn(s: &TheStruct) {
         s.the_fn();
-        //[old]~^ ERROR no method named `the_fn` found
-        //[re]~^^ ERROR E0599
+        //~^ ERROR E0599
     }
 }
 
diff --git a/src/test/ui/coherence/coherence_inherent.old.stderr b/src/test/ui/coherence/coherence_inherent.stderr
index e71547cb89f..e719d5254f6 100644
--- a/src/test/ui/coherence/coherence_inherent.old.stderr
+++ b/src/test/ui/coherence/coherence_inherent.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `the_fn` found for type `&Lib::TheStruct` in the current scope
-  --> $DIR/coherence_inherent.rs:35:11
+  --> $DIR/coherence_inherent.rs:31:11
    |
 LL |         s.the_fn();
    |           ^^^^^^ method not found in `&Lib::TheStruct`
diff --git a/src/test/ui/coherence/coherence_inherent_cc.re.stderr b/src/test/ui/coherence/coherence_inherent_cc.re.stderr
deleted file mode 100644
index 3683943c5c8..00000000000
--- a/src/test/ui/coherence/coherence_inherent_cc.re.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0599]: no method named `the_fn` found for type `&coherence_inherent_cc_lib::TheStruct` in the current scope
-  --> $DIR/coherence_inherent_cc.rs:26:11
-   |
-LL |         s.the_fn();
-   |           ^^^^^^ method not found in `&coherence_inherent_cc_lib::TheStruct`
-   |
-   = help: items from traits can only be used if the trait is in scope
-   = note: the following trait is implemented but not in scope; perhaps add a `use` for it:
-           `use coherence_inherent_cc_lib::TheTrait;`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/coherence/coherence_inherent_cc.rs b/src/test/ui/coherence/coherence_inherent_cc.rs
index 2c980d839b9..759ada248f4 100644
--- a/src/test/ui/coherence/coherence_inherent_cc.rs
+++ b/src/test/ui/coherence/coherence_inherent_cc.rs
@@ -1,7 +1,4 @@
 // aux-build:coherence_inherent_cc_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 // Tests that methods that implement a trait cannot be invoked
 // unless the trait is imported.
@@ -24,8 +21,7 @@ mod NoImport {
 
     fn call_the_fn(s: &TheStruct) {
         s.the_fn();
-        //[old]~^ ERROR no method named `the_fn` found
-        //[re]~^^ ERROR E0599
+        //~^ ERROR E0599
     }
 }
 
diff --git a/src/test/ui/coherence/coherence_inherent_cc.old.stderr b/src/test/ui/coherence/coherence_inherent_cc.stderr
index 3683943c5c8..c666c1a3d1b 100644
--- a/src/test/ui/coherence/coherence_inherent_cc.old.stderr
+++ b/src/test/ui/coherence/coherence_inherent_cc.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `the_fn` found for type `&coherence_inherent_cc_lib::TheStruct` in the current scope
-  --> $DIR/coherence_inherent_cc.rs:26:11
+  --> $DIR/coherence_inherent_cc.rs:23:11
    |
 LL |         s.the_fn();
    |           ^^^^^^ method not found in `&coherence_inherent_cc_lib::TheStruct`
diff --git a/src/test/ui/coherence/coherence_local.rs b/src/test/ui/coherence/coherence_local.rs
index 3eab6e03ae3..ea724ada702 100644
--- a/src/test/ui/coherence/coherence_local.rs
+++ b/src/test/ui/coherence/coherence_local.rs
@@ -3,9 +3,6 @@
 
 // check-pass
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_copy_like_lib as lib;
 
diff --git a/src/test/ui/coherence/coherence_local_err_struct.re.stderr b/src/test/ui/coherence/coherence_local_err_struct.re.stderr
deleted file mode 100644
index 0782f823128..00000000000
--- a/src/test/ui/coherence/coherence_local_err_struct.re.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence_local_err_struct.rs:17:1
-   |
-LL | impl lib::MyCopy for lib::MyStruct<MyType> { }
-   | ^^^^^^^^^^^^^^^^^^^^^---------------------
-   | |                    |
-   | |                    `lib::MyStruct` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence_local_err_struct.rs b/src/test/ui/coherence/coherence_local_err_struct.rs
index d6faaf2977a..a24038eb280 100644
--- a/src/test/ui/coherence/coherence_local_err_struct.rs
+++ b/src/test/ui/coherence/coherence_local_err_struct.rs
@@ -2,9 +2,6 @@
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
 
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 
 extern crate coherence_copy_like_lib as lib;
@@ -15,8 +12,7 @@ struct MyType { x: i32 }
 
 // MyStruct is not fundamental.
 impl lib::MyCopy for lib::MyStruct<MyType> { }
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence_local_err_struct.old.stderr b/src/test/ui/coherence/coherence_local_err_struct.stderr
index 0782f823128..0a1aee9b5c1 100644
--- a/src/test/ui/coherence/coherence_local_err_struct.old.stderr
+++ b/src/test/ui/coherence/coherence_local_err_struct.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence_local_err_struct.rs:17:1
+  --> $DIR/coherence_local_err_struct.rs:14:1
    |
 LL | impl lib::MyCopy for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^---------------------
diff --git a/src/test/ui/coherence/coherence_local_err_tuple.old.stderr b/src/test/ui/coherence/coherence_local_err_tuple.old.stderr
deleted file mode 100644
index f01623f7621..00000000000
--- a/src/test/ui/coherence/coherence_local_err_tuple.old.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence_local_err_tuple.rs:17:1
-   |
-LL | impl lib::MyCopy for (MyType,) { }
-   | ^^^^^^^^^^^^^^^^^^^^^---------
-   | |                    |
-   | |                    this is not defined in the current crate because tuples are always foreign
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0117`.
diff --git a/src/test/ui/coherence/coherence_local_err_tuple.rs b/src/test/ui/coherence/coherence_local_err_tuple.rs
index 2685b2df8cb..f4033862a3e 100644
--- a/src/test/ui/coherence/coherence_local_err_tuple.rs
+++ b/src/test/ui/coherence/coherence_local_err_tuple.rs
@@ -2,9 +2,6 @@
 // `MyType: !MyTrait` along with other "fundamental" wrappers.
 
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 #![allow(dead_code)]
 
 extern crate coherence_copy_like_lib as lib;
@@ -15,8 +12,7 @@ struct MyType { x: i32 }
 
 // Tuples are not fundamental, so this is not a local impl.
 impl lib::MyCopy for (MyType,) { }
-//[old]~^ ERROR E0117
-//[re]~^^ ERROR E0117
+//~^ ERROR E0117
 
 
 fn main() { }
diff --git a/src/test/ui/coherence/coherence_local_err_tuple.re.stderr b/src/test/ui/coherence/coherence_local_err_tuple.stderr
index f01623f7621..a4953859f77 100644
--- a/src/test/ui/coherence/coherence_local_err_tuple.re.stderr
+++ b/src/test/ui/coherence/coherence_local_err_tuple.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/coherence_local_err_tuple.rs:17:1
+  --> $DIR/coherence_local_err_tuple.rs:14:1
    |
 LL | impl lib::MyCopy for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^---------
diff --git a/src/test/ui/coherence/coherence_local_ref.rs b/src/test/ui/coherence/coherence_local_ref.rs
index dff684c1699..2e28839c8a4 100644
--- a/src/test/ui/coherence/coherence_local_ref.rs
+++ b/src/test/ui/coherence/coherence_local_ref.rs
@@ -3,9 +3,6 @@
 
 // check-pass
 // aux-build:coherence_copy_like_lib.rs
-// revisions: old re
-
-#![cfg_attr(re, feature(re_rebalance_coherence))]
 
 extern crate coherence_copy_like_lib as lib;
 
diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.rs b/src/test/ui/coherence/impl-foreign-for-foreign.rs
index de0b66a35eb..4c0d46045e9 100644
--- a/src/test/ui/coherence/impl-foreign-for-foreign.rs
+++ b/src/test/ui/coherence/impl-foreign-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.stderr b/src/test/ui/coherence/impl-foreign-for-foreign.stderr
index 4d7757799e7..fe7c9b93f54 100644
--- a/src/test/ui/coherence/impl-foreign-for-foreign.stderr
+++ b/src/test/ui/coherence/impl-foreign-for-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign-for-foreign.rs:12:1
+  --> $DIR/impl-foreign-for-foreign.rs:10:1
    |
 LL | impl Remote for i32 {
    | ^^^^^^^^^^^^^^^^---
diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs
index 5146263d991..e79f66c0e13 100644
--- a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs
+++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr
index 4d15f0db65f..a33cff2a4d4 100644
--- a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr
+++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign-for-foreign[foreign].rs:12:1
+  --> $DIR/impl-foreign-for-foreign[foreign].rs:10:1
    |
 LL | impl Remote1<Rc<i32>> for i32 {
    | ^^^^^----------------^^^^^---
@@ -11,7 +11,7 @@ LL | impl Remote1<Rc<i32>> for i32 {
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign-for-foreign[foreign].rs:16:1
+  --> $DIR/impl-foreign-for-foreign[foreign].rs:14:1
    |
 LL | impl Remote1<Rc<Local>> for f64 {
    | ^^^^^------------------^^^^^---
@@ -23,7 +23,7 @@ LL | impl Remote1<Rc<Local>> for f64 {
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign-for-foreign[foreign].rs:20:1
+  --> $DIR/impl-foreign-for-foreign[foreign].rs:18:1
    |
 LL | impl<T> Remote1<Rc<T>> for f32 {
    | ^^^^^^^^--------------^^^^^---
diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[local].rs b/src/test/ui/coherence/impl-foreign-for-foreign[local].rs
index 050769dcf4c..0b1413edf37 100644
--- a/src/test/ui/coherence/impl-foreign-for-foreign[local].rs
+++ b/src/test/ui/coherence/impl-foreign-for-foreign[local].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs
index 03b11edf98b..10bdf2db8bb 100644
--- a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs
+++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
index d1f4d9849ac..bd1a933b766 100644
--- a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
+++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign-for-fundamental[foreign].rs:12:1
+  --> $DIR/impl-foreign-for-fundamental[foreign].rs:10:1
    |
 LL | impl Remote for Box<i32> {
    | ^^^^^^^^^^^^^^^^--------
@@ -10,7 +10,7 @@ LL | impl Remote for Box<i32> {
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign-for-fundamental[foreign].rs:16:1
+  --> $DIR/impl-foreign-for-fundamental[foreign].rs:14:1
    |
 LL | impl<T> Remote for Box<Rc<T>> {
    | ^^^^^^^^^^^^^^^^^^^----------
diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs b/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs
index ae03ce6a440..c3fc0e6b8a7 100644
--- a/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs
+++ b/src/test/ui/coherence/impl-foreign-for-fundamental[local].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl-foreign-for-local.rs b/src/test/ui/coherence/impl-foreign-for-local.rs
index c9dddeba18d..04405bc46fb 100644
--- a/src/test/ui/coherence/impl-foreign-for-local.rs
+++ b/src/test/ui/coherence/impl-foreign-for-local.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs
index d461b5abd60..49b3abc99b7 100644
--- a/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs
+++ b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental.rs
@@ -1,5 +1,4 @@
 #![feature(fundamental)]
-#![feature(re_rebalance_coherence)]
 
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
diff --git a/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs
index 0a3d9e2e0e8..1e11789ef39 100644
--- a/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs
+++ b/src/test/ui/coherence/impl-foreign-for-locally-defined-fundamental[foreign].rs
@@ -1,5 +1,4 @@
 #![feature(fundamental)]
-#![feature(re_rebalance_coherence)]
 
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs
index b08fedc5e11..99a399ddc63 100644
--- a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs
+++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr
index 07c7632a53f..5552d825793 100644
--- a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr
+++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign[foreign]-for-foreign.rs:12:1
+  --> $DIR/impl-foreign[foreign]-for-foreign.rs:10:1
    |
 LL | impl Remote1<u32> for f64 {
    | ^^^^^------------^^^^^---
diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs
index 33e85c16476..bc6595bb340 100644
--- a/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs
+++ b/src/test/ui/coherence/impl-foreign[foreign]-for-local.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs
index 06efb6c2ad7..0476cdaffe7 100644
--- a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs
+++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
index 8dcac05c0cc..3ca40e00729 100644
--- a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
+++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:13:1
+  --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:11:1
    |
 LL | impl Remote1<Box<String>> for i32 {
    | ^^^^^--------------------^^^^^---
@@ -11,7 +11,7 @@ LL | impl Remote1<Box<String>> for i32 {
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:17:1
+  --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:15:1
    |
 LL | impl Remote1<Box<Rc<i32>>> for f64 {
    | ^^^^^---------------------^^^^^---
@@ -23,7 +23,7 @@ LL | impl Remote1<Box<Rc<i32>>> for f64 {
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:21:1
+  --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:19:1
    |
 LL | impl<T> Remote1<Box<Rc<T>>> for f32 {
    | ^^^^^^^^-------------------^^^^^---
diff --git a/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs b/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs
index d47e0a36a56..7b83b048548 100644
--- a/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs
+++ b/src/test/ui/coherence/impl-foreign[fundemental[local]]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs
index db7a2ae8076..5282de4b271 100644
--- a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr
index 7e9d3c6e729..95889022bd7 100644
--- a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr
+++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr
@@ -1,5 +1,5 @@
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl[t]-foreign-for-foreign[t].rs:13:1
+  --> $DIR/impl[t]-foreign-for-foreign[t].rs:11:1
    |
 LL | impl Remote for Rc<Local> {
    | ^^^^^^^^^^^^^^^^---------
@@ -10,7 +10,7 @@ LL | impl Remote for Rc<Local> {
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
-  --> $DIR/impl[t]-foreign-for-foreign[t].rs:18:1
+  --> $DIR/impl[t]-foreign-for-foreign[t].rs:16:1
    |
 LL | impl<T> Remote for Arc<T> {
    | ^^^^^^^^^^^^^^^^^^^------
diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs
index 4cc19e1a526..6f5605a2193 100644
--- a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr
index a26b87a3262..69194bdaf56 100644
--- a/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr
+++ b/src/test/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign-for-fundamental[t].rs:12:6
+  --> $DIR/impl[t]-foreign-for-fundamental[t].rs:10:6
    |
 LL | impl<T> Remote for Box<T> {
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs
index 54d4bf04a58..99f3ce44760 100644
--- a/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[foreign[t]_local]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // check-pass
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs
index 66a4d9d2734..81044cd0529 100644
--- a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr
index cbead462e67..b0f34419bb3 100644
--- a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:12:6
+  --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:10:6
    |
 LL | impl<T> Remote1<u32> for Box<T> {
    |      ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<T> Remote1<u32> for Box<T> {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:16:10
+  --> $DIR/impl[t]-foreign[foreign]-for-fundamental[t].rs:14:10
    |
 LL | impl<'a, T> Remote1<u32> for &'a T {
    |          ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs
index 0a67ebcbba4..680ba9f2226 100644
--- a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr
index 3d9afdf6cf6..002f8b7286a 100644
--- a/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[foreign]-for-t.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[foreign]-for-t.rs:12:6
+  --> $DIR/impl[t]-foreign[foreign]-for-t.rs:10:6
    |
 LL | impl<T> Remote1<u32> for T {
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs
index 71598dae96a..fc7649085c3 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr
index 150b1962acb..0c43936e6d4 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:12:6
+  --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:10:6
    |
 LL | impl<T> Remote1<Box<T>> for u32 {
    |      ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<T> Remote1<Box<T>> for u32 {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:16:10
+  --> $DIR/impl[t]-foreign[fundamental[t]]-for-foreign.rs:14:10
    |
 LL | impl<'a, T> Remote1<&'a T> for u32 {
    |          ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs
index 7bf0306f29b..703f25dd60a 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr
index 0d86e74788c..f81f15b204b 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-fundamental[t].stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:12:10
+  --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:10:10
    |
 LL | impl<'a, T> Remote1<Box<T>> for &'a T {
    |          ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<'a, T> Remote1<Box<T>> for &'a T {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:15:10
+  --> $DIR/impl[t]-foreign[fundamental[t]]-for-fundamental[t].rs:13:10
    |
 LL | impl<'a, T> Remote1<&'a T> for Box<T> {
    |          ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs
index 54d577c7492..ec21fdd4e04 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-local.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs
index 7af929006ef..5bdab87bf4e 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr
index 04ac6a868fa..24fd492c57c 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]]-for-t.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:12:6
+  --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:10:6
    |
 LL | impl<T> Remote1<Box<T>> for T {
    |      ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<T> Remote1<Box<T>> for T {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:15:10
+  --> $DIR/impl[t]-foreign[fundamental[t]]-for-t.rs:13:10
    |
 LL | impl<'a, T> Remote1<&'a T> for T {
    |          ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs
index 24e0f309c45..4666e449ca9 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr
index f1fdcecf57d..6a1db165416 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[fundamental[t]_local]-for-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:12:6
+  --> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:10:6
    |
 LL | impl<T> Remote2<Box<T>, Local> for u32 {
    |      ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<T> Remote2<Box<T>, Local> for u32 {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:16:10
+  --> $DIR/impl[t]-foreign[fundamental[t]_local]-for-foreign.rs:14:10
    |
 LL | impl<'a, T> Remote2<&'a T, Local> for u32 {
    |          ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs
index 914680f191a..62e69357e3a 100644
--- a/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign[fundemental[local]]-for-foreign[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs
index 81cf3c3f6ec..1fec19bbab9 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs
index 1e84ff40c62..c8ed28be6f0 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-foreign[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs
index ea6aa101d20..f9b88c6459b 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[foreign[t]].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs
index 54425b6d708..db88c330b39 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr
index 99ccbb89fc2..b5fdb16c2f3 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-fundamental[t].stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:12:6
+  --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:10:6
    |
 LL | impl<T> Remote1<Local> for Box<T> {
    |      ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<T> Remote1<Local> for Box<T> {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:16:6
+  --> $DIR/impl[t]-foreign[local]-for-fundamental[t].rs:14:6
    |
 LL | impl<T> Remote1<Local> for &T {
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs
index 6b1d93cd944..9c14eea1be2 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-local.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs
index 6f35c6c9dbc..dd4110d31e6 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr
index 08cf414c139..7b65212f62a 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[local]-for-t.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[local]-for-t.rs:12:6
+  --> $DIR/impl[t]-foreign[local]-for-t.rs:10:6
    |
 LL | impl<T> Remote1<Local> for T {
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs
index be0875d0110..63c342b76f1 100644
--- a/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[local_fundamental[t]]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs
index 5e89c207733..9bb37c2baab 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr
index e9d1ea8a815..2e5ae6a8eb3 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-foreign.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[t]-for-foreign.rs:12:6
+  --> $DIR/impl[t]-foreign[t]-for-foreign.rs:10:6
    |
 LL | impl<T> Remote1<T> for u32 {
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs
index 300a2c4d48a..79b5aa3fc62 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr
index d8b0d25a578..3976f06947f 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-fundamental.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:12:6
+  --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:10:6
    |
 LL | impl<T> Remote1<T> for Box<T> {
    |      ^ type parameter `T` must be used as the type parameter for some local type
@@ -7,7 +7,7 @@ LL | impl<T> Remote1<T> for Box<T> {
    = note: only traits defined in the current crate can be implemented for a type parameter
 
 error[E0210]: type parameter `B` must be used as the type parameter for some local type (e.g., `MyStruct<B>`)
-  --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:16:13
+  --> $DIR/impl[t]-foreign[t]-for-fundamental.rs:14:13
    |
 LL | impl<'a, A, B> Remote1<A> for &'a B {
    |             ^ type parameter `B` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs
index 769147ea7ea..bc59721c088 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-local.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 // check-pass
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs
index c8513380ff7..bcd6b269a38 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // compile-flags:--crate-name=test
 // aux-build:coherence_lib.rs
 
diff --git a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr
index 7b651e66c3d..8d858b8abee 100644
--- a/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr
+++ b/src/test/ui/coherence/impl[t]-foreign[t]-for-t.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/impl[t]-foreign[t]-for-t.rs:12:6
+  --> $DIR/impl[t]-foreign[t]-for-t.rs:10:6
    |
 LL | impl<T> Remote1<T> for T {
    |      ^ type parameter `T` must be used as the type parameter for some local type
diff --git a/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs
index 3df6114f62a..d18e3f453c9 100644
--- a/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs
+++ b/src/test/ui/coherence/re-rebalance-coherence-default-generic-associated-type.rs
@@ -2,7 +2,6 @@
 // aux-build:re_rebalance_coherence_lib-rpass.rs
 
 #![allow(dead_code)]
-#![feature(re_rebalance_coherence)]
 // check that a generic type with a default value from an associated type can be used without
 // specifying the value, and without invoking coherence errors.
 
diff --git a/src/test/ui/coherence/re-rebalance-coherence.rs b/src/test/ui/coherence/re-rebalance-coherence.rs
index 33ad4e97536..38d096b08e1 100644
--- a/src/test/ui/coherence/re-rebalance-coherence.rs
+++ b/src/test/ui/coherence/re-rebalance-coherence.rs
@@ -1,5 +1,3 @@
-#![feature(re_rebalance_coherence)]
-
 // run-pass
 // aux-build:re_rebalance_coherence_lib.rs
 
diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr
index 8176e96d6de..326b84470d6 100644
--- a/src/test/ui/compare-method/reordered-type-param.stderr
+++ b/src/test/ui/compare-method/reordered-type-param.stderr
@@ -5,7 +5,10 @@ LL |   fn b<C:Clone,D>(&self, x: C) -> C;
    |                             - type in trait
 ...
 LL |   fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
-   |                              ^ expected type parameter, found a different type parameter
+   |        -       -             ^ expected type parameter `F`, found type parameter `G`
+   |        |       |
+   |        |       found type parameter
+   |        expected type parameter
    |
    = note: expected type `fn(&E, F) -> F`
               found type `fn(&E, G) -> G`
diff --git a/src/test/ui/const-generics/const-expression-parameter.stderr b/src/test/ui/const-generics/const-expression-parameter.stderr
index 7311e27c289..28bea4ec94f 100644
--- a/src/test/ui/const-generics/const-expression-parameter.stderr
+++ b/src/test/ui/const-generics/const-expression-parameter.stderr
@@ -2,7 +2,7 @@ error: expected one of `,` or `>`, found `+`
   --> $DIR/const-expression-parameter.rs:13:22
    |
 LL |     i32_identity::<1 + 2>();
-   |                      ^ expected one of `,` or `>` here
+   |                      ^ expected one of `,` or `>`
 
 warning: the feature `const_generics` is incomplete and may cause the compiler to crash
   --> $DIR/const-expression-parameter.rs:1:12
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.rs b/src/test/ui/consts/const-eval/const_fn_ptr.rs
index 498f801db81..9b94b45f522 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr.rs
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.rs
@@ -6,18 +6,18 @@ fn double(x: usize) -> usize { x * 2 }
 const fn double_const(x: usize) -> usize { x * 2 }
 
 const X: fn(usize) -> usize = double;
-const X_const: fn(usize) -> usize = double_const;
+const X_CONST: fn(usize) -> usize = double_const;
 
 const fn bar(x: usize) -> usize {
-    X(x)
+    X(x) //~ WARNING skipping const checks
 }
 
 const fn bar_const(x: usize) -> usize {
-    X_const(x)
+    X_CONST(x) //~ WARNING skipping const checks
 }
 
 const fn foo(x: fn(usize) -> usize, y: usize)  -> usize {
-    x(y)
+    x(y) //~ WARNING skipping const checks
 }
 
 fn main() {
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.stderr b/src/test/ui/consts/const-eval/const_fn_ptr.stderr
index 2fbb1932244..19fa3960346 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr.stderr
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.stderr
@@ -7,7 +7,7 @@ LL |     X(x)
 warning: skipping const checks
   --> $DIR/const_fn_ptr.rs:16:5
    |
-LL |     X_const(x)
+LL |     X_CONST(x)
    |     ^^^^^^^^^^
 
 warning: skipping const checks
@@ -16,11 +16,3 @@ warning: skipping const checks
 LL |     x(y)
    |     ^^^^
 
-warning: constant `X_const` should have an upper case name
-  --> $DIR/const_fn_ptr.rs:9:7
-   |
-LL | const X_const: fn(usize) -> usize = double_const;
-   |       ^^^^^^^ help: convert the identifier to upper case: `X_CONST`
-   |
-   = note: `#[warn(non_upper_case_globals)]` on by default
-
diff --git a/src/test/ui/consts/const-eval/issue-64970.rs b/src/test/ui/consts/const-eval/issue-64970.rs
index ede5081c8a5..ba530438f9a 100644
--- a/src/test/ui/consts/const-eval/issue-64970.rs
+++ b/src/test/ui/consts/const-eval/issue-64970.rs
@@ -10,6 +10,6 @@ fn foo(mut n: i32) {
     }
 
     if n > 0i32 {
-        1i32 / n;
+        let _ = 1i32 / n;
     }
 }
diff --git a/src/test/ui/consts/const-eval/issue-64970.stderr b/src/test/ui/consts/const-eval/issue-64970.stderr
deleted file mode 100644
index 2c44b68cbd1..00000000000
--- a/src/test/ui/consts/const-eval/issue-64970.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: unused arithmetic operation that must be used
-  --> $DIR/issue-64970.rs:13:9
-   |
-LL |         1i32 / n;
-   |         ^^^^^^^^
-   |
-   = note: `#[warn(unused_must_use)]` on by default
-
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 9134ef5a31a..85fb8ac2a4a 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:107:1
    |
 LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
@@ -90,7 +90,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:133:1
    |
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
diff --git a/src/test/ui/consts/const-size_of-cycle.rs b/src/test/ui/consts/const-size_of-cycle.rs
index 1bbe881872c..6c35b9212c6 100644
--- a/src/test/ui/consts/const-size_of-cycle.rs
+++ b/src/test/ui/consts/const-size_of-cycle.rs
@@ -1,5 +1,4 @@
-// ignore-musl
-// ignore-x86
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // error-pattern: cycle detected
 
 struct Foo {
diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr
index 1ae39e7563a..5b06ade44c5 100644
--- a/src/test/ui/consts/const-size_of-cycle.stderr
+++ b/src/test/ui/consts/const-size_of-cycle.stderr
@@ -1,11 +1,11 @@
 error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0`
-  --> $DIR/const-size_of-cycle.rs:6:17
+  --> $DIR/const-size_of-cycle.rs:5:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
-  --> $DIR/const-size_of-cycle.rs:6:17
+  --> $DIR/const-size_of-cycle.rs:5:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     pub fn size_of<T>() -> usize;
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
    = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
-  --> $DIR/const-size_of-cycle.rs:5:1
+  --> $DIR/const-size_of-cycle.rs:4:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
diff --git a/src/test/ui/consts/const_let_promote.rs b/src/test/ui/consts/const_let_promote.rs
new file mode 100644
index 00000000000..f4661e9e425
--- /dev/null
+++ b/src/test/ui/consts/const_let_promote.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+use std::cell::Cell;
+
+const X: Option<Cell<i32>> = None;
+
+const Y: Option<Cell<i32>> = {
+    let x = None;
+    x
+};
+
+// Ensure that binding the final value of a `const` to a variable does not affect promotion.
+#[allow(unused)]
+fn main() {
+    let x: &'static _ = &X;
+    let y: &'static _ = &Y;
+}
diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr
index 7f15f02d4d3..9acb4ad9cbb 100644
--- a/src/test/ui/consts/const_let_refutable.stderr
+++ b/src/test/ui/consts/const_let_refutable.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _]` not covered
+error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
   --> $DIR/const_let_refutable.rs:3:16
    |
 LL | const fn slice([a, b]: &[i32]) -> i32 {
-   |                ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _]` not covered
+   |                ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
   --> $DIR/const_let_refutable.rs:4:5
diff --git a/src/test/ui/consts/issue-62045.rs b/src/test/ui/consts/issue-62045.rs
index efeb9fc551c..5abed374a6d 100644
--- a/src/test/ui/consts/issue-62045.rs
+++ b/src/test/ui/consts/issue-62045.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     assert_eq!(&mut [0; 1][..], &mut []);
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs
index d0f63b148ff..db68a05905a 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs
@@ -136,7 +136,6 @@ const fn no_rpit() -> impl std::fmt::Debug {} //~ ERROR `impl Trait` in const fn
 const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {} //~ ERROR trait bounds other than `Sized`
 const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
 //~^ ERROR trait bounds other than `Sized`
-//~| ERROR cannot return reference to temporary value
 
 const fn no_unsafe() { unsafe {} }
 
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
index 3158b6284db..64b2ce83da2 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr
@@ -286,17 +286,8 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0515]: cannot return reference to temporary value
-  --> $DIR/min_const_fn.rs:137:63
-   |
-LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
-   |                                                               ^--
-   |                                                               ||
-   |                                                               |temporary value created here
-   |                                                               returns a reference to data owned by the current function
-
 error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
-  --> $DIR/min_const_fn.rs:143:41
+  --> $DIR/min_const_fn.rs:142:41
    |
 LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1 }
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -305,7 +296,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:146:21
+  --> $DIR/min_const_fn.rs:145:21
    |
 LL | const fn no_fn_ptrs(_x: fn()) {}
    |                     ^^
@@ -314,7 +305,7 @@ LL | const fn no_fn_ptrs(_x: fn()) {}
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
 error[E0723]: function pointers in const fn are unstable
-  --> $DIR/min_const_fn.rs:148:27
+  --> $DIR/min_const_fn.rs:147:27
    |
 LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    |                           ^^^^
@@ -322,7 +313,7 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error: aborting due to 37 previous errors
+error: aborting due to 36 previous errors
 
-Some errors have detailed explanations: E0493, E0515, E0723.
+Some errors have detailed explanations: E0493, E0723.
 For more information about an error, try `rustc --explain E0493`.
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
index 3833510c0b3..6ca1e59b3af 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.rs
@@ -11,6 +11,5 @@ const fn no_inner_dyn_trait2(x: Hide) {
 }
 const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
 //~^ ERROR trait bounds other than `Sized`
-//~| ERROR temporary value dropped while borrowed
 
 fn main() {}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
index 0ea950d678f..e20b4f9dcb4 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr
@@ -16,16 +16,6 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/min_const_fn_dyn.rs:12:67
-   |
-LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
-   |                                                                  -^    - temporary value is freed at the end of this statement
-   |                                                                  ||
-   |                                                                  |creates a temporary which is freed while still in use
-   |                                                                  cast requires that borrow lasts for `'static`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0716, E0723.
-For more information about an error, try `rustc --explain E0716`.
+For more information about this error, try `rustc --explain E0723`.
diff --git a/src/test/ui/consts/miri_unleashed/enum_discriminants.rs b/src/test/ui/consts/miri_unleashed/enum_discriminants.rs
index 9f34fc73953..623fa2a1547 100644
--- a/src/test/ui/consts/miri_unleashed/enum_discriminants.rs
+++ b/src/test/ui/consts/miri_unleashed/enum_discriminants.rs
@@ -20,9 +20,9 @@ const OVERFLOW: usize = {
         C(WithWraparoundInvalidValues),
     }
 
-    let x = Foo::B;
+    let x = Foo::B; //~ WARNING skipping const checks
     match x {
-        Foo::B => 0,
+        Foo::B => 0, //~ WARNING skipping const checks
         _ => panic!(),
     }
 };
@@ -86,6 +86,8 @@ const MORE_OVERFLOW: usize = {
     }
 
     if let E1::V2 { .. } = (E1::V1 { f: true }) {
+        //~^ WARNING skipping const checks
+        //~| WARNING skipping const checks
         unreachable!()
     }
     if let E1::V1 { .. } = (E1::V1 { f: true }) {
diff --git a/src/test/ui/consts/packed_pattern.rs b/src/test/ui/consts/packed_pattern.rs
index 37ae45b6df7..370fec6fbd4 100644
--- a/src/test/ui/consts/packed_pattern.rs
+++ b/src/test/ui/consts/packed_pattern.rs
@@ -13,7 +13,7 @@ const FOO: Foo = Foo {
 fn main() {
     match FOO {
         Foo { field: (5, 6, 7, 8) } => {},
-        FOO => unreachable!(),
+        FOO => unreachable!(), //~ WARNING unreachable pattern
         _ => unreachable!(),
     }
 }
diff --git a/src/test/ui/consts/packed_pattern2.rs b/src/test/ui/consts/packed_pattern2.rs
index 174161fbd94..ef68d9e513a 100644
--- a/src/test/ui/consts/packed_pattern2.rs
+++ b/src/test/ui/consts/packed_pattern2.rs
@@ -21,7 +21,7 @@ const FOO: Bar = Bar {
 fn main() {
     match FOO {
         Bar { a: Foo { field: (5, 6) } } => {},
-        FOO => unreachable!(),
+        FOO => unreachable!(), //~ WARNING unreachable pattern
         _ => unreachable!(),
     }
 }
diff --git a/src/test/ui/consts/promote_borrowed_field.rs b/src/test/ui/consts/promote_borrowed_field.rs
new file mode 100644
index 00000000000..c4841b46f60
--- /dev/null
+++ b/src/test/ui/consts/promote_borrowed_field.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+// From https://github.com/rust-lang/rust/issues/65727
+
+const _: &i32 = {
+    let x = &(5, false).0;
+    x
+};
+
+fn main() {
+    let _: &'static i32 = &(5, false).0;
+}
diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs
index 464ddcc4cdb..bfeab49548f 100644
--- a/src/test/ui/deprecation/deprecation-in-future.rs
+++ b/src/test/ui/deprecation/deprecation-in-future.rs
@@ -7,6 +7,7 @@ pub fn deprecated_future() {}
 
 fn test() {
     deprecated_future(); // ok; deprecated_in_future only applies to rustc_deprecated
+    //~^ WARNING use of deprecated item 'deprecated_future': text [deprecated]
 }
 
 fn main() {}
diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
index b556d442420..da00f81b96e 100644
--- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
index 7db5fbe3de4..796e6a2b744 100644
--- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Clone-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-enum.rs b/src/test/ui/derives/derives-span-Clone-enum.rs
index 9bb4f486c3e..98ae1b2c5b8 100644
--- a/src/test/ui/derives/derives-span-Clone-enum.rs
+++ b/src/test/ui/derives/derives-span-Clone-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-enum.stderr b/src/test/ui/derives/derives-span-Clone-enum.stderr
index 4371dc900ac..3e94bb551ea 100644
--- a/src/test/ui/derives/derives-span-Clone-enum.stderr
+++ b/src/test/ui/derives/derives-span-Clone-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-enum.rs:9:6
+  --> $DIR/derives-span-Clone-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-struct.rs b/src/test/ui/derives/derives-span-Clone-struct.rs
index f151636f848..db677e26f50 100644
--- a/src/test/ui/derives/derives-span-Clone-struct.rs
+++ b/src/test/ui/derives/derives-span-Clone-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-struct.stderr b/src/test/ui/derives/derives-span-Clone-struct.stderr
index cc3b602c9c0..0674d64fe9d 100644
--- a/src/test/ui/derives/derives-span-Clone-struct.stderr
+++ b/src/test/ui/derives/derives-span-Clone-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-struct.rs:8:5
+  --> $DIR/derives-span-Clone-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.rs b/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
index 7a62885324e..d716b6fe900 100644
--- a/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
index b2bf3527b0c..f6b4006014a 100644
--- a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Clone-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
index 949597bc8f6..10deccb8ad7 100644
--- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
index ca5bcfe930d..6a0e382b9e5 100644
--- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Debug-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-enum.rs b/src/test/ui/derives/derives-span-Debug-enum.rs
index b2a39708ceb..b8bed0eab55 100644
--- a/src/test/ui/derives/derives-span-Debug-enum.rs
+++ b/src/test/ui/derives/derives-span-Debug-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-enum.stderr b/src/test/ui/derives/derives-span-Debug-enum.stderr
index cd367a334fc..f27499ba441 100644
--- a/src/test/ui/derives/derives-span-Debug-enum.stderr
+++ b/src/test/ui/derives/derives-span-Debug-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-enum.rs:9:6
+  --> $DIR/derives-span-Debug-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-struct.rs b/src/test/ui/derives/derives-span-Debug-struct.rs
index cf91c9436a6..22f037ee36f 100644
--- a/src/test/ui/derives/derives-span-Debug-struct.rs
+++ b/src/test/ui/derives/derives-span-Debug-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-struct.stderr b/src/test/ui/derives/derives-span-Debug-struct.stderr
index e00695ec0ba..09d62f12b04 100644
--- a/src/test/ui/derives/derives-span-Debug-struct.stderr
+++ b/src/test/ui/derives/derives-span-Debug-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-struct.rs:8:5
+  --> $DIR/derives-span-Debug-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.rs b/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
index cea973c91a7..c693facfeaa 100644
--- a/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
index 37440b59ae7..f100cf32fdf 100644
--- a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Debug-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Default-struct.rs b/src/test/ui/derives/derives-span-Default-struct.rs
index 71fd5829e75..1654883998d 100644
--- a/src/test/ui/derives/derives-span-Default-struct.rs
+++ b/src/test/ui/derives/derives-span-Default-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Default-struct.stderr b/src/test/ui/derives/derives-span-Default-struct.stderr
index 413d4ec8c29..11664d400ee 100644
--- a/src/test/ui/derives/derives-span-Default-struct.stderr
+++ b/src/test/ui/derives/derives-span-Default-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::default::Default` is not satisfied
-  --> $DIR/derives-span-Default-struct.rs:8:5
+  --> $DIR/derives-span-Default-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::default::Default` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.rs b/src/test/ui/derives/derives-span-Default-tuple-struct.rs
index 463f7d230ca..f1390c8b6f6 100644
--- a/src/test/ui/derives/derives-span-Default-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Default-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
index 8f4d43daa51..c79f093942f 100644
--- a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::default::Default` is not satisfied
-  --> $DIR/derives-span-Default-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Default-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::default::Default` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
index d2dab8687f7..77c386d7f90 100644
--- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
index 52ecce4632d..87c0313ca1f 100644
--- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Eq-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-enum.rs b/src/test/ui/derives/derives-span-Eq-enum.rs
index c6c0d432108..c7fe3781332 100644
--- a/src/test/ui/derives/derives-span-Eq-enum.rs
+++ b/src/test/ui/derives/derives-span-Eq-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-enum.stderr b/src/test/ui/derives/derives-span-Eq-enum.stderr
index bf91a0edc37..c8db6d3ff2f 100644
--- a/src/test/ui/derives/derives-span-Eq-enum.stderr
+++ b/src/test/ui/derives/derives-span-Eq-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-enum.rs:9:6
+  --> $DIR/derives-span-Eq-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-struct.rs b/src/test/ui/derives/derives-span-Eq-struct.rs
index df310039847..8674cadb309 100644
--- a/src/test/ui/derives/derives-span-Eq-struct.rs
+++ b/src/test/ui/derives/derives-span-Eq-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-struct.stderr b/src/test/ui/derives/derives-span-Eq-struct.stderr
index 531e8887cd2..df4ea5b1d41 100644
--- a/src/test/ui/derives/derives-span-Eq-struct.stderr
+++ b/src/test/ui/derives/derives-span-Eq-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-struct.rs:8:5
+  --> $DIR/derives-span-Eq-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.rs b/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
index abf6526b900..99cc9582b5b 100644
--- a/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
index 9e21c6c67bf..def06d71086 100644
--- a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Eq-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
index ed87360a0be..604b0842fa9 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
index 708ebca9fb1..cc1caf78041 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum-struct-variant.rs:11:6
+  --> $DIR/derives-span-Hash-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum.rs b/src/test/ui/derives/derives-span-Hash-enum.rs
index 5b3649c9826..bf3033a232c 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr
index dc171cbe5dd..246d821ed2b 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum.rs:11:6
+  --> $DIR/derives-span-Hash-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-struct.rs b/src/test/ui/derives/derives-span-Hash-struct.rs
index ead70861a0a..b6abb9d229e 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-struct.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr
index 429449b82bf..720c127635e 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-struct.rs:10:5
+  --> $DIR/derives-span-Hash-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
index 820f13ed18e..e01351fe8a6 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
index a6c4c479b24..1fd1e601eca 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-tuple-struct.rs:10:5
+  --> $DIR/derives-span-Hash-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
index 62355cc2d96..6d516d4b0ad 100644
--- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
index 5c0d4e4ebe9..f0d7e4465a7 100644
--- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Ord-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-enum.rs b/src/test/ui/derives/derives-span-Ord-enum.rs
index 72738931d10..51b5d7f0ed1 100644
--- a/src/test/ui/derives/derives-span-Ord-enum.rs
+++ b/src/test/ui/derives/derives-span-Ord-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-enum.stderr b/src/test/ui/derives/derives-span-Ord-enum.stderr
index 56268a23745..37eca92e77e 100644
--- a/src/test/ui/derives/derives-span-Ord-enum.stderr
+++ b/src/test/ui/derives/derives-span-Ord-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-enum.rs:9:6
+  --> $DIR/derives-span-Ord-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-struct.rs b/src/test/ui/derives/derives-span-Ord-struct.rs
index 53d4c2c22b5..c924ecaa315 100644
--- a/src/test/ui/derives/derives-span-Ord-struct.rs
+++ b/src/test/ui/derives/derives-span-Ord-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-struct.stderr b/src/test/ui/derives/derives-span-Ord-struct.stderr
index 40dc3d09dad..72c1fe4803c 100644
--- a/src/test/ui/derives/derives-span-Ord-struct.stderr
+++ b/src/test/ui/derives/derives-span-Ord-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-struct.rs:8:5
+  --> $DIR/derives-span-Ord-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.rs b/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
index 4e09c270986..80546634690 100644
--- a/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
index 4a9dea8c12e..642c8579b51 100644
--- a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Ord-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
index d66faa086de..b13798686c0 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
index ed5468cc4da..d6a56525601 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^
@@ -7,7 +7,7 @@ LL |      x: Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.rs b/src/test/ui/derives/derives-span-PartialEq-enum.rs
index 66edf460b31..5f8f05ad94b 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
index 06a88c03f58..1f5ad42a3aa 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^
@@ -7,7 +7,7 @@ LL |      Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.rs b/src/test/ui/derives/derives-span-PartialEq-struct.rs
index ce5c67af77f..560bf582e8d 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
index b8481048361..4e0b2fa4e6f 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^
@@ -7,7 +7,7 @@ LL |     x: Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
index eaa62831136..09a3249f059 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
index 4398d252125..78e215534e0 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^
@@ -7,7 +7,7 @@ LL |     Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
index 0bc6f98d982..0d18bdc113a 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
index ac9f4504635..a6f0c873e2f 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.rs b/src/test/ui/derives/derives-span-PartialOrd-enum.rs
index ee4423f3bee..78e4babb976 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
index 3e684aef39f..838126111c3 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-struct.rs
index 48435e0cd45..728ec75b6c4 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
index 10659aac642..2df64d915a9 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
index 2aa412e6d1d..c92b47e9297 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
index cbe05e37840..63aebe32ed2 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index f0baa175d63..30ae6ed4c6d 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -48,7 +48,7 @@ error: expected one of `!` or `::`, found `(`
   --> $DIR/issue-40006.rs:28:9
    |
 LL |     ::Y ();
-   |         ^ expected one of `!` or `::` here
+   |         ^ expected one of `!` or `::`
 
 error: missing `fn`, `type`, or `const` for impl-item declaration
   --> $DIR/issue-40006.rs:32:8
diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
index 35123b11133..f230395f7a5 100644
--- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
+++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr
@@ -24,7 +24,7 @@ error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found
 LL |     if (a and b) {
    |           ^^^
    |           |
-   |           expected one of 8 possible tokens here
+   |           expected one of 8 possible tokens
    |           help: use `&&` instead of `and` for the boolean operator
 
 error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or`
@@ -33,7 +33,7 @@ error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found
 LL |     if (a or b) {
    |           ^^
    |           |
-   |           expected one of 8 possible tokens here
+   |           expected one of 8 possible tokens
    |           help: use `||` instead of `or` for the boolean operator
 
 error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
@@ -42,7 +42,7 @@ error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
 LL |     while a and b {
    |             ^^^
    |             |
-   |             expected one of `!`, `.`, `::`, `?`, `{`, or an operator here
+   |             expected one of `!`, `.`, `::`, `?`, `{`, or an operator
    |             help: use `&&` instead of `and` for the boolean operator
 
 error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
@@ -51,7 +51,7 @@ error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
 LL |     while a or b {
    |             ^^
    |             |
-   |             expected one of `!`, `.`, `::`, `?`, `{`, or an operator here
+   |             expected one of `!`, `.`, `::`, `?`, `{`, or an operator
    |             help: use `||` instead of `or` for the boolean operator
 
 error: aborting due to 6 previous errors
diff --git a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
index 2718e89a3f2..4cb9bd1975a 100644
--- a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
+++ b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#56327: Some occurrences of `dyn` within a macro are
 // not instances of identifiers, and thus should *not* be caught by the
diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
index 77eb44c2065..22a7495ca23 100644
--- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
@@ -36,7 +36,7 @@ error: macro expansion ends with an incomplete expression: expected one of `move
   --> <::edition_kw_macro_2015::passes_ident macros>:1:22
    |
 LL | ($ i : ident) => ($ i)
-   |                      ^ expected one of `move`, `|`, or `||` here
+   |                      ^ expected one of `move`, `|`, or `||`
    | 
   ::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8
    |
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
index 01f9f00e91c..7488fcc2e58 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
@@ -36,7 +36,7 @@ error: macro expansion ends with an incomplete expression: expected one of `move
   --> <::edition_kw_macro_2018::passes_ident macros>:1:22
    |
 LL | ($ i : ident) => ($ i)
-   |                      ^ expected one of `move`, `|`, or `||` here
+   |                      ^ expected one of `move`, `|`, or `||`
    | 
   ::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8
    |
diff --git a/src/test/ui/enum-discriminant/discriminant_value.rs b/src/test/ui/enum-discriminant/discriminant_value.rs
index b7000015c71..32d2d40241c 100644
--- a/src/test/ui/enum-discriminant/discriminant_value.rs
+++ b/src/test/ui/enum-discriminant/discriminant_value.rs
@@ -51,34 +51,31 @@ enum Mixed {
 }
 
 pub fn main() {
-    unsafe {
+    assert_eq!(discriminant_value(&CLike1::A), 0);
+    assert_eq!(discriminant_value(&CLike1::B), 1);
+    assert_eq!(discriminant_value(&CLike1::C), 2);
+    assert_eq!(discriminant_value(&CLike1::D), 3);
 
-        assert_eq!(discriminant_value(&CLike1::A), 0);
-        assert_eq!(discriminant_value(&CLike1::B), 1);
-        assert_eq!(discriminant_value(&CLike1::C), 2);
-        assert_eq!(discriminant_value(&CLike1::D), 3);
+    assert_eq!(discriminant_value(&CLike2::A), 5);
+    assert_eq!(discriminant_value(&CLike2::B), 2);
+    assert_eq!(discriminant_value(&CLike2::C), 19);
+    assert_eq!(discriminant_value(&CLike2::D), 20);
 
-        assert_eq!(discriminant_value(&CLike2::A), 5);
-        assert_eq!(discriminant_value(&CLike2::B), 2);
-        assert_eq!(discriminant_value(&CLike2::C), 19);
-        assert_eq!(discriminant_value(&CLike2::D), 20);
+    assert_eq!(discriminant_value(&CLike3::A), 5);
+    assert_eq!(discriminant_value(&CLike3::B), 6);
+    assert_eq!(discriminant_value(&CLike3::C), -1_i8 as u64);
+    assert_eq!(discriminant_value(&CLike3::D), 0);
 
-        assert_eq!(discriminant_value(&CLike3::A), 5);
-        assert_eq!(discriminant_value(&CLike3::B), 6);
-        assert_eq!(discriminant_value(&CLike3::C), -1_i8 as u64);
-        assert_eq!(discriminant_value(&CLike3::D), 0);
+    assert_eq!(discriminant_value(&ADT::First(0,0)), 0);
+    assert_eq!(discriminant_value(&ADT::Second(5)), 1);
 
-        assert_eq!(discriminant_value(&ADT::First(0,0)), 0);
-        assert_eq!(discriminant_value(&ADT::Second(5)), 1);
+    assert_eq!(discriminant_value(&NullablePointer::Nothing), 1);
+    assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0);
 
-        assert_eq!(discriminant_value(&NullablePointer::Nothing), 1);
-        assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0);
+    assert_eq!(discriminant_value(&10), 0);
+    assert_eq!(discriminant_value(&"test"), 0);
 
-        assert_eq!(discriminant_value(&10), 0);
-        assert_eq!(discriminant_value(&"test"), 0);
-
-        assert_eq!(3, discriminant_value(&Mixed::Unit));
-        assert_eq!(2, discriminant_value(&Mixed::Tuple(5)));
-        assert_eq!(1, discriminant_value(&Mixed::Struct{a: 7, b: 11}));
-    }
+    assert_eq!(3, discriminant_value(&Mixed::Unit));
+    assert_eq!(2, discriminant_value(&Mixed::Tuple(5)));
+    assert_eq!(1, discriminant_value(&Mixed::Struct{a: 7, b: 11}));
 }
diff --git a/src/test/ui/error-codes/e0119/complex-impl.rs b/src/test/ui/error-codes/e0119/complex-impl.rs
index 3cba39ecbf9..7dbf93ada5e 100644
--- a/src/test/ui/error-codes/e0119/complex-impl.rs
+++ b/src/test/ui/error-codes/e0119/complex-impl.rs
@@ -6,7 +6,7 @@ use complex_impl_support::{External, M};
 
 struct Q;
 
-impl<R> External for (Q, R) {} //~ ERROR must be used
+impl<R> External for (Q, R) {} //~ ERROR only traits defined
 //~^ ERROR conflicting implementations of trait
 
 fn main() {}
diff --git a/src/test/ui/error-codes/e0119/complex-impl.stderr b/src/test/ui/error-codes/e0119/complex-impl.stderr
index f7516d20af4..0c18a1fbd1f 100644
--- a/src/test/ui/error-codes/e0119/complex-impl.stderr
+++ b/src/test/ui/error-codes/e0119/complex-impl.stderr
@@ -8,15 +8,18 @@ LL | impl<R> External for (Q, R) {}
            - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box<U>, V, W>)
              where <U as std::ops::FnOnce<(T,)>>::Output == V, <V as std::iter::Iterator>::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, <W as std::ops::Add>::Output: std::marker::Copy;
 
-error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g., `MyStruct<R>`)
-  --> $DIR/complex-impl.rs:9:6
+error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
+  --> $DIR/complex-impl.rs:9:1
    |
 LL | impl<R> External for (Q, R) {}
-   |      ^ type parameter `R` must be used as the type parameter for some local type
+   | ^^^^^^^^^^^^^^^^^^^^^------
+   | |                    |
+   | |                    this is not defined in the current crate because tuples are always foreign
+   | impl doesn't use only types from inside the current crate
    |
-   = note: only traits defined in the current crate can be implemented for a type parameter
+   = note: define and implement a trait or new type instead
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0119, E0210.
-For more information about an error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0117, E0119.
+For more information about an error, try `rustc --explain E0117`.
diff --git a/src/test/ui/extern/extern-prelude-core.rs b/src/test/ui/extern/extern-prelude-core.rs
index f0d43404b00..56206425f84 100644
--- a/src/test/ui/extern/extern-prelude-core.rs
+++ b/src/test/ui/extern/extern-prelude-core.rs
@@ -1,5 +1,5 @@
 // run-pass
-#![feature(extern_prelude, lang_items, start)]
+#![feature(lang_items, start)]
 #![no_std]
 
 extern crate std as other;
diff --git a/src/test/ui/extern/extern-prelude-core.stderr b/src/test/ui/extern/extern-prelude-core.stderr
deleted file mode 100644
index f90eb933d3f..00000000000
--- a/src/test/ui/extern/extern-prelude-core.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable
-  --> $DIR/extern-prelude-core.rs:2:12
-   |
-LL | #![feature(extern_prelude, lang_items, start)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(stable_features)]` on by default
-
diff --git a/src/test/ui/extern/extern-prelude-std.rs b/src/test/ui/extern/extern-prelude-std.rs
index 3d28448ee86..b5627fad960 100644
--- a/src/test/ui/extern/extern-prelude-std.rs
+++ b/src/test/ui/extern/extern-prelude-std.rs
@@ -1,5 +1,4 @@
 // run-pass
-#![feature(extern_prelude)]
 
 mod foo {
     pub fn test() {
diff --git a/src/test/ui/extern/extern-prelude-std.stderr b/src/test/ui/extern/extern-prelude-std.stderr
deleted file mode 100644
index 73b1dcfd5e1..00000000000
--- a/src/test/ui/extern/extern-prelude-std.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable
-  --> $DIR/extern-prelude-std.rs:2:12
-   |
-LL | #![feature(extern_prelude)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(stable_features)]` on by default
-
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs b/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs
index bb9e6d4ca83..80c602eb00a 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs
@@ -15,7 +15,7 @@ mod inline {
     //~^ ERROR attribute should be applied to function or closure
 
     #[inline = "2100"] fn f() { }
-    //~^ WARN attribute must be of the form
+    //~^ ERROR attribute must be of the form
     //~| WARN this was previously accepted
 
     #[inline] struct S;
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr
index 4310a0c7d58..0987937192f 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr
@@ -1,10 +1,10 @@
-warning: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
+error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
   --> $DIR/issue-43106-gating-of-inline.rs:17:5
    |
 LL |     #[inline = "2100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^
    |
-   = note: `#[warn(ill_formed_attribute_input)]` on by default
+   = note: `#[deny(ill_formed_attribute_input)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
@@ -47,6 +47,6 @@ error[E0518]: attribute should be applied to function or closure
 LL |     #[inline] impl S { }
    |     ^^^^^^^^^ ---------- not a function or closure
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0518`.
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
index dab946bb818..75a3d9124eb 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
@@ -3,7 +3,7 @@
 // `#![macro_escape]` is incompatible with crate-level `#![macro_use]`
 // already present in issue-43106-gating-of-builtin-attrs.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![macro_escape]
 //~^ WARN macro_escape is a deprecated synonym for macro_use
diff --git a/src/test/ui/feature-gate/unstable-attribute-allow-issue-none.rs b/src/test/ui/feature-gate/unstable-attribute-allow-issue-none.rs
new file mode 100644
index 00000000000..3ce9de3fb1b
--- /dev/null
+++ b/src/test/ui/feature-gate/unstable-attribute-allow-issue-none.rs
@@ -0,0 +1,13 @@
+// Check that an issue value can be explicitly set to "none" instead of "0"
+#![crate_type = "lib"]
+#![feature(staged_api)]
+#![stable(feature = "stable_test_feature", since = "1.0.0")]
+
+#[unstable(feature = "unstable_test_feature", issue = "0")]
+fn unstable_issue_0() {}
+
+#[unstable(feature = "unstable_test_feature", issue = "none")]
+fn unstable_issue_none() {}
+
+#[unstable(feature = "unstable_test_feature", issue = "something")] //~ ERROR incorrect 'issue'
+fn unstable_issue_not_allowed() {}
diff --git a/src/test/ui/feature-gate/unstable-attribute-allow-issue-none.stderr b/src/test/ui/feature-gate/unstable-attribute-allow-issue-none.stderr
new file mode 100644
index 00000000000..fc031f5f8c5
--- /dev/null
+++ b/src/test/ui/feature-gate/unstable-attribute-allow-issue-none.stderr
@@ -0,0 +1,8 @@
+error[E0545]: incorrect 'issue'
+  --> $DIR/unstable-attribute-allow-issue-none.rs:12:1
+   |
+LL | #[unstable(feature = "unstable_test_feature", issue = "something")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/feature-gated-feature-in-macro-arg.stderr b/src/test/ui/feature-gated-feature-in-macro-arg.stderr
index 5ee05154c3a..218e0292776 100644
--- a/src/test/ui/feature-gated-feature-in-macro-arg.stderr
+++ b/src/test/ui/feature-gated-feature-in-macro-arg.stderr
@@ -1,10 +1,8 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gated-feature-in-macro-arg.rs:8:9
+  --> $DIR/feature-gated-feature-in-macro-arg.rs:8:16
    |
-LL | /         extern "rust-intrinsic" {
-LL | |             fn atomic_fence();
-LL | |         }
-   | |_________^
+LL |         extern "rust-intrinsic" {
+   |                ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
diff --git a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
index 0d2e355535d..d58a2d91b2b 100644
--- a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
@@ -1,8 +1,8 @@
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi-msp430-interrupt.rs:4:1
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:4:8
    |
 LL | extern "msp430-interrupt" fn foo() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr
index 0f2622f1065..6db6cb49cef 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi.stderr
@@ -1,591 +1,591 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:13:1
+  --> $DIR/feature-gate-abi.rs:13:8
    |
 LL | extern "rust-intrinsic" fn f1() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:15:1
+  --> $DIR/feature-gate-abi.rs:15:8
    |
 LL | extern "platform-intrinsic" fn f2() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:17:1
+  --> $DIR/feature-gate-abi.rs:17:8
    |
 LL | extern "vectorcall" fn f3() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:18:1
+  --> $DIR/feature-gate-abi.rs:18:8
    |
 LL | extern "rust-call" fn f4() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:19:1
+  --> $DIR/feature-gate-abi.rs:19:8
    |
 LL | extern "msp430-interrupt" fn f5() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:20:1
+  --> $DIR/feature-gate-abi.rs:20:8
    |
 LL | extern "ptx-kernel" fn f6() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:21:1
+  --> $DIR/feature-gate-abi.rs:21:8
    |
 LL | extern "x86-interrupt" fn f7() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:22:1
+  --> $DIR/feature-gate-abi.rs:22:8
    |
 LL | extern "thiscall" fn f8() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:23:1
+  --> $DIR/feature-gate-abi.rs:23:8
    |
 LL | extern "amdgpu-kernel" fn f9() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:24:1
+  --> $DIR/feature-gate-abi.rs:24:8
    |
 LL | extern "efiapi" fn f10() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:28:5
+  --> $DIR/feature-gate-abi.rs:28:12
    |
 LL |     extern "rust-intrinsic" fn m1();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:30:5
+  --> $DIR/feature-gate-abi.rs:30:12
    |
 LL |     extern "platform-intrinsic" fn m2();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:32:5
+  --> $DIR/feature-gate-abi.rs:32:12
    |
 LL |     extern "vectorcall" fn m3();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:33:5
+  --> $DIR/feature-gate-abi.rs:33:12
    |
 LL |     extern "rust-call" fn m4();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:34:5
+  --> $DIR/feature-gate-abi.rs:34:12
    |
 LL |     extern "msp430-interrupt" fn m5();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:35:5
+  --> $DIR/feature-gate-abi.rs:35:12
    |
 LL |     extern "ptx-kernel" fn m6();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:36:5
+  --> $DIR/feature-gate-abi.rs:36:12
    |
 LL |     extern "x86-interrupt" fn m7();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:37:5
+  --> $DIR/feature-gate-abi.rs:37:12
    |
 LL |     extern "thiscall" fn m8();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:38:5
+  --> $DIR/feature-gate-abi.rs:38:12
    |
 LL |     extern "amdgpu-kernel" fn m9();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:39:5
+  --> $DIR/feature-gate-abi.rs:39:12
    |
 LL |     extern "efiapi" fn m10();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:41:5
+  --> $DIR/feature-gate-abi.rs:41:12
    |
 LL |     extern "vectorcall" fn dm3() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:42:5
+  --> $DIR/feature-gate-abi.rs:42:12
    |
 LL |     extern "rust-call" fn dm4() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:43:5
+  --> $DIR/feature-gate-abi.rs:43:12
    |
 LL |     extern "msp430-interrupt" fn dm5() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:44:5
+  --> $DIR/feature-gate-abi.rs:44:12
    |
 LL |     extern "ptx-kernel" fn dm6() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:45:5
+  --> $DIR/feature-gate-abi.rs:45:12
    |
 LL |     extern "x86-interrupt" fn dm7() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:46:5
+  --> $DIR/feature-gate-abi.rs:46:12
    |
 LL |     extern "thiscall" fn dm8() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:47:5
+  --> $DIR/feature-gate-abi.rs:47:12
    |
 LL |     extern "amdgpu-kernel" fn dm9() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:48:5
+  --> $DIR/feature-gate-abi.rs:48:12
    |
 LL |     extern "efiapi" fn dm10() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:55:5
+  --> $DIR/feature-gate-abi.rs:55:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:57:5
+  --> $DIR/feature-gate-abi.rs:57:12
    |
 LL |     extern "platform-intrinsic" fn m2() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:59:5
+  --> $DIR/feature-gate-abi.rs:59:12
    |
 LL |     extern "vectorcall" fn m3() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:60:5
+  --> $DIR/feature-gate-abi.rs:60:12
    |
 LL |     extern "rust-call" fn m4() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:61:5
+  --> $DIR/feature-gate-abi.rs:61:12
    |
 LL |     extern "msp430-interrupt" fn m5() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:62:5
+  --> $DIR/feature-gate-abi.rs:62:12
    |
 LL |     extern "ptx-kernel" fn m6() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:63:5
+  --> $DIR/feature-gate-abi.rs:63:12
    |
 LL |     extern "x86-interrupt" fn m7() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:64:5
+  --> $DIR/feature-gate-abi.rs:64:12
    |
 LL |     extern "thiscall" fn m8() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:65:5
+  --> $DIR/feature-gate-abi.rs:65:12
    |
 LL |     extern "amdgpu-kernel" fn m9() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:66:5
+  --> $DIR/feature-gate-abi.rs:66:12
    |
 LL |     extern "efiapi" fn m10() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:71:5
+  --> $DIR/feature-gate-abi.rs:71:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:73:5
+  --> $DIR/feature-gate-abi.rs:73:12
    |
 LL |     extern "platform-intrinsic" fn im2() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:75:5
+  --> $DIR/feature-gate-abi.rs:75:12
    |
 LL |     extern "vectorcall" fn im3() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:76:5
+  --> $DIR/feature-gate-abi.rs:76:12
    |
 LL |     extern "rust-call" fn im4() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:77:5
+  --> $DIR/feature-gate-abi.rs:77:12
    |
 LL |     extern "msp430-interrupt" fn im5() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:78:5
+  --> $DIR/feature-gate-abi.rs:78:12
    |
 LL |     extern "ptx-kernel" fn im6() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:79:5
+  --> $DIR/feature-gate-abi.rs:79:12
    |
 LL |     extern "x86-interrupt" fn im7() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:80:5
+  --> $DIR/feature-gate-abi.rs:80:12
    |
 LL |     extern "thiscall" fn im8() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:81:5
+  --> $DIR/feature-gate-abi.rs:81:12
    |
 LL |     extern "amdgpu-kernel" fn im9() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:82:5
+  --> $DIR/feature-gate-abi.rs:82:12
    |
 LL |     extern "efiapi" fn im10() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:86:11
+  --> $DIR/feature-gate-abi.rs:86:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:87:11
+  --> $DIR/feature-gate-abi.rs:87:18
    |
 LL | type A2 = extern "platform-intrinsic" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:88:11
+  --> $DIR/feature-gate-abi.rs:88:18
    |
 LL | type A3 = extern "vectorcall" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:89:11
+  --> $DIR/feature-gate-abi.rs:89:18
    |
 LL | type A4 = extern "rust-call" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:90:11
+  --> $DIR/feature-gate-abi.rs:90:18
    |
 LL | type A5 = extern "msp430-interrupt" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:91:11
+  --> $DIR/feature-gate-abi.rs:91:18
    |
 LL | type A6 = extern "ptx-kernel" fn ();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:92:11
+  --> $DIR/feature-gate-abi.rs:92:18
    |
 LL | type A7 = extern "x86-interrupt" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:93:11
+  --> $DIR/feature-gate-abi.rs:93:18
    |
 LL | type A8 = extern "thiscall" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:94:11
+  --> $DIR/feature-gate-abi.rs:94:18
    |
 LL | type A9 = extern "amdgpu-kernel" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:95:12
+  --> $DIR/feature-gate-abi.rs:95:19
    |
 LL | type A10 = extern "efiapi" fn();
-   |            ^^^^^^^^^^^^^^^^^^^^
+   |                   ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:98:1
+  --> $DIR/feature-gate-abi.rs:98:8
    |
 LL | extern "rust-intrinsic" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:99:1
+  --> $DIR/feature-gate-abi.rs:99:8
    |
 LL | extern "platform-intrinsic" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:100:1
+  --> $DIR/feature-gate-abi.rs:100:8
    |
 LL | extern "vectorcall" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:101:1
+  --> $DIR/feature-gate-abi.rs:101:8
    |
 LL | extern "rust-call" {}
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:102:1
+  --> $DIR/feature-gate-abi.rs:102:8
    |
 LL | extern "msp430-interrupt" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:103:1
+  --> $DIR/feature-gate-abi.rs:103:8
    |
 LL | extern "ptx-kernel" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:104:1
+  --> $DIR/feature-gate-abi.rs:104:8
    |
 LL | extern "x86-interrupt" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:105:1
+  --> $DIR/feature-gate-abi.rs:105:8
    |
 LL | extern "thiscall" {}
-   | ^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:106:1
+  --> $DIR/feature-gate-abi.rs:106:8
    |
 LL | extern "amdgpu-kernel" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:107:1
+  --> $DIR/feature-gate-abi.rs:107:8
    |
 LL | extern "efiapi" {}
-   | ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr
index 4954a7d1f71..1757befec35 100644
--- a/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr
@@ -1,10 +1,8 @@
 error[E0658]: unadjusted ABI is an implementation detail and perma-unstable
-  --> $DIR/feature-gate-abi_unadjusted.rs:1:1
+  --> $DIR/feature-gate-abi_unadjusted.rs:1:8
    |
-LL | / extern "unadjusted" fn foo() {
-LL | |
-LL | | }
-   | |_^
+LL | extern "unadjusted" fn foo() {
+   |        ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable
 
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
index e4c80141aa2..724e53debeb 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
@@ -1,8 +1,6 @@
 // This test ensures that attributes on formals in generic parameter
 // lists are included when we are checking for unstable attributes.
 
-// gate-test-custom_attribute
-
 struct StLt<#[lt_struct] 'a>(&'a u32);
 //~^ ERROR cannot find attribute `lt_struct` in this scope
 struct StTy<#[ty_struct] I>(I);
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
index bc89caddb44..b33710ce049 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
@@ -1,101 +1,101 @@
 error: cannot find attribute `lt_hof` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:53:21
+  --> $DIR/feature-gate-custom_attribute2.rs:51:21
    |
 LL |     where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
    |                     ^^^^^^
 
 error: cannot find attribute `ty_meth` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:48:15
+  --> $DIR/feature-gate-custom_attribute2.rs:46:15
    |
 LL |     fn m_ty<#[ty_meth] P>(_: P) { }
    |               ^^^^^^^
 
 error: cannot find attribute `lt_meth` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:46:15
+  --> $DIR/feature-gate-custom_attribute2.rs:44:15
    |
 LL |     fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
    |               ^^^^^^^
 
 error: cannot find attribute `ty_fn` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:42:11
+  --> $DIR/feature-gate-custom_attribute2.rs:40:11
    |
 LL | fn f_ty<#[ty_fn] O>(_: O) { }
    |           ^^^^^
 
 error: cannot find attribute `lt_fn` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:40:11
+  --> $DIR/feature-gate-custom_attribute2.rs:38:11
    |
 LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
    |           ^^^^^
 
 error: cannot find attribute `ty_impl_for` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:35:8
+  --> $DIR/feature-gate-custom_attribute2.rs:33:8
    |
 LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
    |        ^^^^^^^^^^^
 
 error: cannot find attribute `lt_impl_for` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:31:8
+  --> $DIR/feature-gate-custom_attribute2.rs:29:8
    |
 LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
    |        ^^^^^^^^^^^
 
 error: cannot find attribute `ty_inherent` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:28:8
+  --> $DIR/feature-gate-custom_attribute2.rs:26:8
    |
 LL | impl<#[ty_inherent] M> StTy<M> { }
    |        ^^^^^^^^^^^
 
 error: cannot find attribute `lt_inherent` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:26:8
+  --> $DIR/feature-gate-custom_attribute2.rs:24:8
    |
 LL | impl<#[lt_inherent] 'e> StLt<'e> { }
    |        ^^^^^^^^^^^
 
 error: cannot find attribute `ty_type` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:23:13
+  --> $DIR/feature-gate-custom_attribute2.rs:21:13
    |
 LL | type TyTy<#[ty_type] L> = (L, );
    |             ^^^^^^^
 
 error: cannot find attribute `lt_type` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:21:13
+  --> $DIR/feature-gate-custom_attribute2.rs:19:13
    |
 LL | type TyLt<#[lt_type] 'd> = &'d u32;
    |             ^^^^^^^
 
 error: cannot find attribute `ty_trait` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:18:14
+  --> $DIR/feature-gate-custom_attribute2.rs:16:14
    |
 LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
    |              ^^^^^^^^
 
 error: cannot find attribute `lt_trait` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:16:14
+  --> $DIR/feature-gate-custom_attribute2.rs:14:14
    |
 LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
    |              ^^^^^^^^
 
 error: cannot find attribute `ty_enum` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:13:13
+  --> $DIR/feature-gate-custom_attribute2.rs:11:13
    |
 LL | enum EnTy<#[ty_enum] J> { A(J), B }
    |             ^^^^^^^
 
 error: cannot find attribute `lt_enum` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:11:13
+  --> $DIR/feature-gate-custom_attribute2.rs:9:13
    |
 LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
    |             ^^^^^^^
 
 error: cannot find attribute `ty_struct` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:8:15
+  --> $DIR/feature-gate-custom_attribute2.rs:6:15
    |
 LL | struct StTy<#[ty_struct] I>(I);
    |               ^^^^^^^^^
 
 error: cannot find attribute `lt_struct` in this scope
-  --> $DIR/feature-gate-custom_attribute2.rs:6:15
+  --> $DIR/feature-gate-custom_attribute2.rs:4:15
    |
 LL | struct StLt<#[lt_struct] 'a>(&'a u32);
    |               ^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-extern_prelude.stderr b/src/test/ui/feature-gates/feature-gate-extern_prelude.stderr
index c15a8b33037..d72e47e9ed8 100644
--- a/src/test/ui/feature-gates/feature-gate-extern_prelude.stderr
+++ b/src/test/ui/feature-gates/feature-gate-extern_prelude.stderr
@@ -2,7 +2,7 @@ error: expected one of `!` or `::`, found `-`
   --> $DIR/feature-gate-extern_prelude.rs:1:4
    |
 LL | can-only-test-this-in-run-make-fulldeps
-   |    ^ expected one of `!` or `::` here
+   |    ^ expected one of `!` or `::`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
index 101a10e8df7..8f943d357ce 100644
--- a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
+++ b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
@@ -1,18 +1,16 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-intrinsics.rs:1:1
+  --> $DIR/feature-gate-intrinsics.rs:1:8
    |
-LL | / extern "rust-intrinsic" {
-LL | |     fn bar();
-LL | | }
-   | |_^
+LL | extern "rust-intrinsic" {
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-intrinsics.rs:5:1
+  --> $DIR/feature-gate-intrinsics.rs:5:8
    |
 LL | extern "rust-intrinsic" fn baz() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs b/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs
deleted file mode 100644
index bec1531c533..00000000000
--- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Test that `#[rustc_on_unimplemented]` is gated by `on_unimplemented` feature
-// gate.
-
-#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
-//~^ ERROR the `#[rustc_on_unimplemented]` attribute is an experimental feature
-trait Foo<Bar>
-{}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.rs b/src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.rs
deleted file mode 100644
index 505a45379cd..00000000000
--- a/src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Test that the use of the box syntax is gated by `re-rebalance-coherence` feature gate.
-
-// aux-build:re_rebalance_coherence_lib.rs
-
-extern crate re_rebalance_coherence_lib as lib;
-use lib::*;
-
-struct Oracle;
-impl Backend for Oracle {}
-impl<'a, T:'a, Tab> QueryFragment<Oracle> for BatchInsert<'a, T, Tab> {}
-//~^ ERROR E0210
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.stderr b/src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.stderr
deleted file mode 100644
index 504bfb56979..00000000000
--- a/src/test/ui/feature-gates/feature-gate-re-rebalance-coherence.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
-  --> $DIR/feature-gate-re-rebalance-coherence.rs:10:10
-   |
-LL | impl<'a, T:'a, Tab> QueryFragment<Oracle> for BatchInsert<'a, T, Tab> {}
-   |          ^ type parameter `T` must be used as the type parameter for some local type
-   |
-   = note: only traits defined in the current crate can be implemented for a type parameter
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/feature-gates/feature-gate-register_attr.rs b/src/test/ui/feature-gates/feature-gate-register_attr.rs
new file mode 100644
index 00000000000..36dce2aa7b9
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-register_attr.rs
@@ -0,0 +1,3 @@
+#![register_attr(attr)] //~ ERROR the `#[register_attr]` attribute is an experimental feature
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-register_attr.stderr b/src/test/ui/feature-gates/feature-gate-register_attr.stderr
new file mode 100644
index 00000000000..3965d481d9b
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-register_attr.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[register_attr]` attribute is an experimental feature
+  --> $DIR/feature-gate-register_attr.rs:1:1
+   |
+LL | #![register_attr(attr)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/66080
+   = help: add `#![feature(register_attr)]` 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-register_tool.rs b/src/test/ui/feature-gates/feature-gate-register_tool.rs
new file mode 100644
index 00000000000..e599593283b
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-register_tool.rs
@@ -0,0 +1,3 @@
+#![register_tool(tool)] //~ ERROR the `#[register_tool]` attribute is an experimental feature
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-register_tool.stderr b/src/test/ui/feature-gates/feature-gate-register_tool.stderr
new file mode 100644
index 00000000000..177342aed90
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-register_tool.stderr
@@ -0,0 +1,12 @@
+error[E0658]: the `#[register_tool]` attribute is an experimental feature
+  --> $DIR/feature-gate-register_tool.rs:1:1
+   |
+LL | #![register_tool(tool)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/66079
+   = help: add `#![feature(register_tool)]` 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-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index c05379c71ee..657bf13c873 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -1,35 +1,35 @@
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:12
    |
 LL |     extern "rust-call" fn call(self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:12
    |
 LL |     extern "rust-call" fn call_once(self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:12
    |
 LL |     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:12
    |
 LL |     extern "rust-call" fn call_once(&self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
index 723c6619887..f343a42eb8f 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
@@ -1,10 +1,8 @@
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures.rs:9:5
+  --> $DIR/feature-gate-unboxed-closures.rs:9:12
    |
-LL | /     extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
-LL | |         a + b
-LL | |     }
-   | |_____^
+LL |     extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
diff --git a/src/test/ui/generator/issue-53548-1.rs b/src/test/ui/generator/issue-53548-1.rs
index 395456ce7c6..173ae3c6fb6 100644
--- a/src/test/ui/generator/issue-53548-1.rs
+++ b/src/test/ui/generator/issue-53548-1.rs
@@ -2,7 +2,7 @@
 // but which encountered the same ICE/error. See `issue-53548.rs`
 // for details.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::cell::RefCell;
 use std::rc::Rc;
diff --git a/src/test/ui/generator/issue-53548.rs b/src/test/ui/generator/issue-53548.rs
index 8136c65923b..3ebabb91462 100644
--- a/src/test/ui/generator/issue-53548.rs
+++ b/src/test/ui/generator/issue-53548.rs
@@ -15,7 +15,7 @@
 // also analogous to what we would do for higher-ranked regions
 // appearing within the trait in other positions).
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(generators)]
 
diff --git a/src/test/ui/hygiene/dollar-crate-modern.rs b/src/test/ui/hygiene/dollar-crate-modern.rs
index a432fb6eee1..eb176fed87c 100644
--- a/src/test/ui/hygiene/dollar-crate-modern.rs
+++ b/src/test/ui/hygiene/dollar-crate-modern.rs
@@ -3,7 +3,7 @@
 // check-pass
 // aux-build:intercrate.rs
 
-#![feature(decl_macro, crate_in_paths)]
+#![feature(decl_macro)]
 
 extern crate intercrate;
 
diff --git a/src/test/ui/hygiene/dollar-crate-modern.stderr b/src/test/ui/hygiene/dollar-crate-modern.stderr
deleted file mode 100644
index cd40df16ba7..00000000000
--- a/src/test/ui/hygiene/dollar-crate-modern.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: the feature `crate_in_paths` has been stable since 1.30.0 and no longer requires an attribute to enable
-  --> $DIR/dollar-crate-modern.rs:6:24
-   |
-LL | #![feature(decl_macro, crate_in_paths)]
-   |                        ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(stable_features)]` on by default
-
diff --git a/src/test/ui/hygiene/generic_params.rs b/src/test/ui/hygiene/generic_params.rs
index 9dc5adfce47..d319ae6403f 100644
--- a/src/test/ui/hygiene/generic_params.rs
+++ b/src/test/ui/hygiene/generic_params.rs
@@ -4,6 +4,7 @@
 // ignore-pretty pretty-printing is unhygienic
 
 #![feature(decl_macro, rustc_attrs, const_generics)]
+//~^ WARNING the feature `const_generics` is incomplete
 
 mod type_params {
     macro m($T:ident) {
diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.rs b/src/test/ui/hygiene/hygienic-labels-in-let.rs
index fb9523b547d..5d22cf857b7 100644
--- a/src/test/ui/hygiene/hygienic-labels-in-let.rs
+++ b/src/test/ui/hygiene/hygienic-labels-in-let.rs
@@ -13,6 +13,10 @@ macro_rules! loop_x {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
         'x: loop { $e }
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
     }
 }
 
@@ -20,6 +24,11 @@ macro_rules! while_true {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
         'x: while 1 + 1 == 2 { $e }
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
     }
 }
 
@@ -27,6 +36,13 @@ macro_rules! run_once {
     ($e: expr) => {
         // ditto
         'x: for _ in 0..1 { $e }
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
     }
 }
 
@@ -45,6 +61,8 @@ pub fn main() {
 
     let k: isize = {
         'x: for _ in 0..1 {
+            //~^ WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
             // ditto
             loop_x!(break 'x);
             i += 1;
@@ -55,6 +73,10 @@ pub fn main() {
 
     let l: isize = {
         'x: for _ in 0..1 {
+            //~^ WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
             // ditto
             while_true!(break 'x);
             i += 1;
@@ -65,6 +87,12 @@ pub fn main() {
 
     let n: isize = {
         'x: for _ in 0..1 {
+            //~^ WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
+            //~| WARNING shadows a label name that is already in scope
             // ditto
             run_once!(continue 'x);
             i += 1;
diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.stderr b/src/test/ui/hygiene/hygienic-labels-in-let.stderr
index 9c906749f8c..d88470f32a3 100644
--- a/src/test/ui/hygiene/hygienic-labels-in-let.stderr
+++ b/src/test/ui/hygiene/hygienic-labels-in-let.stderr
@@ -11,7 +11,7 @@ LL |             loop_x!(break 'x);
    |             ------------------ in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:47:9
+  --> $DIR/hygienic-labels-in-let.rs:63:9
    |
 LL |         'x: loop {
    |         -- first declared here
@@ -20,7 +20,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:47:9
+  --> $DIR/hygienic-labels-in-let.rs:63:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -60,12 +60,12 @@ LL |         'x: loop { $e }
 ...
 LL |         'x: for _ in 0..1 {
    |         -- first declared here
-LL |             // ditto
+...
 LL |             loop_x!(break 'x);
    |             ------------------ in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:57:9
+  --> $DIR/hygienic-labels-in-let.rs:75:9
    |
 LL |         'x: loop {
    |         -- first declared here
@@ -74,7 +74,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:57:9
+  --> $DIR/hygienic-labels-in-let.rs:75:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -83,7 +83,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:57:9
+  --> $DIR/hygienic-labels-in-let.rs:75:9
    |
 LL |         'x: for _ in 0..1 {
    |         -- first declared here
@@ -92,7 +92,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:57:9
+  --> $DIR/hygienic-labels-in-let.rs:75:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -101,7 +101,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:22:9
+  --> $DIR/hygienic-labels-in-let.rs:26:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         ^^ lifetime 'x already in scope
@@ -113,7 +113,7 @@ LL |             while_true!(break 'x);
    |             ---------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:22:9
+  --> $DIR/hygienic-labels-in-let.rs:26:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -125,7 +125,7 @@ LL |             while_true!(break 'x);
    |             ---------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:22:9
+  --> $DIR/hygienic-labels-in-let.rs:26:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         ^^ lifetime 'x already in scope
@@ -137,7 +137,7 @@ LL |             while_true!(break 'x);
    |             ---------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:22:9
+  --> $DIR/hygienic-labels-in-let.rs:26:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -149,19 +149,19 @@ LL |             while_true!(break 'x);
    |             ---------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:22:9
+  --> $DIR/hygienic-labels-in-let.rs:26:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         ^^ lifetime 'x already in scope
 ...
 LL |         'x: for _ in 0..1 {
    |         -- first declared here
-LL |             // ditto
+...
 LL |             while_true!(break 'x);
    |             ---------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:67:9
+  --> $DIR/hygienic-labels-in-let.rs:89:9
    |
 LL |         'x: loop {
    |         -- first declared here
@@ -170,7 +170,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:67:9
+  --> $DIR/hygienic-labels-in-let.rs:89:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -179,7 +179,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:67:9
+  --> $DIR/hygienic-labels-in-let.rs:89:9
    |
 LL |         'x: for _ in 0..1 {
    |         -- first declared here
@@ -188,7 +188,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:67:9
+  --> $DIR/hygienic-labels-in-let.rs:89:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -197,7 +197,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:67:9
+  --> $DIR/hygienic-labels-in-let.rs:89:9
    |
 LL |         'x: for _ in 0..1 {
    |         -- first declared here
@@ -206,7 +206,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:67:9
+  --> $DIR/hygienic-labels-in-let.rs:89:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         -- first declared here
@@ -215,7 +215,7 @@ LL |         'x: for _ in 0..1 {
    |         ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -227,7 +227,7 @@ LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -239,7 +239,7 @@ LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -251,7 +251,7 @@ LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -263,7 +263,7 @@ LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -275,7 +275,7 @@ LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         -- first declared here
@@ -287,14 +287,14 @@ LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels-in-let.rs:29:9
+  --> $DIR/hygienic-labels-in-let.rs:38:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
 ...
 LL |         'x: for _ in 0..1 {
    |         -- first declared here
-LL |             // ditto
+...
 LL |             run_once!(continue 'x);
    |             ----------------------- in this macro invocation
 
diff --git a/src/test/ui/hygiene/hygienic-labels.rs b/src/test/ui/hygiene/hygienic-labels.rs
index a364dd9c887..8eafb4c8d21 100644
--- a/src/test/ui/hygiene/hygienic-labels.rs
+++ b/src/test/ui/hygiene/hygienic-labels.rs
@@ -10,6 +10,10 @@ macro_rules! loop_x {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
         'x: loop { $e }
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
     }
 }
 
@@ -17,6 +21,13 @@ macro_rules! run_once {
     ($e: expr) => {
         // ditto
         'x: for _ in 0..1 { $e }
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
     }
 }
 
@@ -24,6 +35,11 @@ macro_rules! while_x {
     ($e: expr) => {
         // ditto
         'x: while 1 + 1 == 2 { $e }
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
     }
 }
 
@@ -35,17 +51,32 @@ pub fn main() {
     }
 
     'x: loop {
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+
         // ditto
         loop_x!(break 'x);
         panic!("break doesn't act hygienically inside infinite loop");
     }
 
     'x: while 1 + 1 == 2 {
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+
         while_x!(break 'x);
         panic!("break doesn't act hygienically inside infinite while loop");
     }
 
     'x: for _ in 0..1 {
+        //~^ WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+        //~| WARNING shadows a label name that is already in scope
+
         // ditto
         run_once!(continue 'x);
         panic!("continue doesn't act hygienically inside for loop");
diff --git a/src/test/ui/hygiene/hygienic-labels.stderr b/src/test/ui/hygiene/hygienic-labels.stderr
index d88dfce540e..285e9037e97 100644
--- a/src/test/ui/hygiene/hygienic-labels.stderr
+++ b/src/test/ui/hygiene/hygienic-labels.stderr
@@ -11,7 +11,7 @@ LL |         loop_x!(break 'x);
    |         ------------------ in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:37:5
+  --> $DIR/hygienic-labels.rs:53:5
    |
 LL |     'x: for _ in 0..1 {
    |     -- first declared here
@@ -20,7 +20,7 @@ LL |     'x: loop {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:37:5
+  --> $DIR/hygienic-labels.rs:53:5
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -60,12 +60,12 @@ LL |         'x: loop { $e }
 ...
 LL |     'x: loop {
    |     -- first declared here
-LL |         // ditto
+...
 LL |         loop_x!(break 'x);
    |         ------------------ in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:43:5
+  --> $DIR/hygienic-labels.rs:62:5
    |
 LL |     'x: for _ in 0..1 {
    |     -- first declared here
@@ -74,7 +74,7 @@ LL |     'x: while 1 + 1 == 2 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:43:5
+  --> $DIR/hygienic-labels.rs:62:5
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -83,7 +83,7 @@ LL |     'x: while 1 + 1 == 2 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:43:5
+  --> $DIR/hygienic-labels.rs:62:5
    |
 LL |     'x: loop {
    |     -- first declared here
@@ -92,7 +92,7 @@ LL |     'x: while 1 + 1 == 2 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:43:5
+  --> $DIR/hygienic-labels.rs:62:5
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -101,7 +101,7 @@ LL |     'x: while 1 + 1 == 2 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:26:9
+  --> $DIR/hygienic-labels.rs:37:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         ^^ lifetime 'x already in scope
@@ -113,7 +113,7 @@ LL |         while_x!(break 'x);
    |         ------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:26:9
+  --> $DIR/hygienic-labels.rs:37:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -125,7 +125,7 @@ LL |         while_x!(break 'x);
    |         ------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:26:9
+  --> $DIR/hygienic-labels.rs:37:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         ^^ lifetime 'x already in scope
@@ -137,7 +137,7 @@ LL |         while_x!(break 'x);
    |         ------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:26:9
+  --> $DIR/hygienic-labels.rs:37:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -149,18 +149,19 @@ LL |         while_x!(break 'x);
    |         ------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:26:9
+  --> $DIR/hygienic-labels.rs:37:9
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         ^^ lifetime 'x already in scope
 ...
 LL |     'x: while 1 + 1 == 2 {
    |     -- first declared here
+...
 LL |         while_x!(break 'x);
    |         ------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:48:5
+  --> $DIR/hygienic-labels.rs:72:5
    |
 LL |     'x: for _ in 0..1 {
    |     -- first declared here
@@ -169,7 +170,7 @@ LL |     'x: for _ in 0..1 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:48:5
+  --> $DIR/hygienic-labels.rs:72:5
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -178,7 +179,7 @@ LL |     'x: for _ in 0..1 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:48:5
+  --> $DIR/hygienic-labels.rs:72:5
    |
 LL |     'x: loop {
    |     -- first declared here
@@ -187,7 +188,7 @@ LL |     'x: for _ in 0..1 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:48:5
+  --> $DIR/hygienic-labels.rs:72:5
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -196,7 +197,7 @@ LL |     'x: for _ in 0..1 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:48:5
+  --> $DIR/hygienic-labels.rs:72:5
    |
 LL |     'x: while 1 + 1 == 2 {
    |     -- first declared here
@@ -205,7 +206,7 @@ LL |     'x: for _ in 0..1 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:48:5
+  --> $DIR/hygienic-labels.rs:72:5
    |
 LL |         'x: while 1 + 1 == 2 { $e }
    |         -- first declared here
@@ -214,7 +215,7 @@ LL |     'x: for _ in 0..1 {
    |     ^^ lifetime 'x already in scope
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -226,7 +227,7 @@ LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -238,7 +239,7 @@ LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -250,7 +251,7 @@ LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: loop { $e }
    |         -- first declared here
@@ -262,7 +263,7 @@ LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -274,7 +275,7 @@ LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
@@ -286,14 +287,14 @@ LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
 warning: label name `'x` shadows a label name that is already in scope
-  --> $DIR/hygienic-labels.rs:19:9
+  --> $DIR/hygienic-labels.rs:23:9
    |
 LL |         'x: for _ in 0..1 { $e }
    |         ^^ lifetime 'x already in scope
 ...
 LL |     'x: for _ in 0..1 {
    |     -- first declared here
-LL |         // ditto
+...
 LL |         run_once!(continue 'x);
    |         ----------------------- in this macro invocation
 
diff --git a/src/test/ui/hygiene/issue-61574-const-parameters.rs b/src/test/ui/hygiene/issue-61574-const-parameters.rs
index dcfb42287d5..81e9b1b36e0 100644
--- a/src/test/ui/hygiene/issue-61574-const-parameters.rs
+++ b/src/test/ui/hygiene/issue-61574-const-parameters.rs
@@ -3,7 +3,7 @@
 
 // check-pass
 
-#![feature(const_generics)]
+#![feature(const_generics)] //~ WARNING `const_generics` is incomplete
 
 use std::ops::Add;
 
diff --git a/src/test/ui/if-ret.rs b/src/test/ui/if-ret.rs
index e1e795d83be..6bb0141848a 100644
--- a/src/test/ui/if-ret.rs
+++ b/src/test/ui/if-ret.rs
@@ -3,6 +3,6 @@
 #![allow(unused_parens)]
 // pretty-expanded FIXME #23616
 
-fn foo() { if (return) { } }
+fn foo() { if (return) { } } //~ WARNING unreachable block in `if` expression
 
 pub fn main() { foo(); }
diff --git a/src/test/ui/if/ifmt-bad-arg.rs b/src/test/ui/if/ifmt-bad-arg.rs
index ba897f171af..a0b0a8fb985 100644
--- a/src/test/ui/if/ifmt-bad-arg.rs
+++ b/src/test/ui/if/ifmt-bad-arg.rs
@@ -86,4 +86,9 @@ tenth number: {}",
     println!("{:foo}", 1); //~ ERROR unknown format trait `foo`
     println!("{5} {:4$} {6:7$}", 1);
     //~^ ERROR invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument)
+
+    // We used to ICE here because we tried to unconditionally access the first argument, which
+    // doesn't exist.
+    println!("{:.*}");
+    //~^ ERROR 2 positional arguments in format string, but no arguments were given
 }
diff --git a/src/test/ui/if/ifmt-bad-arg.stderr b/src/test/ui/if/ifmt-bad-arg.stderr
index c58cbc31233..d65ffd85060 100644
--- a/src/test/ui/if/ifmt-bad-arg.stderr
+++ b/src/test/ui/if/ifmt-bad-arg.stderr
@@ -257,10 +257,10 @@ LL |     println!("{} {:07$} {}", 1, 3.2, 4);
    = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
 
 error: unknown format trait `foo`
-  --> $DIR/ifmt-bad-arg.rs:86:24
+  --> $DIR/ifmt-bad-arg.rs:86:17
    |
 LL |     println!("{:foo}", 1);
-   |                        ^
+   |                 ^^^
    |
    = note: the only appropriate formatting traits are:
            - ``, which uses the `Display` trait
@@ -285,6 +285,17 @@ LL |     println!("{5} {:4$} {6:7$}", 1);
    = note: positional arguments are zero-based
    = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
 
+error: 2 positional arguments in format string, but no arguments were given
+  --> $DIR/ifmt-bad-arg.rs:92:15
+   |
+LL |     println!("{:.*}");
+   |               ^^--^
+   |                 |
+   |                 this precision flag adds an extra required argument at position 0, which is why there are 2 arguments expected
+   |
+   = note: positional arguments are zero-based
+   = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
+
 error[E0308]: mismatched types
   --> $DIR/ifmt-bad-arg.rs:78:32
    |
@@ -303,6 +314,6 @@ LL |     println!("{} {:07$.*} {}", 1, 3.2, 4);
    = note: expected type `&usize`
               found type `&{float}`
 
-error: aborting due to 35 previous errors
+error: aborting due to 36 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/if/ifmt-unknown-trait.stderr b/src/test/ui/if/ifmt-unknown-trait.stderr
index 7853b5ca0c9..459432bf4e4 100644
--- a/src/test/ui/if/ifmt-unknown-trait.stderr
+++ b/src/test/ui/if/ifmt-unknown-trait.stderr
@@ -1,8 +1,8 @@
 error: unknown format trait `notimplemented`
-  --> $DIR/ifmt-unknown-trait.rs:2:34
+  --> $DIR/ifmt-unknown-trait.rs:2:16
    |
 LL |     format!("{:notimplemented}", "3");
-   |                                  ^^^
+   |                ^^^^^^^^^^^^^^
    |
    = note: the only appropriate formatting traits are:
            - ``, which uses the `Display` trait
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
index e4d0a731ebf..7cb4677a2b1 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
@@ -5,7 +5,9 @@ LL |     fn foo<A: Debug>(&self, a: &A, b: &impl Debug);
    |                                -- type in trait
 ...
 LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
-   |                                ^^^^^^^^^^^ expected type parameter, found a different type parameter
+   |            -                   ^^^^^^^^^^^ expected type parameter `B`, found type parameter `impl Debug`
+   |            |
+   |            expected type parameter
    |
    = note: expected type `fn(&(), &B, &impl Debug)`
               found type `fn(&(), &impl Debug, &B)`
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.rs b/src/test/ui/impl-trait/impl-generic-mismatch.rs
index f4fba4c34c1..5597df4ba49 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.rs
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.rs
@@ -1,5 +1,4 @@
-// ignore-musl
-// ignore-x86
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 
 use std::fmt::Debug;
 
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.stderr b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
index bfe94119a02..2278519e95a 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0643]: method `foo` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:11:12
+  --> $DIR/impl-generic-mismatch.rs:10:12
    |
 LL |     fn foo(&self, _: &impl Debug);
    |                       ---------- declaration in trait here
@@ -13,7 +13,7 @@ LL |     fn foo(&self, _: &impl Debug) { }
    |          --           ^^^^^^^^^^
 
 error[E0643]: method `bar` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:20:23
+  --> $DIR/impl-generic-mismatch.rs:19:23
    |
 LL |     fn bar<U: Debug>(&self, _: &U);
    |            - declaration in trait here
@@ -27,7 +27,7 @@ LL |     fn bar<U: Debug>(&self, _: &U) { }
    |           ^^^^^^^^^^            ^
 
 error[E0643]: method `hash` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:31:33
+  --> $DIR/impl-generic-mismatch.rs:30:33
    |
 LL |     fn hash(&self, hasher: &mut impl Hasher) {}
    |                                 ^^^^^^^^^^^ expected generic parameter, found `impl Trait`
diff --git a/src/test/ui/impl-trait/issues/issue-42479.rs b/src/test/ui/impl-trait/issues/issue-42479.rs
index 7d69cd0a303..efc1f975d16 100644
--- a/src/test/ui/impl-trait/issues/issue-42479.rs
+++ b/src/test/ui/impl-trait/issues/issue-42479.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::iter::once;
 
diff --git a/src/test/ui/impl-trait/issues/issue-49376.rs b/src/test/ui/impl-trait/issues/issue-49376.rs
index 12e69b16adf..e4472fcc160 100644
--- a/src/test/ui/impl-trait/issues/issue-49376.rs
+++ b/src/test/ui/impl-trait/issues/issue-49376.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Tests for nested self-reference which caused a stack overflow.
 
diff --git a/src/test/ui/impl-trait/issues/issue-52128.rs b/src/test/ui/impl-trait/issues/issue-52128.rs
index ac26c10e55d..5afd380dd4f 100644
--- a/src/test/ui/impl-trait/issues/issue-52128.rs
+++ b/src/test/ui/impl-trait/issues/issue-52128.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![deny(warnings)]
 
diff --git a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
index 0c07101bb7b..0c34c97e258 100644
--- a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
+++ b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
@@ -1,7 +1,7 @@
 // This used to ICE because it creates an `impl Trait` that captures a
 // hidden empty region.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn server() -> impl FilterBase2 {
     segment2(|| { loop { } }).map2(|| "")
diff --git a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
index ed066ce1924..c4f738a34b6 100644
--- a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
+++ b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
@@ -5,7 +5,7 @@
 // opaque type. As all regions are now required to outlive the bound in an
 // opaque type we avoid the issue here.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct A<F>(F);
 
diff --git a/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs b/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs
index 5eef6a39325..0daec3305c0 100644
--- a/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs
+++ b/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs
@@ -1,42 +1,17 @@
 // rust-lang/rust#57979 : the initial support for `impl Trait` didn't
 // properly check syntax hidden behind an associated type projection,
 // but it did catch *some cases*. This is checking that we continue to
-// properly emit errors for those, even with the new
-// future-incompatibility warnings.
+// properly emit errors for those.
 //
 // issue-57979-nested-impl-trait-in-assoc-proj.rs shows the main case
 // that we were previously failing to catch.
 
 struct Deeper<T>(T);
 
-mod allowed {
-    #![allow(nested_impl_trait)]
-
-    pub trait Foo<T> { }
-    pub trait Bar { }
-    pub trait Quux { type Assoc; }
-    pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
-    //~^ ERROR nested `impl Trait` is not allowed
-}
-
-mod warned {
-    #![warn(nested_impl_trait)]
-
-    pub trait Foo<T> { }
-    pub trait Bar { }
-    pub trait Quux { type Assoc; }
-    pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
-    //~^ ERROR nested `impl Trait` is not allowed
-}
-
-mod denied {
-    #![deny(nested_impl_trait)]
-
-    pub trait Foo<T> { }
-    pub trait Bar { }
-    pub trait Quux { type Assoc; }
-    pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
-    //~^ ERROR nested `impl Trait` is not allowed
-}
+pub trait Foo<T> { }
+pub trait Bar { }
+pub trait Quux { type Assoc; }
+pub fn demo(_: impl Quux<Assoc=Deeper<impl Foo<impl Bar>>>) { }
+//~^ ERROR nested `impl Trait` is not allowed
 
 fn main() { }
diff --git a/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr b/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr
index 2b6f15e6d3e..6bebbc01f3d 100644
--- a/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr
+++ b/src/test/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr
@@ -1,30 +1,12 @@
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:18:59
+  --> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:14:48
    |
-LL |     pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
-   |                                                  ---------^^^^^^^^-
-   |                                                  |        |
-   |                                                  |        nested `impl Trait` here
-   |                                                  outer `impl Trait`
+LL | pub fn demo(_: impl Quux<Assoc=Deeper<impl Foo<impl Bar>>>) { }
+   |                                       ---------^^^^^^^^-
+   |                                       |        |
+   |                                       |        nested `impl Trait` here
+   |                                       outer `impl Trait`
 
-error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:28:59
-   |
-LL |     pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
-   |                                                  ---------^^^^^^^^-
-   |                                                  |        |
-   |                                                  |        nested `impl Trait` here
-   |                                                  outer `impl Trait`
-
-error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:38:59
-   |
-LL |     pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
-   |                                                  ---------^^^^^^^^-
-   |                                                  |        |
-   |                                                  |        nested `impl Trait` here
-   |                                                  outer `impl Trait`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0666`.
diff --git a/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs b/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs
index 84fcb5e2880..c5ecd1caae1 100644
--- a/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs
+++ b/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs
@@ -3,35 +3,10 @@
 // Here we test behavior of occurrences of `impl Trait` within a path
 // component in that context.
 
-mod allowed {
-    #![allow(nested_impl_trait)]
-
-    pub trait Bar { }
-    pub trait Quux<T> { type Assoc; }
-    pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
-    impl<T> Quux<T> for () { type Assoc = u32; }
-}
-
-mod warned {
-    #![warn(nested_impl_trait)]
-
-    pub trait Bar { }
-    pub trait Quux<T> { type Assoc; }
-    pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
-    //~^ WARN `impl Trait` is not allowed in path parameters
-    //~| WARN will become a hard error in a future release!
-    impl<T> Quux<T> for () { type Assoc = u32; }
-}
-
-mod denied {
-    #![deny(nested_impl_trait)]
-
-    pub trait Bar { }
-    pub trait Quux<T> { type Assoc; }
-    pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
-    //~^ ERROR `impl Trait` is not allowed in path parameters
-    //~| WARN will become a hard error in a future release!
-    impl<T> Quux<T> for () { type Assoc = u32; }
-}
+pub trait Bar { }
+pub trait Quux<T> { type Assoc; }
+pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
+//~^ ERROR `impl Trait` is not allowed in path parameters
+impl<T> Quux<T> for () { type Assoc = u32; }
 
 fn main() { }
diff --git a/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr b/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr
index 982ecba291f..f64545d83b8 100644
--- a/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr
+++ b/src/test/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr
@@ -1,30 +1,8 @@
-warning: `impl Trait` is not allowed in path parameters
-  --> $DIR/issue-57979-impl-trait-in-path.rs:20:52
+error[E0667]: `impl Trait` is not allowed in path parameters
+  --> $DIR/issue-57979-impl-trait-in-path.rs:8:48
    |
-LL |     pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
-   |                                                    ^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/issue-57979-impl-trait-in-path.rs:16:13
-   |
-LL |     #![warn(nested_impl_trait)]
-   |             ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
-
-error: `impl Trait` is not allowed in path parameters
-  --> $DIR/issue-57979-impl-trait-in-path.rs:31:52
-   |
-LL |     pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
-   |                                                    ^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/issue-57979-impl-trait-in-path.rs:27:13
-   |
-LL |     #![deny(nested_impl_trait)]
-   |             ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
+LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
+   |                                                ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs b/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs
index 5c20ffc7c67..5a444d3dfdd 100644
--- a/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs
+++ b/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs
@@ -3,35 +3,10 @@
 // Here we test behavior of occurrences of `impl Trait` within an
 // `impl Trait` in that context.
 
-mod allowed {
-    #![allow(nested_impl_trait)]
-
-    pub trait Foo<T> { }
-    pub trait Bar { }
-    pub trait Quux { type Assoc; }
-    pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
-}
-
-mod warned {
-    #![warn(nested_impl_trait)]
-
-    pub trait Foo<T> { }
-    pub trait Bar { }
-    pub trait Quux { type Assoc; }
-    pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
-    //~^ WARN nested `impl Trait` is not allowed
-    //~| WARN will become a hard error in a future release!
-}
-
-mod denied {
-    #![deny(nested_impl_trait)]
-
-    pub trait Foo<T> { }
-    pub trait Bar { }
-    pub trait Quux { type Assoc; }
-    pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
-    //~^ ERROR nested `impl Trait` is not allowed
-    //~| WARN will become a hard error in a future release!
-}
+pub trait Foo<T> { }
+pub trait Bar { }
+pub trait Quux { type Assoc; }
+pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
+//~^ ERROR nested `impl Trait` is not allowed
 
 fn main() { }
diff --git a/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr b/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr
index 508aea24321..8d3d4b5e206 100644
--- a/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr
+++ b/src/test/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr
@@ -1,36 +1,12 @@
-warning: nested `impl Trait` is not allowed
-  --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:21:45
-   |
-LL |     pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
-   |                                    ---------^^^^^^^^-
-   |                                    |        |
-   |                                    |        nested `impl Trait` here
-   |                                    outer `impl Trait`
-   |
-note: lint level defined here
-  --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:16:13
-   |
-LL |     #![warn(nested_impl_trait)]
-   |             ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
-
-error: nested `impl Trait` is not allowed
-  --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:32:45
-   |
-LL |     pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
-   |                                    ---------^^^^^^^^-
-   |                                    |        |
-   |                                    |        nested `impl Trait` here
-   |                                    outer `impl Trait`
-   |
-note: lint level defined here
-  --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:27:13
-   |
-LL |     #![deny(nested_impl_trait)]
-   |             ^^^^^^^^^^^^^^^^^
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
+error[E0666]: nested `impl Trait` is not allowed
+  --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:9:41
+   |
+LL | pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
+   |                                ---------^^^^^^^^-
+   |                                |        |
+   |                                |        nested `impl Trait` here
+   |                                outer `impl Trait`
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0666`.
diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr
index 129d7ef5783..151dc681621 100644
--- a/src/test/ui/impl-trait/trait_type.stderr
+++ b/src/test/ui/impl-trait/trait_type.stderr
@@ -29,7 +29,7 @@ error[E0046]: not all trait items implemented, missing: `fmt`
 LL | impl std::fmt::Display for MyType4 {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
    |
-   = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+   = help: implement the missing item: `fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { unimplemented!() }`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr
index d92c3f034e5..ae20a5aa883 100644
--- a/src/test/ui/impl-trait/universal-mismatched-type.stderr
+++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr
@@ -2,9 +2,11 @@ error[E0308]: mismatched types
   --> $DIR/universal-mismatched-type.rs:4:5
    |
 LL | fn foo(x: impl Debug) -> String {
-   |                          ------ expected `std::string::String` because of return type
+   |           ----------     ------ expected `std::string::String` because of return type
+   |           |
+   |           this type parameter
 LL |     x
-   |     ^ expected struct `std::string::String`, found type parameter
+   |     ^ expected struct `std::string::String`, found type parameter `impl Debug`
    |
    = note: expected type `std::string::String`
               found type `impl Debug`
diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
index 98a70f268cf..f540d319a27 100644
--- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr
+++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
@@ -1,11 +1,16 @@
 error[E0308]: mismatched types
   --> $DIR/universal-two-impl-traits.rs:5:9
    |
+LL | fn foo(x: impl Debug, y: impl Debug) -> String {
+   |           ----------     ---------- found type parameter
+   |           |
+   |           expected type parameter
+LL |     let mut a = x;
 LL |     a = y;
-   |         ^ expected type parameter, found a different type parameter
+   |         ^ expected type parameter `impl Debug`, found a different type parameter `impl Debug`
    |
-   = note: expected type `impl Debug` (type parameter)
-              found type `impl Debug` (type parameter)
+   = note: expected type `impl Debug` (type parameter `impl Debug`)
+              found type `impl Debug` (type parameter `impl Debug`)
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
index ce8c2d5168f..abcc92ce34d 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // aux-build:two_macros.rs
 
 macro_rules! define_vec {
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
index 8e01fc8df3d..7a55abe4255 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
@@ -1,5 +1,5 @@
 error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:21:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:20:9
    |
 LL |         extern crate std as core;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,13 +8,13 @@ LL | define_other_core!();
    | --------------------- in this macro invocation
 
 error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:14:9
    |
 LL |         Vec::panic!();
    |         ^^^ ambiguous name
    |
 note: `Vec` could refer to the crate imported here
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:6:9
    |
 LL |         extern crate std as Vec;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/imports/import-prefix-macro-1.stderr b/src/test/ui/imports/import-prefix-macro-1.stderr
index 577f1282471..6c12a366b71 100644
--- a/src/test/ui/imports/import-prefix-macro-1.stderr
+++ b/src/test/ui/imports/import-prefix-macro-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `::`, `;`, or `as`, found `{`
   --> $DIR/import-prefix-macro-1.rs:11:27
    |
 LL |     ($p: path) => (use $p {S, Z});
-   |                           ^ expected one of `::`, `;`, or `as` here
+   |                           ^^^^^^ expected one of `::`, `;`, or `as`
 ...
 LL | import! { a::b::c }
    | ------------------- in this macro invocation
diff --git a/src/test/ui/imports/issue-53140.rs b/src/test/ui/imports/issue-53140.rs
index 1854ddf96b8..7b4cc176806 100644
--- a/src/test/ui/imports/issue-53140.rs
+++ b/src/test/ui/imports/issue-53140.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 mod m {
     pub struct S(u8);
diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs
index 8cb602d868c..2df328cca89 100644
--- a/src/test/ui/imports/issue-55811.rs
+++ b/src/test/ui/imports/issue-55811.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // aux-build:issue-55811.rs
 
 extern crate issue_55811;
diff --git a/src/test/ui/imports/issue-56263.rs b/src/test/ui/imports/issue-56263.rs
index 4763ae4be99..363781f2daf 100644
--- a/src/test/ui/imports/issue-56263.rs
+++ b/src/test/ui/imports/issue-56263.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 use ::std;
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
index eca9a67fcb3..369de040070 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::ops::Deref;
 trait Trait {}
 
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
index d3862e3d4df..8086d3f1fbc 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
@@ -1,5 +1,5 @@
 error: `impl` item signature doesn't match `trait` item signature
-  --> $DIR/mismatched_trait_impl-2.rs:10:5
+  --> $DIR/mismatched_trait_impl-2.rs:9:5
    |
 LL |     fn deref(&self) -> &dyn Trait {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait
diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs
index a90b268db8c..1d508e8e820 100644
--- a/src/test/ui/inference/inference-variable-behind-raw-pointer.rs
+++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // tests that the following code compiles, but produces a future-compatibility warning
 
@@ -6,4 +6,6 @@ fn main() {
     let data = std::ptr::null();
     let _ = &data as *const *const ();
     if data.is_null() {}
+    //~^ WARNING type annotations needed
+    //~| WARNING this was previously accepted by the compiler but is being phased out
 }
diff --git a/src/test/ui/interior-mutability/interior-mutability.rs b/src/test/ui/interior-mutability/interior-mutability.rs
index 6968e3669ca..60633fdd393 100644
--- a/src/test/ui/interior-mutability/interior-mutability.rs
+++ b/src/test/ui/interior-mutability/interior-mutability.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::cell::Cell;
 use std::panic::catch_unwind;
 fn main() {
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index b76fce28805..5c129524f51 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
-  --> $DIR/interior-mutability.rs:7:5
+  --> $DIR/interior-mutability.rs:6:5
    |
 LL |     catch_unwind(|| { x.set(23); });
    |     ^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -12,7 +12,7 @@ LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
    = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<i32>`
-   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:7:18: 7:35 x:&std::cell::Cell<i32>]`
+   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:6:18: 6:35 x:&std::cell::Cell<i32>]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/invalid/invalid-variadic-function.stderr b/src/test/ui/invalid/invalid-variadic-function.stderr
index fd20bd84edc..7e58b17e7db 100644
--- a/src/test/ui/invalid/invalid-variadic-function.stderr
+++ b/src/test/ui/invalid/invalid-variadic-function.stderr
@@ -8,7 +8,7 @@ error: expected one of `->`, `where`, or `{`, found `;`
   --> $DIR/invalid-variadic-function.rs:1:30
    |
 LL | extern "C" fn foo(x: u8, ...);
-   |                              ^ expected one of `->`, `where`, or `{` here
+   |                              ^ expected one of `->`, `where`, or `{`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/auxiliary/issue-38715-modern.rs b/src/test/ui/issues/auxiliary/issue-38715-modern.rs
deleted file mode 100644
index 15d072957cb..00000000000
--- a/src/test/ui/issues/auxiliary/issue-38715-modern.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#![allow(duplicate_macro_exports)]
-
-#[macro_export]
-macro_rules! foo_modern { ($i:ident) => {} }
-
-#[macro_export]
-macro_rules! foo_modern { () => {} }
diff --git a/src/test/ui/issues/auxiliary/issue-38715.rs b/src/test/ui/issues/auxiliary/issue-38715.rs
deleted file mode 100644
index 5c15073f5a5..00000000000
--- a/src/test/ui/issues/auxiliary/issue-38715.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#![allow(duplicate_macro_exports)]
-
-#[macro_export]
-macro_rules! foo { ($i:ident) => {} }
-
-#[macro_export]
-macro_rules! foo { () => {} }
diff --git a/src/test/ui/issues/issue-10396.rs b/src/test/ui/issues/issue-10396.rs
index 0781e5e3ed9..d16ea3dc344 100644
--- a/src/test/ui/issues/issue-10396.rs
+++ b/src/test/ui/issues/issue-10396.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Debug)]
 enum Foo<'s> {
diff --git a/src/test/ui/issues/issue-10456.rs b/src/test/ui/issues/issue-10456.rs
index 7eac095de5d..9f8d2595520 100644
--- a/src/test/ui/issues/issue-10456.rs
+++ b/src/test/ui/issues/issue-10456.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub struct Foo;
diff --git a/src/test/ui/issues/issue-10763.rs b/src/test/ui/issues/issue-10763.rs
index 091a7c52963..627a8c2384c 100644
--- a/src/test/ui/issues/issue-10763.rs
+++ b/src/test/ui/issues/issue-10763.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-10853.rs b/src/test/ui/issues/issue-10853.rs
index c9de39feda6..3dcabf9b165 100644
--- a/src/test/ui/issues/issue-10853.rs
+++ b/src/test/ui/issues/issue-10853.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![deny(missing_docs)]
diff --git a/src/test/ui/issues/issue-10902.rs b/src/test/ui/issues/issue-10902.rs
index d53ce9a1db8..162482d49ab 100644
--- a/src/test/ui/issues/issue-10902.rs
+++ b/src/test/ui/issues/issue-10902.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-11384.rs b/src/test/ui/issues/issue-11384.rs
index 443c2be08bb..0105b4d223e 100644
--- a/src/test/ui/issues/issue-11384.rs
+++ b/src/test/ui/issues/issue-11384.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Common { fn dummy(&self) { } }
diff --git a/src/test/ui/issues/issue-11592.rs b/src/test/ui/issues/issue-11592.rs
index 0298f83baf8..a4611f2f90e 100644
--- a/src/test/ui/issues/issue-11592.rs
+++ b/src/test/ui/issues/issue-11592.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 //! Ensure the private trait Bar isn't complained about.
 
 #![deny(missing_docs)]
diff --git a/src/test/ui/issues/issue-11612.rs b/src/test/ui/issues/issue-11612.rs
index 553648a5ebc..9f7f1cc6fc7 100644
--- a/src/test/ui/issues/issue-11612.rs
+++ b/src/test/ui/issues/issue-11612.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // #11612
 // We weren't updating the auto adjustments with all the resolved
diff --git a/src/test/ui/issues/issue-11869.rs b/src/test/ui/issues/issue-11869.rs
index a44094bfb23..b300f4593a7 100644
--- a/src/test/ui/issues/issue-11869.rs
+++ b/src/test/ui/issues/issue-11869.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs
index 77278ecda6e..7f25c9a787e 100644
--- a/src/test/ui/issues/issue-1251.rs
+++ b/src/test/ui/issues/issue-1251.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_attributes)]
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-12729.rs b/src/test/ui/issues/issue-12729.rs
index 67c1bdc32ed..aa0b04af28e 100644
--- a/src/test/ui/issues/issue-12729.rs
+++ b/src/test/ui/issues/issue-12729.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-13105.rs b/src/test/ui/issues/issue-13105.rs
index 2410e2f1367..15a98c77983 100644
--- a/src/test/ui/issues/issue-13105.rs
+++ b/src/test/ui/issues/issue-13105.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/src/test/ui/issues/issue-13167.rs b/src/test/ui/issues/issue-13167.rs
index e04faabb7e8..8584c98decf 100644
--- a/src/test/ui/issues/issue-13167.rs
+++ b/src/test/ui/issues/issue-13167.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 use std::slice;
diff --git a/src/test/ui/issues/issue-13214.rs b/src/test/ui/issues/issue-13214.rs
index 0015169b117..0cf8d0675e6 100644
--- a/src/test/ui/issues/issue-13214.rs
+++ b/src/test/ui/issues/issue-13214.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // defining static with struct that contains enum
 // with &'static str variant used to cause ICE
diff --git a/src/test/ui/issues/issue-13405.rs b/src/test/ui/issues/issue-13405.rs
index fb48abe2648..732172b23ed 100644
--- a/src/test/ui/issues/issue-13405.rs
+++ b/src/test/ui/issues/issue-13405.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-13703.rs b/src/test/ui/issues/issue-13703.rs
index fe5458a7d7c..424c99974b3 100644
--- a/src/test/ui/issues/issue-13703.rs
+++ b/src/test/ui/issues/issue-13703.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize }
diff --git a/src/test/ui/issues/issue-13775.rs b/src/test/ui/issues/issue-13775.rs
index 0359bb581d5..f5977effc40 100644
--- a/src/test/ui/issues/issue-13775.rs
+++ b/src/test/ui/issues/issue-13775.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/src/test/ui/issues/issue-13837.rs b/src/test/ui/issues/issue-13837.rs
index 06790fbd324..645b1c0eb87 100644
--- a/src/test/ui/issues/issue-13837.rs
+++ b/src/test/ui/issues/issue-13837.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr
index 3f2d0aa87ad..67721356208 100644
--- a/src/test/ui/issues/issue-13853.stderr
+++ b/src/test/ui/issues/issue-13853.stderr
@@ -2,10 +2,10 @@ error[E0308]: mismatched types
   --> $DIR/issue-13853.rs:14:9
    |
 LL |     fn nodes<'a, I: Iterator<Item=&'a N>>(&self) -> I
-   |                                                     - expected `I` because of return type
+   |                  - this type parameter              - expected `I` because of return type
 ...
 LL |         self.iter()
-   |         ^^^^^^^^^^^ expected type parameter, found struct `std::slice::Iter`
+   |         ^^^^^^^^^^^ expected type parameter `I`, found struct `std::slice::Iter`
    |
    = note: expected type `I`
               found type `std::slice::Iter<'_, N>`
diff --git a/src/test/ui/issues/issue-14082.rs b/src/test/ui/issues/issue-14082.rs
index e5f1b492f27..52b8c86802f 100644
--- a/src/test/ui/issues/issue-14082.rs
+++ b/src/test/ui/issues/issue-14082.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![allow(unused_imports, dead_code)]
diff --git a/src/test/ui/issues/issue-14227.rs b/src/test/ui/issues/issue-14227.rs
index 5de3867f95c..d80eefc41bf 100644
--- a/src/test/ui/issues/issue-14227.rs
+++ b/src/test/ui/issues/issue-14227.rs
@@ -1,10 +1,7 @@
-#![allow(safe_extern_statics, warnings)]
-
 extern {
     pub static symbol: u32;
 }
 static CRASH: u32 = symbol;
-//~^ ERROR could not evaluate static initializer
-//~| tried to read from foreign (extern) static
+//~^ ERROR use of extern static is unsafe and requires
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-14227.stderr b/src/test/ui/issues/issue-14227.stderr
index 88e99e213bf..f9cdbe452df 100644
--- a/src/test/ui/issues/issue-14227.stderr
+++ b/src/test/ui/issues/issue-14227.stderr
@@ -1,9 +1,11 @@
-error[E0080]: could not evaluate static initializer
-  --> $DIR/issue-14227.rs:6:21
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-14227.rs:4:21
    |
 LL | static CRASH: u32 = symbol;
-   |                     ^^^^^^ tried to read from foreign (extern) static
+   |                     ^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/issues/issue-14254.rs b/src/test/ui/issues/issue-14254.rs
index 8b04fa192ad..6f930837641 100644
--- a/src/test/ui/issues/issue-14254.rs
+++ b/src/test/ui/issues/issue-14254.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo: Sized {
diff --git a/src/test/ui/issues/issue-14330.rs b/src/test/ui/issues/issue-14330.rs
index be31fa5eabc..0844fc72045 100644
--- a/src/test/ui/issues/issue-14330.rs
+++ b/src/test/ui/issues/issue-14330.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_imports)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-14837.rs b/src/test/ui/issues/issue-14837.rs
index a276e27f9dc..a83bc415002 100644
--- a/src/test/ui/issues/issue-14837.rs
+++ b/src/test/ui/issues/issue-14837.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #[deny(dead_code)]
diff --git a/src/test/ui/issues/issue-14901.rs b/src/test/ui/issues/issue-14901.rs
index c164658331e..5319abbdf0e 100644
--- a/src/test/ui/issues/issue-14901.rs
+++ b/src/test/ui/issues/issue-14901.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Reader {}
 
 enum Wrapper<'a> {
diff --git a/src/test/ui/issues/issue-14933.rs b/src/test/ui/issues/issue-14933.rs
index f229c0f7c26..bd95332caba 100644
--- a/src/test/ui/issues/issue-14933.rs
+++ b/src/test/ui/issues/issue-14933.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub type BigRat<T = isize> = T;
diff --git a/src/test/ui/issues/issue-14936.rs b/src/test/ui/issues/issue-14936.rs
index 809a1088992..33532855fcd 100644
--- a/src/test/ui/issues/issue-14936.rs
+++ b/src/test/ui/issues/issue-14936.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_macros)]
 #![allow(dead_code)]
 #![feature(asm)]
diff --git a/src/test/ui/issues/issue-14959.rs b/src/test/ui/issues/issue-14959.rs
index bd6c7a2bda9..e31a9431558 100644
--- a/src/test/ui/issues/issue-14959.rs
+++ b/src/test/ui/issues/issue-14959.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![feature(fn_traits, unboxed_closures)]
diff --git a/src/test/ui/issues/issue-15108.rs b/src/test/ui/issues/issue-15108.rs
deleted file mode 100644
index b8231ad4e83..00000000000
--- a/src/test/ui/issues/issue-15108.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-// build-pass (FIXME(62277): could be check-pass?)
-// pretty-expanded FIXME #23616
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-15261.rs b/src/test/ui/issues/issue-15261.rs
index dd859475f9c..ec413f6d1d2 100644
--- a/src/test/ui/issues/issue-15261.rs
+++ b/src/test/ui/issues/issue-15261.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-15689-2.rs b/src/test/ui/issues/issue-15689-2.rs
index 1731a356ccd..83dcb1406f8 100644
--- a/src/test/ui/issues/issue-15689-2.rs
+++ b/src/test/ui/issues/issue-15689-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-15735.rs b/src/test/ui/issues/issue-15735.rs
index 0da4d4a620b..f9ba34405f6 100644
--- a/src/test/ui/issues/issue-15735.rs
+++ b/src/test/ui/issues/issue-15735.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct A<'a> {
     a: &'a i32,
diff --git a/src/test/ui/issues/issue-16441.rs b/src/test/ui/issues/issue-16441.rs
index bae3813f9da..1086aeb3055 100644
--- a/src/test/ui/issues/issue-16441.rs
+++ b/src/test/ui/issues/issue-16441.rs
@@ -5,6 +5,7 @@
 struct Empty;
 
 // This used to cause an ICE
+#[allow(improper_ctypes)]
 extern "C" fn ice(_a: Empty) {}
 
 fn main() {
diff --git a/src/test/ui/issues/issue-16538.rs b/src/test/ui/issues/issue-16538.rs
index a990c078a79..54d9a732912 100644
--- a/src/test/ui/issues/issue-16538.rs
+++ b/src/test/ui/issues/issue-16538.rs
@@ -1,5 +1,3 @@
-#![allow(safe_extern_statics)]
-
 mod Y {
     pub type X = usize;
     extern {
@@ -13,5 +11,6 @@ mod Y {
 static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
 //~^ ERROR `*const usize` cannot be shared between threads safely [E0277]
 //~| ERROR E0015
+//~| ERROR use of extern static is unsafe and requires
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-16538.stderr b/src/test/ui/issues/issue-16538.stderr
index 2d8b5bf2f6f..5e1f95a989e 100644
--- a/src/test/ui/issues/issue-16538.stderr
+++ b/src/test/ui/issues/issue-16538.stderr
@@ -1,11 +1,11 @@
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
-  --> $DIR/issue-16538.rs:13:27
+  --> $DIR/issue-16538.rs:11:27
    |
 LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `*const usize` cannot be shared between threads safely
-  --> $DIR/issue-16538.rs:13:1
+  --> $DIR/issue-16538.rs:11:1
    |
 LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const usize` cannot be shared between threads safely
@@ -13,7 +13,15 @@ LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
    = help: the trait `std::marker::Sync` is not implemented for `*const usize`
    = note: shared static variables must have a type that implements `Sync`
 
-error: aborting due to 2 previous errors
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-16538.rs:11:34
+   |
+LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
+   |                                  ^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0015, E0277.
+Some errors have detailed explanations: E0015, E0133, E0277.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/issues/issue-16596.rs b/src/test/ui/issues/issue-16596.rs
index 693dea436bb..e7a09630251 100644
--- a/src/test/ui/issues/issue-16596.rs
+++ b/src/test/ui/issues/issue-16596.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 trait MatrixRow { fn dummy(&self) { }}
diff --git a/src/test/ui/issues/issue-16668.rs b/src/test/ui/issues/issue-16668.rs
index a898ab20a48..92efb42fe30 100644
--- a/src/test/ui/issues/issue-16668.rs
+++ b/src/test/ui/issues/issue-16668.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Parser<'a, I, O> {
     parse: Box<dyn FnMut(I) -> Result<O, String> + 'a>
diff --git a/src/test/ui/issues/issue-17121.rs b/src/test/ui/issues/issue-17121.rs
index 0f1d4f5410d..34b1e2099be 100644
--- a/src/test/ui/issues/issue-17121.rs
+++ b/src/test/ui/issues/issue-17121.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 // ignore-cloudabi no std::fs
diff --git a/src/test/ui/issues/issue-17263.rs b/src/test/ui/issues/issue-17263.rs
index f24acb7b304..7e9ff685482 100644
--- a/src/test/ui/issues/issue-17263.rs
+++ b/src/test/ui/issues/issue-17263.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(box_syntax)]
 
diff --git a/src/test/ui/issues/issue-17336.rs b/src/test/ui/issues/issue-17336.rs
index 830d799fb65..89ce59b11f2 100644
--- a/src/test/ui/issues/issue-17336.rs
+++ b/src/test/ui/issues/issue-17336.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_must_use)]
 #[allow(dead_code)]
 fn check(a: &str) {
diff --git a/src/test/ui/issues/issue-17450.rs b/src/test/ui/issues/issue-17450.rs
index 595e0a4d25c..1ac0af1754b 100644
--- a/src/test/ui/issues/issue-17450.rs
+++ b/src/test/ui/issues/issue-17450.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code, warnings)]
 
 static mut x: isize = 3;
diff --git a/src/test/ui/issues/issue-17718-const-destructors.rs b/src/test/ui/issues/issue-17718-const-destructors.rs
index 7ec025ec3af..c9a729c7b20 100644
--- a/src/test/ui/issues/issue-17718-const-destructors.rs
+++ b/src/test/ui/issues/issue-17718-const-destructors.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct A;
 impl Drop for A {
diff --git a/src/test/ui/issues/issue-17732.rs b/src/test/ui/issues/issue-17732.rs
index 17135c191ca..5e11fc4fcfb 100644
--- a/src/test/ui/issues/issue-17732.rs
+++ b/src/test/ui/issues/issue-17732.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-17746.rs b/src/test/ui/issues/issue-17746.rs
index 847b2eb60bb..bab64a4b5ae 100644
--- a/src/test/ui/issues/issue-17746.rs
+++ b/src/test/ui/issues/issue-17746.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #17746
 
diff --git a/src/test/ui/issues/issue-17904.rs b/src/test/ui/issues/issue-17904.rs
index d916abb9c73..c3f504ac1b9 100644
--- a/src/test/ui/issues/issue-17904.rs
+++ b/src/test/ui/issues/issue-17904.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Test that we can parse where clauses on various forms of tuple
 // structs.
diff --git a/src/test/ui/issues/issue-18083.rs b/src/test/ui/issues/issue-18083.rs
index f159ed4a0ce..36420ec142e 100644
--- a/src/test/ui/issues/issue-18083.rs
+++ b/src/test/ui/issues/issue-18083.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_imports)]
 // These crossed imports should resolve fine, and not block on
diff --git a/src/test/ui/issues/issue-18088.rs b/src/test/ui/issues/issue-18088.rs
index 06f259958f8..c557b5a6512 100644
--- a/src/test/ui/issues/issue-18088.rs
+++ b/src/test/ui/issues/issue-18088.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub trait Indexable<T>: std::ops::Index<usize, Output = T> {
     fn index2(&self, i: usize) -> &T {
diff --git a/src/test/ui/issues/issue-18188.rs b/src/test/ui/issues/issue-18188.rs
index da10a8647ba..ce166724aff 100644
--- a/src/test/ui/issues/issue-18188.rs
+++ b/src/test/ui/issues/issue-18188.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub trait Promisable: Send + Sync {}
diff --git a/src/test/ui/issues/issue-1821.rs b/src/test/ui/issues/issue-1821.rs
index db97a507b68..76ee9c3edb0 100644
--- a/src/test/ui/issues/issue-1821.rs
+++ b/src/test/ui/issues/issue-1821.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-18446-2.rs b/src/test/ui/issues/issue-18446-2.rs
index 6b984c13da5..85422d4d261 100644
--- a/src/test/ui/issues/issue-18446-2.rs
+++ b/src/test/ui/issues/issue-18446-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Test that methods in trait impls should override default methods.
 
diff --git a/src/test/ui/issues/issue-1866.rs b/src/test/ui/issues/issue-1866.rs
index 0223e2ebea9..e4fe26800ef 100644
--- a/src/test/ui/issues/issue-1866.rs
+++ b/src/test/ui/issues/issue-1866.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-18738.rs b/src/test/ui/issues/issue-18738.rs
index ec4429234bc..bcc1ec03f26 100644
--- a/src/test/ui/issues/issue-18738.rs
+++ b/src/test/ui/issues/issue-18738.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Eq, PartialEq, PartialOrd, Ord)]
 enum Test<'a> {
diff --git a/src/test/ui/issues/issue-18809.rs b/src/test/ui/issues/issue-18809.rs
index 9b8275f8119..cc5b4a64c6d 100644
--- a/src/test/ui/issues/issue-18809.rs
+++ b/src/test/ui/issues/issue-18809.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait Tup {
     type T0;
     type T1;
diff --git a/src/test/ui/issues/issue-18906.rs b/src/test/ui/issues/issue-18906.rs
index 387fd41fb7a..976a9f49b9d 100644
--- a/src/test/ui/issues/issue-18906.rs
+++ b/src/test/ui/issues/issue-18906.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-18988.rs b/src/test/ui/issues/issue-18988.rs
index 6dbfd3a0a98..708965d81d8 100644
--- a/src/test/ui/issues/issue-18988.rs
+++ b/src/test/ui/issues/issue-18988.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 pub trait Foo : Send { }
 
diff --git a/src/test/ui/issues/issue-19037.rs b/src/test/ui/issues/issue-19037.rs
index 30497d3e94f..74623da1454 100644
--- a/src/test/ui/issues/issue-19037.rs
+++ b/src/test/ui/issues/issue-19037.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19081.rs b/src/test/ui/issues/issue-19081.rs
index 0948cd3271b..fbfe4c6f839 100644
--- a/src/test/ui/issues/issue-19081.rs
+++ b/src/test/ui/issues/issue-19081.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Hasher {
     type State;
 
diff --git a/src/test/ui/issues/issue-19097.rs b/src/test/ui/issues/issue-19097.rs
index c800e0bd12a..2f4b0d575bb 100644
--- a/src/test/ui/issues/issue-19097.rs
+++ b/src/test/ui/issues/issue-19097.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // regression test for #19097
 
diff --git a/src/test/ui/issues/issue-19098.rs b/src/test/ui/issues/issue-19098.rs
index 37c0d7f0522..3d05f11b697 100644
--- a/src/test/ui/issues/issue-19098.rs
+++ b/src/test/ui/issues/issue-19098.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Handler {
     fn handle(&self, _: &mut String);
 }
diff --git a/src/test/ui/issues/issue-19102.rs b/src/test/ui/issues/issue-19102.rs
index 76ed3efc4ed..1f32d10b644 100644
--- a/src/test/ui/issues/issue-19102.rs
+++ b/src/test/ui/issues/issue-19102.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_imports)]
 #![deny(unused_qualifications)]
 
diff --git a/src/test/ui/issues/issue-19129-1.rs b/src/test/ui/issues/issue-19129-1.rs
index e17ee053f33..03a9691018a 100644
--- a/src/test/ui/issues/issue-19129-1.rs
+++ b/src/test/ui/issues/issue-19129-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Trait<Input> {
diff --git a/src/test/ui/issues/issue-19129-2.rs b/src/test/ui/issues/issue-19129-2.rs
index 30c64573a15..991d79d4159 100644
--- a/src/test/ui/issues/issue-19129-2.rs
+++ b/src/test/ui/issues/issue-19129-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19398.rs b/src/test/ui/issues/issue-19398.rs
index 28d266a1d61..a9d0acaa26f 100644
--- a/src/test/ui/issues/issue-19398.rs
+++ b/src/test/ui/issues/issue-19398.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait T {
diff --git a/src/test/ui/issues/issue-19404.rs b/src/test/ui/issues/issue-19404.rs
index 40c9fdac7b0..f1cf1feb005 100644
--- a/src/test/ui/issues/issue-19404.rs
+++ b/src/test/ui/issues/issue-19404.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 use std::any::TypeId;
diff --git a/src/test/ui/issues/issue-19479.rs b/src/test/ui/issues/issue-19479.rs
index c134d85c7e9..70bfe7213f2 100644
--- a/src/test/ui/issues/issue-19479.rs
+++ b/src/test/ui/issues/issue-19479.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Base {
diff --git a/src/test/ui/issues/issue-19631.rs b/src/test/ui/issues/issue-19631.rs
index 015758dd6e1..694e6dcd15a 100644
--- a/src/test/ui/issues/issue-19631.rs
+++ b/src/test/ui/issues/issue-19631.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19632.rs b/src/test/ui/issues/issue-19632.rs
index ddd87a9f6e9..203976079fb 100644
--- a/src/test/ui/issues/issue-19632.rs
+++ b/src/test/ui/issues/issue-19632.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19850.rs b/src/test/ui/issues/issue-19850.rs
index d51cf0cfcb9..4a578c398a8 100644
--- a/src/test/ui/issues/issue-19850.rs
+++ b/src/test/ui/issues/issue-19850.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_variables)]
 // Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
 // bindings
diff --git a/src/test/ui/issues/issue-19982.rs b/src/test/ui/issues/issue-19982.rs
index fb88781ee28..12419c109c5 100644
--- a/src/test/ui/issues/issue-19982.rs
+++ b/src/test/ui/issues/issue-19982.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(fn_traits, unboxed_closures)]
 
diff --git a/src/test/ui/issues/issue-20009.rs b/src/test/ui/issues/issue-20009.rs
index 730f1a9a162..f289e58c50e 100644
--- a/src/test/ui/issues/issue-20009.rs
+++ b/src/test/ui/issues/issue-20009.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Check that associated types are `Sized`
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-20091.rs b/src/test/ui/issues/issue-20091.rs
index 68e0f65ca23..90db44fa02d 100644
--- a/src/test/ui/issues/issue-20091.rs
+++ b/src/test/ui/issues/issue-20091.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// run-pass
 #![allow(stable_features)]
 
 // ignore-cloudabi no processes
diff --git a/src/test/ui/issues/issue-20186.rs b/src/test/ui/issues/issue-20186.rs
index 28cbde772c5..54d68f10052 100644
--- a/src/test/ui/issues/issue-20186.rs
+++ b/src/test/ui/issues/issue-20186.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 struct Foo;
diff --git a/src/test/ui/issues/issue-20225.stderr b/src/test/ui/issues/issue-20225.stderr
index 4c464e6d4f6..40093b13edf 100644
--- a/src/test/ui/issues/issue-20225.stderr
+++ b/src/test/ui/issues/issue-20225.stderr
@@ -1,8 +1,10 @@
 error[E0053]: method `call` has an incompatible type for trait
   --> $DIR/issue-20225.rs:6:3
    |
+LL | impl<'a, T> Fn<(&'a T,)> for Foo {
+   |          - this type parameter
 LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
    |
    = note: expected type `extern "rust-call" fn(&Foo, (&'a T,))`
               found type `extern "rust-call" fn(&Foo, (T,))`
@@ -12,8 +14,10 @@ LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
 error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/issue-20225.rs:12:3
    |
+LL | impl<'a, T> FnMut<(&'a T,)> for Foo {
+   |          - this type parameter
 LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
    |
    = note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))`
               found type `extern "rust-call" fn(&mut Foo, (T,))`
@@ -23,8 +27,11 @@ LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
 error[E0053]: method `call_once` has an incompatible type for trait
   --> $DIR/issue-20225.rs:20:3
    |
+LL | impl<'a, T> FnOnce<(&'a T,)> for Foo {
+   |          - this type parameter
+...
 LL |   extern "rust-call" fn call_once(self, (_,): (T,)) {}
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found type parameter `T`
    |
    = note: expected type `extern "rust-call" fn(Foo, (&'a T,))`
               found type `extern "rust-call" fn(Foo, (T,))`
diff --git a/src/test/ui/issues/issue-20396.rs b/src/test/ui/issues/issue-20396.rs
index 5e0411b2cd2..4a34f8b385f 100644
--- a/src/test/ui/issues/issue-20396.rs
+++ b/src/test/ui/issues/issue-20396.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
diff --git a/src/test/ui/issues/issue-20414.rs b/src/test/ui/issues/issue-20414.rs
index 5c6929d45d1..2496e342a2f 100644
--- a/src/test/ui/issues/issue-20414.rs
+++ b/src/test/ui/issues/issue-20414.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-20454.rs b/src/test/ui/issues/issue-20454.rs
index 13ce1daf30a..46cae33f102 100644
--- a/src/test/ui/issues/issue-20454.rs
+++ b/src/test/ui/issues/issue-20454.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_must_use)]
 use std::thread;
 
diff --git a/src/test/ui/issues/issue-20616-1.stderr b/src/test/ui/issues/issue-20616-1.stderr
index 143486c8f5a..81604623785 100644
--- a/src/test/ui/issues/issue-20616-1.stderr
+++ b/src/test/ui/issues/issue-20616-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `T`
   --> $DIR/issue-20616-1.rs:9:16
    |
 LL | type Type_1<'a T> = &'a T;
-   |                ^ expected one of `,`, `:`, or `>` here
+   |                ^ expected one of `,`, `:`, or `>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-2.stderr b/src/test/ui/issues/issue-20616-2.stderr
index 1152dec8bad..50ec7a304c5 100644
--- a/src/test/ui/issues/issue-20616-2.stderr
+++ b/src/test/ui/issues/issue-20616-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `,` or `>`, found `(`
   --> $DIR/issue-20616-2.rs:12:31
    |
 LL | type Type_2 = Type_1_<'static ()>;
-   |                               ^ expected one of `,` or `>` here
+   |                               ^ expected one of `,` or `>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-3.stderr b/src/test/ui/issues/issue-20616-3.stderr
index f51fb949c74..cc4d79484e7 100644
--- a/src/test/ui/issues/issue-20616-3.stderr
+++ b/src/test/ui/issues/issue-20616-3.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
   --> $DIR/issue-20616-3.rs:13:24
    |
 LL | type Type_3<T> = Box<T,,>;
-   |                        ^ expected one of `>`, const, identifier, lifetime, or type here
+   |                        ^ expected one of `>`, const, identifier, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-4.stderr b/src/test/ui/issues/issue-20616-4.stderr
index 22a655465e8..254e4d6a34d 100644
--- a/src/test/ui/issues/issue-20616-4.stderr
+++ b/src/test/ui/issues/issue-20616-4.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
   --> $DIR/issue-20616-4.rs:16:34
    |
 LL | type Type_4<T> = Type_1_<'static,, T>;
-   |                                  ^ expected one of `>`, const, identifier, lifetime, or type here
+   |                                  ^ expected one of `>`, const, identifier, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-5.stderr b/src/test/ui/issues/issue-20616-5.stderr
index d83fc41f43e..aee8bf01a43 100644
--- a/src/test/ui/issues/issue-20616-5.stderr
+++ b/src/test/ui/issues/issue-20616-5.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
   --> $DIR/issue-20616-5.rs:22:34
    |
 LL | type Type_5<'a> = Type_1_<'a, (),,>;
-   |                                  ^ expected one of `>`, const, identifier, lifetime, or type here
+   |                                  ^ expected one of `>`, const, identifier, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-6.stderr b/src/test/ui/issues/issue-20616-6.stderr
index 0740df59523..7192a87bc18 100644
--- a/src/test/ui/issues/issue-20616-6.stderr
+++ b/src/test/ui/issues/issue-20616-6.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
   --> $DIR/issue-20616-6.rs:25:26
    |
 LL | type Type_6 = Type_5_<'a,,>;
-   |                          ^ expected one of `>`, const, identifier, lifetime, or type here
+   |                          ^ expected one of `>`, const, identifier, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-7.stderr b/src/test/ui/issues/issue-20616-7.stderr
index c0e108375be..123dc1e2b7d 100644
--- a/src/test/ui/issues/issue-20616-7.stderr
+++ b/src/test/ui/issues/issue-20616-7.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
   --> $DIR/issue-20616-7.rs:28:22
    |
 LL | type Type_7 = Box<(),,>;
-   |                      ^ expected one of `>`, const, identifier, lifetime, or type here
+   |                      ^ expected one of `>`, const, identifier, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-8.stderr b/src/test/ui/issues/issue-20616-8.stderr
index 0ef9192f1e7..479469634c5 100644
--- a/src/test/ui/issues/issue-20616-8.stderr
+++ b/src/test/ui/issues/issue-20616-8.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
   --> $DIR/issue-20616-8.rs:31:16
    |
 LL | type Type_8<'a,,> = &'a ();
-   |                ^ expected one of `>`, `const`, identifier, or lifetime here
+   |                ^ expected one of `>`, `const`, identifier, or lifetime
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20616-9.stderr b/src/test/ui/issues/issue-20616-9.stderr
index 5fd1400a2e8..b7e3322b7aa 100644
--- a/src/test/ui/issues/issue-20616-9.stderr
+++ b/src/test/ui/issues/issue-20616-9.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
   --> $DIR/issue-20616-9.rs:34:15
    |
 LL | type Type_9<T,,> = Box<T>;
-   |               ^ expected one of `>`, `const`, identifier, or lifetime here
+   |               ^ expected one of `>`, `const`, identifier, or lifetime
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-2063-resource.rs b/src/test/ui/issues/issue-2063-resource.rs
index ea4cbf2cede..1d0527447ba 100644
--- a/src/test/ui/issues/issue-2063-resource.rs
+++ b/src/test/ui/issues/issue-2063-resource.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // test that autoderef of a type like this does not
 // cause compiler to loop.  Note that no instances
diff --git a/src/test/ui/issues/issue-20644.rs b/src/test/ui/issues/issue-20644.rs
index bde65229ec2..36eac382496 100644
--- a/src/test/ui/issues/issue-20644.rs
+++ b/src/test/ui/issues/issue-20644.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(unused_imports)]
 #![allow(stable_features)]
diff --git a/src/test/ui/issues/issue-20763-1.rs b/src/test/ui/issues/issue-20763-1.rs
index 0f0ac8f6462..858d313fc32 100644
--- a/src/test/ui/issues/issue-20763-1.rs
+++ b/src/test/ui/issues/issue-20763-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-20763-2.rs b/src/test/ui/issues/issue-20763-2.rs
index e3b566d0503..aa5bed209ee 100644
--- a/src/test/ui/issues/issue-20763-2.rs
+++ b/src/test/ui/issues/issue-20763-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-20797.rs b/src/test/ui/issues/issue-20797.rs
index bda7e8f818b..5d82592e5ea 100644
--- a/src/test/ui/issues/issue-20797.rs
+++ b/src/test/ui/issues/issue-20797.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // ignore-cloudabi no std::fs
 
 // Regression test for #20797.
diff --git a/src/test/ui/issues/issue-20825-2.rs b/src/test/ui/issues/issue-20825-2.rs
index 7d72ef839ea..b79a2973082 100644
--- a/src/test/ui/issues/issue-20825-2.rs
+++ b/src/test/ui/issues/issue-20825-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Subscriber {
     type Input;
 }
diff --git a/src/test/ui/issues/issue-21140.rs b/src/test/ui/issues/issue-21140.rs
index 92834bbb0e4..01de901112e 100644
--- a/src/test/ui/issues/issue-21140.rs
+++ b/src/test/ui/issues/issue-21140.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Trait where Self::Out: std::fmt::Display {
     type Out;
 }
diff --git a/src/test/ui/issues/issue-21146.stderr b/src/test/ui/issues/issue-21146.stderr
index 2798196ea00..c71fda3d63f 100644
--- a/src/test/ui/issues/issue-21146.stderr
+++ b/src/test/ui/issues/issue-21146.stderr
@@ -2,7 +2,7 @@ error: expected one of `!` or `::`, found `<eof>`
   --> $DIR/auxiliary/issue-21146-inc.rs:3:1
    |
 LL | parse_error
-   | ^^^^^^^^^^^ expected one of `!` or `::` here
+   | ^^^^^^^^^^^ expected one of `!` or `::`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-21160.rs b/src/test/ui/issues/issue-21160.rs
index dfb39743352..0199abbd8f0 100644
--- a/src/test/ui/issues/issue-21160.rs
+++ b/src/test/ui/issues/issue-21160.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 struct Bar;
 
 impl Bar {
diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr
index 9f88fa2fadd..65ba64b49d0 100644
--- a/src/test/ui/issues/issue-21160.stderr
+++ b/src/test/ui/issues/issue-21160.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Bar: std::hash::Hash` is not satisfied
-  --> $DIR/issue-21160.rs:10:12
+  --> $DIR/issue-21160.rs:9:12
    |
 LL | struct Foo(Bar);
    |            ^^^ the trait `std::hash::Hash` is not implemented for `Bar`
diff --git a/src/test/ui/issues/issue-21174-2.rs b/src/test/ui/issues/issue-21174-2.rs
index 351a98d5c85..c90f91f6a69 100644
--- a/src/test/ui/issues/issue-21174-2.rs
+++ b/src/test/ui/issues/issue-21174-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 trait Trait<'a> {
diff --git a/src/test/ui/issues/issue-21245.rs b/src/test/ui/issues/issue-21245.rs
index d0aa16bfb16..c8e55a0cc20 100644
--- a/src/test/ui/issues/issue-21245.rs
+++ b/src/test/ui/issues/issue-21245.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for issue #21245. Check that we are able to infer
 // the types in these examples correctly. It used to be that
diff --git a/src/test/ui/issues/issue-21363.rs b/src/test/ui/issues/issue-21363.rs
index d5f1eec061d..acc28cb430b 100644
--- a/src/test/ui/issues/issue-21363.rs
+++ b/src/test/ui/issues/issue-21363.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![no_implicit_prelude]
diff --git a/src/test/ui/issues/issue-21402.rs b/src/test/ui/issues/issue-21402.rs
index 21e0d58b5f4..d140b6162ce 100644
--- a/src/test/ui/issues/issue-21402.rs
+++ b/src/test/ui/issues/issue-21402.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-21520.rs b/src/test/ui/issues/issue-21520.rs
index 133bcc2360a..ab4ac7237c7 100644
--- a/src/test/ui/issues/issue-21520.rs
+++ b/src/test/ui/issues/issue-21520.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Test that the requirement (in `Bar`) that `T::Bar : 'static` does
 // not wind up propagating to `T`.
diff --git a/src/test/ui/issues/issue-21562.rs b/src/test/ui/issues/issue-21562.rs
index 2f3ee7b7490..a47d739c6be 100644
--- a/src/test/ui/issues/issue-21562.rs
+++ b/src/test/ui/issues/issue-21562.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-21622.rs b/src/test/ui/issues/issue-21622.rs
index 4aae089943f..2d4cddac911 100644
--- a/src/test/ui/issues/issue-21622.rs
+++ b/src/test/ui/issues/issue-21622.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
diff --git a/src/test/ui/issues/issue-21634.rs b/src/test/ui/issues/issue-21634.rs
index 36b207bb2a4..2731bfd767f 100644
--- a/src/test/ui/issues/issue-21634.rs
+++ b/src/test/ui/issues/issue-21634.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// run-pass
 #![allow(stable_features)]
 
 #![feature(cfg_target_feature)]
diff --git a/src/test/ui/issues/issue-21726.rs b/src/test/ui/issues/issue-21726.rs
index 1c8284c8295..b98cf216695 100644
--- a/src/test/ui/issues/issue-21726.rs
+++ b/src/test/ui/issues/issue-21726.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #21726: an issue arose around the rules for
 // subtyping of projection types that resulted in an unconstrained
diff --git a/src/test/ui/issues/issue-21891.rs b/src/test/ui/issues/issue-21891.rs
index de0aa2919cf..576f0253e63 100644
--- a/src/test/ui/issues/issue-21891.rs
+++ b/src/test/ui/issues/issue-21891.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-22066.rs b/src/test/ui/issues/issue-22066.rs
index fbf31aa4243..8e8ba5dc46c 100644
--- a/src/test/ui/issues/issue-22066.rs
+++ b/src/test/ui/issues/issue-22066.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait LineFormatter<'a> {
     type Iter: Iterator<Item=&'a str> + 'a;
     fn iter(&'a self, line: &'a str) -> Self::Iter;
diff --git a/src/test/ui/issues/issue-22356.rs b/src/test/ui/issues/issue-22356.rs
index ec4695e5e0a..47fad3bb909 100644
--- a/src/test/ui/issues/issue-22356.rs
+++ b/src/test/ui/issues/issue-22356.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(type_alias_bounds)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-22375.rs b/src/test/ui/issues/issue-22375.rs
index 201aea3a05c..21a1a4c8380 100644
--- a/src/test/ui/issues/issue-22375.rs
+++ b/src/test/ui/issues/issue-22375.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait A<T: A<T>> {}
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-22471.rs b/src/test/ui/issues/issue-22471.rs
index befccc19bf8..69879ab7fdf 100644
--- a/src/test/ui/issues/issue-22471.rs
+++ b/src/test/ui/issues/issue-22471.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(type_alias_bounds)]
 
diff --git a/src/test/ui/issues/issue-22777.rs b/src/test/ui/issues/issue-22777.rs
index 81efb250dfa..a31f059408f 100644
--- a/src/test/ui/issues/issue-22777.rs
+++ b/src/test/ui/issues/issue-22777.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // This test is reduced from libsyntax.  It is just checking that we
 // can successfully deal with a "deep" structure, which the drop-check
 // was hitting a recursion limit on at one point.
diff --git a/src/test/ui/issues/issue-22781.rs b/src/test/ui/issues/issue-22781.rs
index 37f40aa0421..d644cec4d56 100644
--- a/src/test/ui/issues/issue-22781.rs
+++ b/src/test/ui/issues/issue-22781.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_variables)]
 use std::collections::HashMap;
 use std::collections::hash_map::Entry::Vacant;
diff --git a/src/test/ui/issues/issue-22814.rs b/src/test/ui/issues/issue-22814.rs
index 065e7edc67e..4079adfc8b6 100644
--- a/src/test/ui/issues/issue-22814.rs
+++ b/src/test/ui/issues/issue-22814.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait Test {}
 
 macro_rules! test {
diff --git a/src/test/ui/issues/issue-22894.rs b/src/test/ui/issues/issue-22894.rs
index 7b1513a10c0..93c1db914ea 100644
--- a/src/test/ui/issues/issue-22894.rs
+++ b/src/test/ui/issues/issue-22894.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #[allow(dead_code)]
 static X: &'static str = &*"";
 fn main() {}
diff --git a/src/test/ui/issues/issue-2311-2.rs b/src/test/ui/issues/issue-2311-2.rs
index f735338fcdb..760d4edaa98 100644
--- a/src/test/ui/issues/issue-2311-2.rs
+++ b/src/test/ui/issues/issue-2311-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-2311.rs b/src/test/ui/issues/issue-2311.rs
index 151ad4e2664..21ff19f7f03 100644
--- a/src/test/ui/issues/issue-2311.rs
+++ b/src/test/ui/issues/issue-2311.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(non_camel_case_types)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-2312.rs b/src/test/ui/issues/issue-2312.rs
index b445f9581b3..8a94bcbd4cc 100644
--- a/src/test/ui/issues/issue-2312.rs
+++ b/src/test/ui/issues/issue-2312.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-23406.rs b/src/test/ui/issues/issue-23406.rs
index 2e57b16e3c7..d00d5d6f944 100644
--- a/src/test/ui/issues/issue-23406.rs
+++ b/src/test/ui/issues/issue-23406.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 trait Inner {
     type T;
diff --git a/src/test/ui/issues/issue-23442.rs b/src/test/ui/issues/issue-23442.rs
index 659e1e07942..d1e4317e5b4 100644
--- a/src/test/ui/issues/issue-23442.rs
+++ b/src/test/ui/issues/issue-23442.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::marker::PhantomData;
 
diff --git a/src/test/ui/issues/issue-23550.rs b/src/test/ui/issues/issue-23550.rs
index fad0ad7ecca..9cce9a0a98b 100644
--- a/src/test/ui/issues/issue-23550.rs
+++ b/src/test/ui/issues/issue-23550.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![feature(core_intrinsics)]
 #![allow(warnings)]
 
diff --git a/src/test/ui/issues/issue-23649-3.rs b/src/test/ui/issues/issue-23649-3.rs
index febdc4256c7..8f61c71d6eb 100644
--- a/src/test/ui/issues/issue-23649-3.rs
+++ b/src/test/ui/issues/issue-23649-3.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #[derive(PartialEq)]
 struct Slice { slice: [u8] }
 
diff --git a/src/test/ui/issues/issue-24085.rs b/src/test/ui/issues/issue-24085.rs
index dc2de922ff0..86e94beb7e2 100644
--- a/src/test/ui/issues/issue-24085.rs
+++ b/src/test/ui/issues/issue-24085.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #24085. Errors were occurring in region
 // inference due to the requirement that `'a:b'`, which was getting
diff --git a/src/test/ui/issues/issue-24161.rs b/src/test/ui/issues/issue-24161.rs
index c5c8651d43b..f4cdd982ac6 100644
--- a/src/test/ui/issues/issue-24161.rs
+++ b/src/test/ui/issues/issue-24161.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Copy,Clone)]
 struct Functions {
diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr
index 9c53c1b86ce..ace5b5f72fc 100644
--- a/src/test/ui/issues/issue-24204.stderr
+++ b/src/test/ui/issues/issue-24204.stderr
@@ -5,7 +5,7 @@ LL | trait Trait: Sized {
    | ------------------ required by `Trait`
 ...
 LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::new(b) }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found associated type
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
    |
    = note: expected type `T`
               found type `<<T as Trait>::A as MultiDispatch<i32>>::O`
diff --git a/src/test/ui/issues/issue-24227.rs b/src/test/ui/issues/issue-24227.rs
index eaadaf7c449..12816c235f8 100644
--- a/src/test/ui/issues/issue-24227.rs
+++ b/src/test/ui/issues/issue-24227.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // This resulted in an ICE. Test for future-proofing
 // Issue #24227
 
diff --git a/src/test/ui/issues/issue-24338.rs b/src/test/ui/issues/issue-24338.rs
index 09cc99f9507..3a2c790f852 100644
--- a/src/test/ui/issues/issue-24338.rs
+++ b/src/test/ui/issues/issue-24338.rs
@@ -1,5 +1,5 @@
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait DictLike<'a> {
     type ItemsIterator: Iterator<Item=u8>;
diff --git a/src/test/ui/issues/issue-24389.rs b/src/test/ui/issues/issue-24389.rs
index 63d1687af50..7cc7611769a 100644
--- a/src/test/ui/issues/issue-24389.rs
+++ b/src/test/ui/issues/issue-24389.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 struct Foo;
diff --git a/src/test/ui/issues/issue-24434.rs b/src/test/ui/issues/issue-24434.rs
index b500b9d56dd..4c1bfc03c9a 100644
--- a/src/test/ui/issues/issue-24434.rs
+++ b/src/test/ui/issues/issue-24434.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags:--cfg set1
 
 #![cfg_attr(set1, feature(rustc_attrs))]
diff --git a/src/test/ui/issues/issue-2487-a.rs b/src/test/ui/issues/issue-2487-a.rs
index a43933d2020..fe12dad74f5 100644
--- a/src/test/ui/issues/issue-2487-a.rs
+++ b/src/test/ui/issues/issue-2487-a.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-2502.rs b/src/test/ui/issues/issue-2502.rs
index 9a2bbb82413..63151002438 100644
--- a/src/test/ui/issues/issue-2502.rs
+++ b/src/test/ui/issues/issue-2502.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-25180.rs b/src/test/ui/issues/issue-25180.rs
index 12f8f88a170..29dc07f4914 100644
--- a/src/test/ui/issues/issue-25180.rs
+++ b/src/test/ui/issues/issue-25180.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-25394.rs b/src/test/ui/issues/issue-25394.rs
index c41b554df14..2f0ae19fcb1 100644
--- a/src/test/ui/issues/issue-25394.rs
+++ b/src/test/ui/issues/issue-25394.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Debug)]
 struct Row<T>([T]);
diff --git a/src/test/ui/issues/issue-25579.rs b/src/test/ui/issues/issue-25579.rs
index 32b4b75b080..5f5a0f4d267 100644
--- a/src/test/ui/issues/issue-25579.rs
+++ b/src/test/ui/issues/issue-25579.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 enum Sexpression {
     Num(()),
diff --git a/src/test/ui/issues/issue-26095.rs b/src/test/ui/issues/issue-26095.rs
index 1e3cc902e56..638f8f57187 100644
--- a/src/test/ui/issues/issue-26095.rs
+++ b/src/test/ui/issues/issue-26095.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-2611-3.rs b/src/test/ui/issues/issue-2611-3.rs
index 7335d53f8a6..a95a748e091 100644
--- a/src/test/ui/issues/issue-2611-3.rs
+++ b/src/test/ui/issues/issue-2611-3.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Tests that impls are allowed to have looser, more permissive bounds
 // than the traits require.
diff --git a/src/test/ui/issues/issue-26205.rs b/src/test/ui/issues/issue-26205.rs
index 45ca998a831..f5f39ded021 100644
--- a/src/test/ui/issues/issue-26205.rs
+++ b/src/test/ui/issues/issue-26205.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::ops::{Deref, DerefMut};
 
diff --git a/src/test/ui/issues/issue-26646.rs b/src/test/ui/issues/issue-26646.rs
index d6f51ce9c99..86e4bd7e8f8 100644
--- a/src/test/ui/issues/issue-26646.rs
+++ b/src/test/ui/issues/issue-26646.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(unused_attributes)]
 
 #[repr(C)]
diff --git a/src/test/ui/issues/issue-26997.rs b/src/test/ui/issues/issue-26997.rs
index a2b32a13678..9e7e47117ac 100644
--- a/src/test/ui/issues/issue-26997.rs
+++ b/src/test/ui/issues/issue-26997.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 pub struct Foo {
     x: isize,
@@ -6,6 +6,7 @@ pub struct Foo {
 }
 
 impl Foo {
+    #[allow(improper_ctypes)]
     pub extern fn foo_new() -> Foo {
         Foo { x: 21, y: 33 }
     }
diff --git a/src/test/ui/issues/issue-27033.rs b/src/test/ui/issues/issue-27033.rs
index bcb06d743a0..7120dee6339 100644
--- a/src/test/ui/issues/issue-27033.rs
+++ b/src/test/ui/issues/issue-27033.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 fn main() {
     match Some(1) {
         None @ _ => {} //~ ERROR match bindings cannot shadow unit variants
diff --git a/src/test/ui/issues/issue-27033.stderr b/src/test/ui/issues/issue-27033.stderr
index a4baa7bdf7f..2d6d2ef41bd 100644
--- a/src/test/ui/issues/issue-27033.stderr
+++ b/src/test/ui/issues/issue-27033.stderr
@@ -1,5 +1,5 @@
 error[E0530]: match bindings cannot shadow unit variants
-  --> $DIR/issue-27033.rs:5:9
+  --> $DIR/issue-27033.rs:4:9
    |
 LL |         None @ _ => {}
    |         ^^^^ cannot be named the same as a unit variant
@@ -10,7 +10,7 @@ LL | pub use crate::option::Option::{self, Some, None};
    |                                             ---- the unit variant `None` is defined here
 
 error[E0530]: match bindings cannot shadow constants
-  --> $DIR/issue-27033.rs:9:9
+  --> $DIR/issue-27033.rs:8:9
    |
 LL |     const C: u8 = 1;
    |     ---------------- the constant `C` is defined here
diff --git a/src/test/ui/issues/issue-27105.rs b/src/test/ui/issues/issue-27105.rs
index e7584d941ba..3339af364a0 100644
--- a/src/test/ui/issues/issue-27105.rs
+++ b/src/test/ui/issues/issue-27105.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 use std::cell::RefCell;
 use std::rc::Rc;
 
diff --git a/src/test/ui/issues/issue-27281.rs b/src/test/ui/issues/issue-27281.rs
index 58b8f07bca6..717d8b2c2aa 100644
--- a/src/test/ui/issues/issue-27281.rs
+++ b/src/test/ui/issues/issue-27281.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Trait<'a> {
     type T;
     type U;
diff --git a/src/test/ui/issues/issue-2748-a.rs b/src/test/ui/issues/issue-2748-a.rs
index 5f566e186eb..cbb9bcc28ac 100644
--- a/src/test/ui/issues/issue-2748-a.rs
+++ b/src/test/ui/issues/issue-2748-a.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/issues/issue-27583.rs b/src/test/ui/issues/issue-27583.rs
index 9981f867bd0..84c94c7c905 100644
--- a/src/test/ui/issues/issue-27583.rs
+++ b/src/test/ui/issues/issue-27583.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for issue #27583. Unclear how useful this will be
 // going forward, since the issue in question was EXTREMELY sensitive
 // to compiler internals (like the precise numbering of nodes), but
diff --git a/src/test/ui/issues/issue-27889.rs b/src/test/ui/issues/issue-27889.rs
index bb5a186b457..623416a5d00 100644
--- a/src/test/ui/issues/issue-27889.rs
+++ b/src/test/ui/issues/issue-27889.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 // Test that a field can have the same name in different variants
diff --git a/src/test/ui/issues/issue-2804-2.rs b/src/test/ui/issues/issue-2804-2.rs
index 68933fc2e8a..d02725505ac 100644
--- a/src/test/ui/issues/issue-2804-2.rs
+++ b/src/test/ui/issues/issue-2804-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Minimized version of issue-2804.rs. Both check that callee IDs don't
 // clobber the previous node ID in a macro expr
diff --git a/src/test/ui/issues/issue-28279.rs b/src/test/ui/issues/issue-28279.rs
index e36a9551ab5..bab5df122c8 100644
--- a/src/test/ui/issues/issue-28279.rs
+++ b/src/test/ui/issues/issue-28279.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::rc::Rc;
 
diff --git a/src/test/ui/issues/issue-28324.rs b/src/test/ui/issues/issue-28324.rs
index 73e8cd6ab0d..bb48508a4a4 100644
--- a/src/test/ui/issues/issue-28324.rs
+++ b/src/test/ui/issues/issue-28324.rs
@@ -1,11 +1,8 @@
-#![allow(safe_extern_statics)]
-
 extern {
     static error_message_count: u32;
 }
 
 pub static BAZ: u32 = *&error_message_count;
-//~^ ERROR could not evaluate static initializer
-//~| tried to read from foreign (extern) static
+//~^ ERROR use of extern static is unsafe and requires
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-28324.stderr b/src/test/ui/issues/issue-28324.stderr
index bbd02ba03f4..d7dad992152 100644
--- a/src/test/ui/issues/issue-28324.stderr
+++ b/src/test/ui/issues/issue-28324.stderr
@@ -1,9 +1,11 @@
-error[E0080]: could not evaluate static initializer
-  --> $DIR/issue-28324.rs:7:23
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-28324.rs:5:24
    |
 LL | pub static BAZ: u32 = *&error_message_count;
-   |                       ^^^^^^^^^^^^^^^^^^^^^ tried to read from foreign (extern) static
+   |                        ^^^^^^^^^^^^^^^^^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/issues/issue-28561.rs b/src/test/ui/issues/issue-28561.rs
index cc4e63696e5..1241fb0b1f8 100644
--- a/src/test/ui/issues/issue-28561.rs
+++ b/src/test/ui/issues/issue-28561.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
 struct Array<T> {
     f00: [T; 00],
diff --git a/src/test/ui/issues/issue-28600.rs b/src/test/ui/issues/issue-28600.rs
index 05c4050b03a..170c0a07125 100644
--- a/src/test/ui/issues/issue-28600.rs
+++ b/src/test/ui/issues/issue-28600.rs
@@ -1,9 +1,10 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // #28600 ICE: pub extern fn with parameter type &str inside struct impl
 
 struct Test;
 
 impl Test {
+    #[allow(improper_ctypes)]
     #[allow(dead_code)]
     #[allow(unused_variables)]
     pub extern fn test(val: &str) {
diff --git a/src/test/ui/issues/issue-28822.rs b/src/test/ui/issues/issue-28822.rs
index 2c0c01aa827..10e5d1dd0ac 100644
--- a/src/test/ui/issues/issue-28822.rs
+++ b/src/test/ui/issues/issue-28822.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-28871.rs b/src/test/ui/issues/issue-28871.rs
index 43564dfcc46..210c783de79 100644
--- a/src/test/ui/issues/issue-28871.rs
+++ b/src/test/ui/issues/issue-28871.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for #28871. The problem is that rustc encountered
 // two ways to project, one from a where clause and one from the where
 // clauses on the trait definition. (In fact, in this case, the where
diff --git a/src/test/ui/issues/issue-28936.rs b/src/test/ui/issues/issue-28936.rs
index 9267491aafd..da9e92c0c80 100644
--- a/src/test/ui/issues/issue-28936.rs
+++ b/src/test/ui/issues/issue-28936.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub type Session = i32;
 pub struct StreamParser<'a, T> {
     _tokens: T,
diff --git a/src/test/ui/issues/issue-28999.rs b/src/test/ui/issues/issue-28999.rs
index 888a8010a2f..cec3e25da86 100644
--- a/src/test/ui/issues/issue-28999.rs
+++ b/src/test/ui/issues/issue-28999.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub struct Xyz<'a, V> {
     pub v: (V, &'a u32),
 }
diff --git a/src/test/ui/issues/issue-29030.rs b/src/test/ui/issues/issue-29030.rs
index f9e89840314..723e358407f 100644
--- a/src/test/ui/issues/issue-29030.rs
+++ b/src/test/ui/issues/issue-29030.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Debug)]
 struct Message<'a, P: 'a = &'a [u8]> {
diff --git a/src/test/ui/issues/issue-29037.rs b/src/test/ui/issues/issue-29037.rs
index b1ca76be10d..155ed144b3a 100644
--- a/src/test/ui/issues/issue-29037.rs
+++ b/src/test/ui/issues/issue-29037.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // This test ensures that each pointer type `P<X>` is covariant in `X`.
 
diff --git a/src/test/ui/issues/issue-2904.rs b/src/test/ui/issues/issue-2904.rs
index 36bc8002f99..73aa78f09b9 100644
--- a/src/test/ui/issues/issue-2904.rs
+++ b/src/test/ui/issues/issue-2904.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
diff --git a/src/test/ui/issues/issue-29048.rs b/src/test/ui/issues/issue-29048.rs
index e3ccb0d6579..039f072f107 100644
--- a/src/test/ui/issues/issue-29048.rs
+++ b/src/test/ui/issues/issue-29048.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub struct Chan;
 pub struct ChanSelect<'c, T> {
     chans: Vec<(&'c Chan, T)>,
diff --git a/src/test/ui/issues/issue-29071.rs b/src/test/ui/issues/issue-29071.rs
index 7e016a715cd..8bdacf2cebb 100644
--- a/src/test/ui/issues/issue-29071.rs
+++ b/src/test/ui/issues/issue-29071.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-29276.rs b/src/test/ui/issues/issue-29276.rs
index 2532dac9772..02b69565953 100644
--- a/src/test/ui/issues/issue-29276.rs
+++ b/src/test/ui/issues/issue-29276.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct S([u8; { struct Z; 0 }]);
 
diff --git a/src/test/ui/issues/issue-2951.rs b/src/test/ui/issues/issue-2951.rs
index e0ae3ffa624..cc52dab0245 100644
--- a/src/test/ui/issues/issue-2951.rs
+++ b/src/test/ui/issues/issue-2951.rs
@@ -4,7 +4,7 @@ fn foo<T, U>(x: T, y: U) {
     //~^  ERROR mismatched types
     //~| expected type `T`
     //~| found type `U`
-    //~| expected type parameter, found a different type parameter
+    //~| expected type parameter `T`, found type parameter `U`
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-2951.stderr b/src/test/ui/issues/issue-2951.stderr
index a6ccc4835fa..41457175290 100644
--- a/src/test/ui/issues/issue-2951.stderr
+++ b/src/test/ui/issues/issue-2951.stderr
@@ -1,8 +1,13 @@
 error[E0308]: mismatched types
   --> $DIR/issue-2951.rs:3:10
    |
+LL | fn foo<T, U>(x: T, y: U) {
+   |        -  - found type parameter
+   |        |
+   |        expected type parameter
+LL |     let mut xx = x;
 LL |     xx = y;
-   |          ^ expected type parameter, found a different type parameter
+   |          ^ expected type parameter `T`, found type parameter `U`
    |
    = note: expected type `T`
               found type `U`
diff --git a/src/test/ui/issues/issue-29516.rs b/src/test/ui/issues/issue-29516.rs
index 8966730fd87..d43367e3452 100644
--- a/src/test/ui/issues/issue-29516.rs
+++ b/src/test/ui/issues/issue-29516.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![feature(optin_builtin_traits)]
 
 auto trait NotSame {}
diff --git a/src/test/ui/issues/issue-29540.rs b/src/test/ui/issues/issue-29540.rs
index e472f71aa7f..2a4d50f613c 100644
--- a/src/test/ui/issues/issue-29540.rs
+++ b/src/test/ui/issues/issue-29540.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #[derive(Debug)]
 pub struct Config {
     pub name: String,
diff --git a/src/test/ui/issues/issue-29710.rs b/src/test/ui/issues/issue-29710.rs
index d4de756e56f..bc98d389c6e 100644
--- a/src/test/ui/issues/issue-29710.rs
+++ b/src/test/ui/issues/issue-29710.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(unused_results)]
 #![allow(dead_code)]
 
diff --git a/src/test/ui/issues/issue-29740.rs b/src/test/ui/issues/issue-29740.rs
index 50a03d86acb..20398890baf 100644
--- a/src/test/ui/issues/issue-29740.rs
+++ b/src/test/ui/issues/issue-29740.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #29740. Inefficient MIR matching algorithms
 // generated way too much code for this sort of case, leading to OOM.
diff --git a/src/test/ui/issues/issue-29743.rs b/src/test/ui/issues/issue-29743.rs
index 2598b07490e..250cd7e1b25 100644
--- a/src/test/ui/issues/issue-29743.rs
+++ b/src/test/ui/issues/issue-29743.rs
@@ -1,5 +1,4 @@
-//
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     let mut i = [1, 2, 3];
diff --git a/src/test/ui/issues/issue-31260.rs b/src/test/ui/issues/issue-31260.rs
index 608900301e0..4db7445b025 100644
--- a/src/test/ui/issues/issue-31260.rs
+++ b/src/test/ui/issues/issue-31260.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 pub struct Struct<K: 'static> {
     pub field: K,
diff --git a/src/test/ui/issues/issue-3149.rs b/src/test/ui/issues/issue-3149.rs
index da3fe9ad6ec..6ab3bc846a3 100644
--- a/src/test/ui/issues/issue-3149.rs
+++ b/src/test/ui/issues/issue-3149.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-31597.rs b/src/test/ui/issues/issue-31597.rs
index 1d28a91ea7e..2872be6d6c8 100644
--- a/src/test/ui/issues/issue-31597.rs
+++ b/src/test/ui/issues/issue-31597.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait Make {
     type Out;
diff --git a/src/test/ui/issues/issue-32324.rs b/src/test/ui/issues/issue-32324.rs
index eaad98d6785..2df547b2e0c 100644
--- a/src/test/ui/issues/issue-32324.rs
+++ b/src/test/ui/issues/issue-32324.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 trait Resources {
diff --git a/src/test/ui/issues/issue-32995-2.rs b/src/test/ui/issues/issue-32995-2.rs
index 2234f68f246..e713a64d3f5 100644
--- a/src/test/ui/issues/issue-32995-2.rs
+++ b/src/test/ui/issues/issue-32995-2.rs
@@ -1,13 +1,9 @@
-#![allow(unused)]
-
 fn main() {
     { fn f<X: ::std::marker()::Send>() {} }
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 
     { fn f() -> impl ::std::marker()::Send { } }
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 }
 
 #[derive(Clone)]
@@ -15,4 +11,3 @@ struct X;
 
 impl ::std::marker()::Copy for X {}
 //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-//~| WARN previously accepted
diff --git a/src/test/ui/issues/issue-32995-2.stderr b/src/test/ui/issues/issue-32995-2.stderr
index 976e3064db6..6c2d772a233 100644
--- a/src/test/ui/issues/issue-32995-2.stderr
+++ b/src/test/ui/issues/issue-32995-2.stderr
@@ -1,30 +1,21 @@
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:4:22
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995-2.rs:2:22
    |
 LL |     { fn f<X: ::std::marker()::Send>() {} }
-   |                      ^^^^^^^^
-   |
-   = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                      ^^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:8:29
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995-2.rs:5:29
    |
 LL |     { fn f() -> impl ::std::marker()::Send { } }
-   |                             ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                             ^^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:16:13
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995-2.rs:12:13
    |
 LL | impl ::std::marker()::Copy for X {}
-   |             ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |             ^^^^^^^^ only `Fn` traits may use parentheses
 
 error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0214`.
diff --git a/src/test/ui/issues/issue-32995.rs b/src/test/ui/issues/issue-32995.rs
index 3526deffc79..0d07a76939f 100644
--- a/src/test/ui/issues/issue-32995.rs
+++ b/src/test/ui/issues/issue-32995.rs
@@ -1,33 +1,24 @@
-#![allow(unused)]
-
 fn main() {
     let x: usize() = 1;
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 
     let b: ::std::boxed()::Box<_> = Box::new(1);
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 
     let p = ::std::str::()::from_utf8(b"foo").unwrap();
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 
     let p = ::std::str::from_utf8::()(b"foo").unwrap();
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 
     let o : Box<dyn (::std::marker()::Send)> = Box::new(1);
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 
     let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1);
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 }
 
 fn foo<X:Default>() {
     let d : X() = Default::default();
     //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
-    //~| WARN previously accepted
 }
diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr
index 724e82a59dc..b868011b99b 100644
--- a/src/test/ui/issues/issue-32995.stderr
+++ b/src/test/ui/issues/issue-32995.stderr
@@ -1,66 +1,45 @@
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:4:12
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:2:12
    |
 LL |     let x: usize() = 1;
-   |            ^^^^^^^
-   |
-   = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |            ^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:8:19
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:5:19
    |
 LL |     let b: ::std::boxed()::Box<_> = Box::new(1);
-   |                   ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                   ^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:12:20
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:8:20
    |
 LL |     let p = ::std::str::()::from_utf8(b"foo").unwrap();
-   |                    ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                    ^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:16:25
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:11:25
    |
 LL |     let p = ::std::str::from_utf8::()(b"foo").unwrap();
-   |                         ^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                         ^^^^^^^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:20:29
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:14:29
    |
 LL |     let o : Box<dyn (::std::marker()::Send)> = Box::new(1);
-   |                             ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                             ^^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:24:35
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:17:35
    |
 LL |     let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1);
-   |                                   ^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                                   ^^^^^^^^ only `Fn` traits may use parentheses
 
-error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:30:13
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/issue-32995.rs:22:13
    |
 LL |     let d : X() = Default::default();
-   |             ^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |             ^^^ only `Fn` traits may use parentheses
 
 error: aborting due to 7 previous errors
 
+For more information about this error, try `rustc --explain E0214`.
diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.rs b/src/test/ui/issues/issue-33140-traitobject-crate.rs
index 03567b20a8f..46b68f1c9fe 100644
--- a/src/test/ui/issues/issue-33140-traitobject-crate.rs
+++ b/src/test/ui/issues/issue-33140-traitobject-crate.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(order_dependent_trait_objects)]
 
@@ -83,9 +83,15 @@ unsafe impl<T> Trait for dyn (::std::iter::Iterator<Item=T>) + Send + Sync { }
 unsafe impl Trait for dyn (::std::marker::Send) + Send { }
 unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
 unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
+//~^ WARNING conflicting implementations of trait `Trait` for type
+//~| WARNING this was previously accepted by the compiler but is being phased out
 unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
+//~^ WARNING conflicting implementations of trait `Trait` for type
+//~| WARNING this was previously accepted by the compiler but is being phased out
 unsafe impl Trait for dyn (::std::marker::Sync) + Sync { }
 unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
+//~^ WARNING conflicting implementations of trait `Trait` for type
+//~| WARNING this was previously accepted by the compiler but is being phased out
 unsafe impl Trait for dyn (::std::ops::Drop) + Send { }
 unsafe impl Trait for dyn (::std::ops::Drop) + Sync { }
 unsafe impl Trait for dyn (::std::ops::Drop) + Send + Sync { }
diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.stderr b/src/test/ui/issues/issue-33140-traitobject-crate.stderr
index 76db98aa38b..f31ea9391ab 100644
--- a/src/test/ui/issues/issue-33140-traitobject-crate.stderr
+++ b/src/test/ui/issues/issue-33140-traitobject-crate.stderr
@@ -15,10 +15,11 @@ LL | #![warn(order_dependent_trait_objects)]
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
 warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:86:1
+  --> $DIR/issue-33140-traitobject-crate.rs:88:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
    | ------------------------------------------------------------- first implementation here
+...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
    |
@@ -26,11 +27,11 @@ LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
    = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
 
 warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
-  --> $DIR/issue-33140-traitobject-crate.rs:88:1
+  --> $DIR/issue-33140-traitobject-crate.rs:92:1
    |
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
    | ------------------------------------------------------ first implementation here
-LL | unsafe impl Trait for dyn (::std::marker::Sync) + Sync { }
+...
 LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
    |
diff --git a/src/test/ui/issues/issue-33264.rs b/src/test/ui/issues/issue-33264.rs
index e6370bc84de..31638b00439 100644
--- a/src/test/ui/issues/issue-33264.rs
+++ b/src/test/ui/issues/issue-33264.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // only-x86_64
 
 #![allow(dead_code, non_upper_case_globals)]
diff --git a/src/test/ui/issues/issue-33287.rs b/src/test/ui/issues/issue-33287.rs
index 036a1e37688..770eb7c02bb 100644
--- a/src/test/ui/issues/issue-33287.rs
+++ b/src/test/ui/issues/issue-33287.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 const A: [u32; 1] = [0];
diff --git a/src/test/ui/issues/issue-3344.stderr b/src/test/ui/issues/issue-3344.stderr
index 6593e07b189..271fbb6c874 100644
--- a/src/test/ui/issues/issue-3344.stderr
+++ b/src/test/ui/issues/issue-3344.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
 LL | impl PartialOrd for Thing {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
    |
-   = note: `partial_cmp` from trait: `fn(&Self, &Rhs) -> std::option::Option<std::cmp::Ordering>`
+   = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> std::option::Option<std::cmp::Ordering> { unimplemented!() }`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-33903.rs b/src/test/ui/issues/issue-33903.rs
index 6a8305dabeb..613aa121a47 100644
--- a/src/test/ui/issues/issue-33903.rs
+++ b/src/test/ui/issues/issue-33903.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Issue 33903:
 // Built-in indexing should be used even when the index is not
diff --git a/src/test/ui/issues/issue-34194.rs b/src/test/ui/issues/issue-34194.rs
index ea89e4cbdeb..6dce556e9e3 100644
--- a/src/test/ui/issues/issue-34194.rs
+++ b/src/test/ui/issues/issue-34194.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 
 struct A {
diff --git a/src/test/ui/issues/issue-3424.rs b/src/test/ui/issues/issue-3424.rs
index a8ff03e2a24..43d75a6525f 100644
--- a/src/test/ui/issues/issue-3424.rs
+++ b/src/test/ui/issues/issue-3424.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 // rustc --test ignores2.rs && ./ignores2
diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr
index 8d52e08374a..a3749487ac9 100644
--- a/src/test/ui/issues/issue-34334.stderr
+++ b/src/test/ui/issues/issue-34334.stderr
@@ -14,7 +14,7 @@ error: expected one of `,` or `>`, found `=`
   --> $DIR/issue-34334.rs:2:29
    |
 LL |     let sr: Vec<(u32, _, _) = vec![];
-   |         ---                 ^ expected one of `,` or `>` here
+   |         ---                 ^ expected one of `,` or `>`
    |         | |
    |         | help: use `=` if you meant to assign
    |         while parsing the type for `sr`
diff --git a/src/test/ui/issues/issue-34751.rs b/src/test/ui/issues/issue-34751.rs
index a921cb50612..6309c0a0257 100644
--- a/src/test/ui/issues/issue-34751.rs
+++ b/src/test/ui/issues/issue-34751.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)'
 
diff --git a/src/test/ui/issues/issue-34780.rs b/src/test/ui/issues/issue-34780.rs
index 3202ef64021..fbedad35b86 100644
--- a/src/test/ui/issues/issue-34780.rs
+++ b/src/test/ui/issues/issue-34780.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(stable_features)]
 #![feature(associated_consts)]
 
diff --git a/src/test/ui/issues/issue-35376.rs b/src/test/ui/issues/issue-35376.rs
index b415d655405..eb139ec4d7f 100644
--- a/src/test/ui/issues/issue-35376.rs
+++ b/src/test/ui/issues/issue-35376.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![feature(specialization)]
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-35546.rs b/src/test/ui/issues/issue-35546.rs
index e2f0f98d57b..004679a6240 100644
--- a/src/test/ui/issues/issue-35546.rs
+++ b/src/test/ui/issues/issue-35546.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // Regression test for #35546. Check that we are able to codegen
 // this. Before we had problems because of the drop glue signature
diff --git a/src/test/ui/issues/issue-3563-2.rs b/src/test/ui/issues/issue-3563-2.rs
index 5ab668eed18..88a449b85b8 100644
--- a/src/test/ui/issues/issue-3563-2.rs
+++ b/src/test/ui/issues/issue-3563-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Canvas {
diff --git a/src/test/ui/issues/issue-36075.rs b/src/test/ui/issues/issue-36075.rs
index 00c8cf1fb8a..bc5bdc3ff9e 100644
--- a/src/test/ui/issues/issue-36075.rs
+++ b/src/test/ui/issues/issue-36075.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait DeclarationParser {
     type Declaration;
diff --git a/src/test/ui/issues/issue-3609.rs b/src/test/ui/issues/issue-3609.rs
index e8fc073a158..57ff12a08ce 100644
--- a/src/test/ui/issues/issue-3609.rs
+++ b/src/test/ui/issues/issue-3609.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
diff --git a/src/test/ui/issues/issue-36744-without-calls.rs b/src/test/ui/issues/issue-36744-without-calls.rs
index 4d03d9bbca6..dc5dc4f13c0 100644
--- a/src/test/ui/issues/issue-36744-without-calls.rs
+++ b/src/test/ui/issues/issue-36744-without-calls.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // Tests for an LLVM abort when storing a lifetime-parametric fn into
 // context that is expecting one that is not lifetime-parametric
 // (i.e., has no `for <'_>`).
diff --git a/src/test/ui/issues/issue-37323.rs b/src/test/ui/issues/issue-37323.rs
index 61c8029adf5..55f5c5a9581 100644
--- a/src/test/ui/issues/issue-37323.rs
+++ b/src/test/ui/issues/issue-37323.rs
@@ -1,4 +1,5 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
+// compile-flags: -Zsave-analysis
 
 #![feature(rustc_attrs)]
 #![allow(warnings)]
diff --git a/src/test/ui/issues/issue-37655.rs b/src/test/ui/issues/issue-37655.rs
index fecff4e0246..416854d66f3 100644
--- a/src/test/ui/issues/issue-37655.rs
+++ b/src/test/ui/issues/issue-37655.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for #37655. The problem was a false edge created by
 // coercion that wound up requiring that `'a` (in `split()`) outlive
 // `'b`, which shouldn't be necessary.
diff --git a/src/test/ui/issues/issue-37725.rs b/src/test/ui/issues/issue-37725.rs
index eefdc72f0c3..965ecde6f3c 100644
--- a/src/test/ui/issues/issue-37725.rs
+++ b/src/test/ui/issues/issue-37725.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 trait Foo {
     fn foo(&self);
diff --git a/src/test/ui/issues/issue-37733.rs b/src/test/ui/issues/issue-37733.rs
index c1df28331a5..e211e2c3336 100644
--- a/src/test/ui/issues/issue-37733.rs
+++ b/src/test/ui/issues/issue-37733.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 type A = for<> fn();
 
diff --git a/src/test/ui/issues/issue-38715-rpass.rs b/src/test/ui/issues/issue-38715-rpass.rs
deleted file mode 100644
index e3c3a027f3c..00000000000
--- a/src/test/ui/issues/issue-38715-rpass.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// run-pass
-// aux-build:issue-38715.rs
-// aux-build:issue-38715-modern.rs
-
-// Test that `#[macro_export] macro_rules!` shadow earlier `#[macro_export] macro_rules!`
-
-#[macro_use]
-extern crate issue_38715;
-#[macro_use]
-extern crate issue_38715_modern;
-
-fn main() {
-    foo!();
-    foo_modern!();
-}
diff --git a/src/test/ui/issues/issue-38715.rs b/src/test/ui/issues/issue-38715.rs
index 850ffcdabe4..7e9defab588 100644
--- a/src/test/ui/issues/issue-38715.rs
+++ b/src/test/ui/issues/issue-38715.rs
@@ -3,6 +3,5 @@ macro_rules! foo { ($i:ident) => {} }
 
 #[macro_export]
 macro_rules! foo { () => {} } //~ ERROR a macro named `foo` has already been exported
-                              //~| WARN this was previously accepted
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-38715.stderr b/src/test/ui/issues/issue-38715.stderr
index 02b96d2d244..d7c4f88ff50 100644
--- a/src/test/ui/issues/issue-38715.stderr
+++ b/src/test/ui/issues/issue-38715.stderr
@@ -4,9 +4,6 @@ error: a macro named `foo` has already been exported
 LL | macro_rules! foo { () => {} }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `foo` already exported
    |
-   = note: `#[deny(duplicate_macro_exports)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition!
-   = note: for more information, see issue #35896 <https://github.com/rust-lang/rust/issues/35896>
 note: previous macro export is now shadowed
   --> $DIR/issue-38715.rs:2:1
    |
diff --git a/src/test/ui/issues/issue-38727.rs b/src/test/ui/issues/issue-38727.rs
index 3c728e9def1..2d418b65269 100644
--- a/src/test/ui/issues/issue-38727.rs
+++ b/src/test/ui/issues/issue-38727.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #[repr(u64)]
 enum A {
diff --git a/src/test/ui/issues/issue-3874.rs b/src/test/ui/issues/issue-3874.rs
index b290da52080..f9553d88d24 100644
--- a/src/test/ui/issues/issue-3874.rs
+++ b/src/test/ui/issues/issue-3874.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-38763.rs b/src/test/ui/issues/issue-38763.rs
index 6e6de09225f..c84846bc4e8 100644
--- a/src/test/ui/issues/issue-38763.rs
+++ b/src/test/ui/issues/issue-38763.rs
@@ -4,6 +4,7 @@
 #[repr(C)]
 pub struct Foo(i128);
 
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub extern "C" fn foo(x: Foo) -> Foo { x }
 
diff --git a/src/test/ui/issues/issue-38875/issue-38875.rs b/src/test/ui/issues/issue-38875/issue-38875.rs
index 68981eaf2b5..124e4d6fd41 100644
--- a/src/test/ui/issues/issue-38875/issue-38875.rs
+++ b/src/test/ui/issues/issue-38875/issue-38875.rs
@@ -1,5 +1,5 @@
 // aux-build:issue-38875-b.rs
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 extern crate issue_38875_b;
 
diff --git a/src/test/ui/issues/issue-3888-2.rs b/src/test/ui/issues/issue-3888-2.rs
index 3d4b184ab6b..d1ef914bdec 100644
--- a/src/test/ui/issues/issue-3888-2.rs
+++ b/src/test/ui/issues/issue-3888-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-39089.rs b/src/test/ui/issues/issue-39089.rs
index 12ca9e1da0f..c7d4f8bd320 100644
--- a/src/test/ui/issues/issue-39089.rs
+++ b/src/test/ui/issues/issue-39089.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 fn f<T: ?for<'a> Sized>() {}
 
diff --git a/src/test/ui/issues/issue-39467.rs b/src/test/ui/issues/issue-39467.rs
index 86e67560008..397751e4ec3 100644
--- a/src/test/ui/issues/issue-39467.rs
+++ b/src/test/ui/issues/issue-39467.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 macro_rules! expr { () => { () } }
 
diff --git a/src/test/ui/issues/issue-39616.stderr b/src/test/ui/issues/issue-39616.stderr
index 75eb55fa50b..74e94eda51f 100644
--- a/src/test/ui/issues/issue-39616.stderr
+++ b/src/test/ui/issues/issue-39616.stderr
@@ -8,7 +8,7 @@ error: expected one of `)`, `,`, `->`, `where`, or `{`, found `]`
   --> $DIR/issue-39616.rs:1:16
    |
 LL | fn foo(a: [0; 1]) {}
-   |                ^ expected one of `)`, `,`, `->`, `where`, or `{` here
+   |                ^ expected one of `)`, `,`, `->`, `where`, or `{`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-39720.rs b/src/test/ui/issues/issue-39720.rs
index a3baa361d57..1a4775fc960 100644
--- a/src/test/ui/issues/issue-39720.rs
+++ b/src/test/ui/issues/issue-39720.rs
@@ -5,12 +5,12 @@
 
 #![feature(repr_simd, platform_intrinsics)]
 
-#[repr(C)]
+#[repr(C)] //~ WARNING conflicting representation hints
 #[repr(simd)]
 #[derive(Copy, Clone, Debug)]
 pub struct char3(pub i8, pub i8, pub i8);
 
-#[repr(C)]
+#[repr(C)]  //~ WARNING conflicting representation hints
 #[repr(simd)]
 #[derive(Copy, Clone, Debug)]
 pub struct short3(pub i16, pub i16, pub i16);
diff --git a/src/test/ui/issues/issue-3979-2.rs b/src/test/ui/issues/issue-3979-2.rs
index f3fcfd2c8fb..4ec128a4586 100644
--- a/src/test/ui/issues/issue-3979-2.rs
+++ b/src/test/ui/issues/issue-3979-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait A {
diff --git a/src/test/ui/issues/issue-39848.stderr b/src/test/ui/issues/issue-39848.stderr
index fa87967432d..47aa8e17a30 100644
--- a/src/test/ui/issues/issue-39848.stderr
+++ b/src/test/ui/issues/issue-39848.stderr
@@ -2,7 +2,7 @@ error: expected `{`, found `foo`
   --> $DIR/issue-39848.rs:8:19
    |
 LL |         if $tgt.has_$field() {}
-   |         --                 - help: try placing this code inside a block: `{ ) }`
+   |         --                -- help: try placing this code inside a block: `{ () }`
    |         |
    |         this `if` statement has a condition, but no block
 ...
diff --git a/src/test/ui/issues/issue-3991.rs b/src/test/ui/issues/issue-3991.rs
index b8ff671bf38..4851eddf533 100644
--- a/src/test/ui/issues/issue-3991.rs
+++ b/src/test/ui/issues/issue-3991.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-39984.rs b/src/test/ui/issues/issue-39984.rs
index 613aad1a34f..1c9ae26cab2 100644
--- a/src/test/ui/issues/issue-39984.rs
+++ b/src/test/ui/issues/issue-39984.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unreachable_code)]
 // Regression test for issue #39984.
diff --git a/src/test/ui/issues/issue-40136.rs b/src/test/ui/issues/issue-40136.rs
index 412ddafdd97..29d3fc2d560 100644
--- a/src/test/ui/issues/issue-40136.rs
+++ b/src/test/ui/issues/issue-40136.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 macro_rules! m { () => { 0 } }
diff --git a/src/test/ui/issues/issue-4025.rs b/src/test/ui/issues/issue-4025.rs
index 6e009ba6eb4..dc534c64c60 100644
--- a/src/test/ui/issues/issue-4025.rs
+++ b/src/test/ui/issues/issue-4025.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_mut)]
 /*
diff --git a/src/test/ui/issues/issue-40510-2.rs b/src/test/ui/issues/issue-40510-2.rs
index 499fa8a04f2..3ae84be0578 100644
--- a/src/test/ui/issues/issue-40510-2.rs
+++ b/src/test/ui/issues/issue-40510-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused)]
 
 fn f() {
diff --git a/src/test/ui/issues/issue-40510-4.rs b/src/test/ui/issues/issue-40510-4.rs
index 5fad7e4a629..48bb8d36f55 100644
--- a/src/test/ui/issues/issue-40510-4.rs
+++ b/src/test/ui/issues/issue-40510-4.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused)]
 
 fn f() {
diff --git a/src/test/ui/issues/issue-40962.rs b/src/test/ui/issues/issue-40962.rs
index c051133cbed..7b91c06819f 100644
--- a/src/test/ui/issues/issue-40962.rs
+++ b/src/test/ui/issues/issue-40962.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 macro_rules! m {
     ($i:meta) => {
         #[derive($i)]
diff --git a/src/test/ui/issues/issue-41272.rs b/src/test/ui/issues/issue-41272.rs
index 9cd20036286..1f4da46f894 100644
--- a/src/test/ui/issues/issue-41272.rs
+++ b/src/test/ui/issues/issue-41272.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Foo;
 
diff --git a/src/test/ui/issues/issue-41298.rs b/src/test/ui/issues/issue-41298.rs
index c719664de0d..a1b4de39bee 100644
--- a/src/test/ui/issues/issue-41298.rs
+++ b/src/test/ui/issues/issue-41298.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Function<T, F> { t: T, f: F }
 
diff --git a/src/test/ui/issues/issue-41628.rs b/src/test/ui/issues/issue-41628.rs
index 92369fdcd49..92159824eb0 100644
--- a/src/test/ui/issues/issue-41628.rs
+++ b/src/test/ui/issues/issue-41628.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(dead_code)]
 
 #[used]
diff --git a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
index 6c6cec25a9a..3d678ba041b 100644
--- a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
+++ b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #41936. The coerce-unsized trait check in
 // coherence was using subtyping, which triggered variance
diff --git a/src/test/ui/issues/issue-41998.rs b/src/test/ui/issues/issue-41998.rs
index 2f2842598fc..7696a3108d1 100644
--- a/src/test/ui/issues/issue-41998.rs
+++ b/src/test/ui/issues/issue-41998.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 
 fn main() {
diff --git a/src/test/ui/issues/issue-42467.rs b/src/test/ui/issues/issue-42467.rs
index f1a55169ffd..afa1bcd13fc 100644
--- a/src/test/ui/issues/issue-42467.rs
+++ b/src/test/ui/issues/issue-42467.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Foo<T>(T);
 
diff --git a/src/test/ui/issues/issue-42956.rs b/src/test/ui/issues/issue-42956.rs
index 8cf0ae00306..e6b3f9ffab7 100644
--- a/src/test/ui/issues/issue-42956.rs
+++ b/src/test/ui/issues/issue-42956.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(stable_features)]
 #![feature(associated_consts)]
diff --git a/src/test/ui/issues/issue-43057.rs b/src/test/ui/issues/issue-43057.rs
index 7e1d5036f37..4ce52af434c 100644
--- a/src/test/ui/issues/issue-43057.rs
+++ b/src/test/ui/issues/issue-43057.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused)]
 
 macro_rules! column {
diff --git a/src/test/ui/issues/issue-43357.rs b/src/test/ui/issues/issue-43357.rs
index 3090e229b6d..474c9765595 100644
--- a/src/test/ui/issues/issue-43357.rs
+++ b/src/test/ui/issues/issue-43357.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait Trait {
     type Output;
diff --git a/src/test/ui/issues/issue-43398.rs b/src/test/ui/issues/issue-43398.rs
index ae52e8f3f6b..f0b762c6254 100644
--- a/src/test/ui/issues/issue-43398.rs
+++ b/src/test/ui/issues/issue-43398.rs
@@ -7,9 +7,7 @@
 enum Big { A, B }
 
 fn main() {
-    unsafe {
-        println!("{} {:?}",
-            std::intrinsics::discriminant_value(&Big::A),
-            std::mem::discriminant(&Big::B));
-    }
+    println!("{} {:?}",
+        std::intrinsics::discriminant_value(&Big::A),
+        std::mem::discriminant(&Big::B));
 }
diff --git a/src/test/ui/issues/issue-43483.rs b/src/test/ui/issues/issue-43483.rs
index f071d110f32..76dd1c2eb58 100644
--- a/src/test/ui/issues/issue-43483.rs
+++ b/src/test/ui/issues/issue-43483.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 trait VecN {
diff --git a/src/test/ui/issues/issue-44005.rs b/src/test/ui/issues/issue-44005.rs
index f6fe9fcbd89..041fcdbf823 100644
--- a/src/test/ui/issues/issue-44005.rs
+++ b/src/test/ui/issues/issue-44005.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 pub trait Foo<'a> {
     type Bar;
     fn foo(&'a self) -> Self::Bar;
diff --git a/src/test/ui/issues/issue-44021.stderr b/src/test/ui/issues/issue-44021.stderr
index 94500087e55..b888cd989a6 100644
--- a/src/test/ui/issues/issue-44021.stderr
+++ b/src/test/ui/issues/issue-44021.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `}`
   --> $DIR/issue-44021.rs:3:18
    |
 LL |     fn f() {|x, y}
-   |                  ^ expected one of `:`, `@`, or `|` here
+   |                  ^ expected one of `:`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs
index 42f30bf3023..a4903ed2cb4 100644
--- a/src/test/ui/issues/issue-44056.rs
+++ b/src/test/ui/issues/issue-44056.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass (FIXME(55996): should be run on targets supporting avx)
 // only-x86_64
 // no-prefer-dynamic
 // compile-flags: -Ctarget-feature=+avx -Clto
diff --git a/src/test/ui/issues/issue-44247.rs b/src/test/ui/issues/issue-44247.rs
index ef244e03857..3544880fade 100644
--- a/src/test/ui/issues/issue-44247.rs
+++ b/src/test/ui/issues/issue-44247.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait T {
     type X;
diff --git a/src/test/ui/issues/issue-44373-2.rs b/src/test/ui/issues/issue-44373-2.rs
index 7fdc4b1ee5b..194ce1dca77 100644
--- a/src/test/ui/issues/issue-44373-2.rs
+++ b/src/test/ui/issues/issue-44373-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 struct Foo(bool);
diff --git a/src/test/ui/issues/issue-4464.rs b/src/test/ui/issues/issue-4464.rs
index 13df6112482..7ac107150a0 100644
--- a/src/test/ui/issues/issue-4464.rs
+++ b/src/test/ui/issues/issue-4464.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-44730.rs b/src/test/ui/issues/issue-44730.rs
index 93f0445d343..0493811b279 100644
--- a/src/test/ui/issues/issue-44730.rs
+++ b/src/test/ui/issues/issue-44730.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 //! dox
 
 #![deny(missing_docs)]
diff --git a/src/test/ui/issues/issue-44851.rs b/src/test/ui/issues/issue-44851.rs
index 735678047a5..23daaeb0f00 100644
--- a/src/test/ui/issues/issue-44851.rs
+++ b/src/test/ui/issues/issue-44851.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 macro_rules! a {
     () => { "a" }
 }
diff --git a/src/test/ui/issues/issue-45425.rs b/src/test/ui/issues/issue-45425.rs
index 99e018ba6c8..10ce374eada 100644
--- a/src/test/ui/issues/issue-45425.rs
+++ b/src/test/ui/issues/issue-45425.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::ops::Add;
 
diff --git a/src/test/ui/issues/issue-46959.rs b/src/test/ui/issues/issue-46959.rs
index 86f1158c198..3611a956836 100644
--- a/src/test/ui/issues/issue-46959.rs
+++ b/src/test/ui/issues/issue-46959.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(non_camel_case_types)]
 
 #[allow(dead_code)]
diff --git a/src/test/ui/issues/issue-46964.rs b/src/test/ui/issues/issue-46964.rs
index 9cf53973d87..28fa92f2091 100644
--- a/src/test/ui/issues/issue-46964.rs
+++ b/src/test/ui/issues/issue-46964.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 mod my_mod {
     #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
     pub struct Name<'a> {
diff --git a/src/test/ui/issues/issue-47094.rs b/src/test/ui/issues/issue-47094.rs
index f17d4f88d90..97da984d4af 100644
--- a/src/test/ui/issues/issue-47094.rs
+++ b/src/test/ui/issues/issue-47094.rs
@@ -1,12 +1,12 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
-#[repr(C,u8)]
+#[repr(C,u8)] //~ WARNING conflicting representation hints
 enum Foo {
     A,
     B,
 }
 
-#[repr(C)]
+#[repr(C)] //~ WARNING conflicting representation hints
 #[repr(u8)]
 enum Bar {
     A,
diff --git a/src/test/ui/issues/issue-47309.rs b/src/test/ui/issues/issue-47309.rs
index 03092022d4d..abed9687b49 100644
--- a/src/test/ui/issues/issue-47309.rs
+++ b/src/test/ui/issues/issue-47309.rs
@@ -3,7 +3,7 @@
 // See https://github.com/rust-lang/rust/issues/47309
 
 // compile-flags:-Clink-dead-code
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 #![crate_type="rlib"]
 
diff --git a/src/test/ui/issues/issue-47673.rs b/src/test/ui/issues/issue-47673.rs
index 0d813e2fad2..b5f0febfbee 100644
--- a/src/test/ui/issues/issue-47673.rs
+++ b/src/test/ui/issues/issue-47673.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_imports)]
 
 use {{}, {}};
diff --git a/src/test/ui/issues/issue-47703-1.rs b/src/test/ui/issues/issue-47703-1.rs
index 95738828647..61d684c2a81 100644
--- a/src/test/ui/issues/issue-47703-1.rs
+++ b/src/test/ui/issues/issue-47703-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct AtomicRefMut<'a> {
     value: &'a mut i32,
diff --git a/src/test/ui/issues/issue-47703-tuple.rs b/src/test/ui/issues/issue-47703-tuple.rs
index 1b285f219dc..bad187ead81 100644
--- a/src/test/ui/issues/issue-47703-tuple.rs
+++ b/src/test/ui/issues/issue-47703-tuple.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct WithDrop;
 
diff --git a/src/test/ui/issues/issue-47703.rs b/src/test/ui/issues/issue-47703.rs
index dbf49c7621f..38be6f5d2a9 100644
--- a/src/test/ui/issues/issue-47703.rs
+++ b/src/test/ui/issues/issue-47703.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct MyStruct<'a> {
     field: &'a mut (),
diff --git a/src/test/ui/issues/issue-47722.rs b/src/test/ui/issues/issue-47722.rs
index b3c344257b6..5645a634343 100644
--- a/src/test/ui/issues/issue-47722.rs
+++ b/src/test/ui/issues/issue-47722.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Tests that automatic coercions from &mut T to *mut T
 // allow borrows of T to expire immediately - essentially, that
diff --git a/src/test/ui/issues/issue-47789.rs b/src/test/ui/issues/issue-47789.rs
index 28671db0998..32dd909b2e9 100644
--- a/src/test/ui/issues/issue-47789.rs
+++ b/src/test/ui/issues/issue-47789.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(non_upper_case_globals)]
 
 static mut x: &'static u32 = &0;
diff --git a/src/test/ui/issues/issue-4830.rs b/src/test/ui/issues/issue-4830.rs
index 3724bb6393c..a8553bd6bf3 100644
--- a/src/test/ui/issues/issue-4830.rs
+++ b/src/test/ui/issues/issue-4830.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-48551.rs b/src/test/ui/issues/issue-48551.rs
index 903b2e29929..b95a4832bb2 100644
--- a/src/test/ui/issues/issue-48551.rs
+++ b/src/test/ui/issues/issue-48551.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for #48551. Covers a case where duplicate candidates
 // arose during associated type projection.
 
diff --git a/src/test/ui/issues/issue-49556.rs b/src/test/ui/issues/issue-49556.rs
index d3c6d17f416..c8c172f0e2f 100644
--- a/src/test/ui/issues/issue-49556.rs
+++ b/src/test/ui/issues/issue-49556.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 fn iter<'a>(data: &'a [usize]) -> impl Iterator<Item = usize> + 'a {
     data.iter()
         .map(
diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs
index 767e06c4e90..98de014e90b 100644
--- a/src/test/ui/issues/issue-49579.rs
+++ b/src/test/ui/issues/issue-49579.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn fibs(n: u32) -> impl Iterator<Item=u128> {
     (0 .. n)
diff --git a/src/test/ui/issues/issue-50187.rs b/src/test/ui/issues/issue-50187.rs
index f530c3853e3..4b0aeaab410 100644
--- a/src/test/ui/issues/issue-50187.rs
+++ b/src/test/ui/issues/issue-50187.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(decl_macro)]
 
diff --git a/src/test/ui/issues/issue-50411.rs b/src/test/ui/issues/issue-50411.rs
index a32faa69841..1bf12707817 100644
--- a/src/test/ui/issues/issue-50411.rs
+++ b/src/test/ui/issues/issue-50411.rs
@@ -4,7 +4,7 @@
 // second time. Uncool.
 
 // compile-flags:-Zmir-opt-level=3
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 fn main() {
     let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count();
diff --git a/src/test/ui/issues/issue-50471.rs b/src/test/ui/issues/issue-50471.rs
index e728e45e60b..7278c392d54 100644
--- a/src/test/ui/issues/issue-50471.rs
+++ b/src/test/ui/issues/issue-50471.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     assert!({false});
diff --git a/src/test/ui/issues/issue-50518.rs b/src/test/ui/issues/issue-50518.rs
index 653b52902d2..1e7b7794929 100644
--- a/src/test/ui/issues/issue-50518.rs
+++ b/src/test/ui/issues/issue-50518.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 use std::marker::PhantomData;
 
 struct Meta<A> {
diff --git a/src/test/ui/issues/issue-50761.rs b/src/test/ui/issues/issue-50761.rs
index 59d4f9afdaa..1bf494ba8f9 100644
--- a/src/test/ui/issues/issue-50761.rs
+++ b/src/test/ui/issues/issue-50761.rs
@@ -1,6 +1,6 @@
 // Confirm that we don't accidentally divide or mod by zero in llvm_type
 
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 mod a {
     pub trait A {}
diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs
index b170e09d02d..d38eb826678 100644
--- a/src/test/ui/issues/issue-50993.rs
+++ b/src/test/ui/issues/issue-50993.rs
@@ -1,5 +1,5 @@
 // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf`
 
 #![feature(no_core)]
diff --git a/src/test/ui/issues/issue-51582.rs b/src/test/ui/issues/issue-51582.rs
index 63ef05729bc..40a70c623a7 100644
--- a/src/test/ui/issues/issue-51582.rs
+++ b/src/test/ui/issues/issue-51582.rs
@@ -14,5 +14,5 @@ fn main() {
     assert_eq!(1, make_b() as u8);
     assert_eq!(1, make_b() as i32);
     assert_eq!(1, make_b() as u32);
-    assert_eq!(1, unsafe { std::intrinsics::discriminant_value(&make_b()) });
+    assert_eq!(1, std::intrinsics::discriminant_value(&make_b()));
 }
diff --git a/src/test/ui/issues/issue-51655.rs b/src/test/ui/issues/issue-51655.rs
index c2ad60fd8cf..36fd90dabed 100644
--- a/src/test/ui/issues/issue-51655.rs
+++ b/src/test/ui/issues/issue-51655.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 const PATH_DOT: &[u8] = &[b'.'];
diff --git a/src/test/ui/issues/issue-51907.rs b/src/test/ui/issues/issue-51907.rs
index 3691fe19117..1946611a17c 100644
--- a/src/test/ui/issues/issue-51907.rs
+++ b/src/test/ui/issues/issue-51907.rs
@@ -6,7 +6,9 @@ trait Foo {
 
 struct Bar;
 impl Foo for Bar {
+    #[allow(improper_ctypes)]
     extern fn borrow(&self) {}
+    #[allow(improper_ctypes)]
     extern fn take(self: Box<Self>) {}
 }
 
diff --git a/src/test/ui/issues/issue-51947.rs b/src/test/ui/issues/issue-51947.rs
index b5ebf156a27..c877fb8aef1 100644
--- a/src/test/ui/issues/issue-51947.rs
+++ b/src/test/ui/issues/issue-51947.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 #![crate_type = "lib"]
 #![feature(linkage)]
diff --git a/src/test/ui/issues/issue-52057.rs b/src/test/ui/issues/issue-52057.rs
index 911983445e6..98f49fe8f55 100644
--- a/src/test/ui/issues/issue-52057.rs
+++ b/src/test/ui/issues/issue-52057.rs
@@ -7,7 +7,6 @@
 pub trait Parser {
     type Input;
 
-    #[inline(always)]
     fn parse_first(input: &mut Self::Input);
 }
 
diff --git a/src/test/ui/issues/issue-52057.stderr b/src/test/ui/issues/issue-52057.stderr
deleted file mode 100644
index 33b79dba73e..00000000000
--- a/src/test/ui/issues/issue-52057.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: `#[inline]` is ignored on function prototypes
-  --> $DIR/issue-52057.rs:10:5
-   |
-LL |     #[inline(always)]
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(unused_attributes)]` on by default
-
diff --git a/src/test/ui/issues/issue-52496.stderr b/src/test/ui/issues/issue-52496.stderr
index 43009a15bd4..10fcc46f344 100644
--- a/src/test/ui/issues/issue-52496.stderr
+++ b/src/test/ui/issues/issue-52496.stderr
@@ -8,7 +8,7 @@ error: expected one of `,` or `}`, found `.`
   --> $DIR/issue-52496.rs:8:22
    |
 LL |     let _ = Foo { bar.into(), bat: -1, . };
-   |             ---      ^ expected one of `,` or `}` here
+   |             ---      ^ expected one of `,` or `}`
    |             |
    |             while parsing this struct
 
diff --git a/src/test/ui/issues/issue-52992.rs b/src/test/ui/issues/issue-52992.rs
index 727dd43d574..530d1a61b31 100644
--- a/src/test/ui/issues/issue-52992.rs
+++ b/src/test/ui/issues/issue-52992.rs
@@ -2,7 +2,7 @@
 // implied bounds was causing outlives relations that were not
 // properly handled.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {}
 
diff --git a/src/test/ui/issues/issue-53419.rs b/src/test/ui/issues/issue-53419.rs
index 64ac0b1c03b..892ec66afec 100644
--- a/src/test/ui/issues/issue-53419.rs
+++ b/src/test/ui/issues/issue-53419.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Foo {
     bar: dyn for<'r> Fn(usize, &'r dyn FnMut())
diff --git a/src/test/ui/issues/issue-5353.rs b/src/test/ui/issues/issue-5353.rs
index cca17595051..1d6813d5a39 100644
--- a/src/test/ui/issues/issue-5353.rs
+++ b/src/test/ui/issues/issue-5353.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-53568.rs b/src/test/ui/issues/issue-53568.rs
index 7644810c947..49ae444f97e 100644
--- a/src/test/ui/issues/issue-53568.rs
+++ b/src/test/ui/issues/issue-53568.rs
@@ -1,7 +1,7 @@
 // Regression test for an NLL-related ICE (#53568) -- we failed to
 // resolve inference variables in "custom type-ops".
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Future {
     type Item;
diff --git a/src/test/ui/issues/issue-53675-a-test-called-panic.rs b/src/test/ui/issues/issue-53675-a-test-called-panic.rs
index b8dca96946a..e573038980d 100644
--- a/src/test/ui/issues/issue-53675-a-test-called-panic.rs
+++ b/src/test/ui/issues/issue-53675-a-test-called-panic.rs
@@ -1,7 +1,7 @@
 // rust-lang/rust#53675: At one point the compiler errored when a test
 // named `panic` used the `assert!` macro in expression position.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags: --test
 
 mod in_expression_position {
diff --git a/src/test/ui/issues/issue-53912.rs b/src/test/ui/issues/issue-53912.rs
index 4718aea0429..65b6825a832 100644
--- a/src/test/ui/issues/issue-53912.rs
+++ b/src/test/ui/issues/issue-53912.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 // This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the
 // reproduction compiles successfully and doesn't segfault, whereas that test just checks that the
diff --git a/src/test/ui/issues/issue-54387.rs b/src/test/ui/issues/issue-54387.rs
index 7aee500744d..60e3a02f4ce 100644
--- a/src/test/ui/issues/issue-54387.rs
+++ b/src/test/ui/issues/issue-54387.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub struct GstRc {
     _obj: *const (),
diff --git a/src/test/ui/issues/issue-54521-1.rs b/src/test/ui/issues/issue-54521-1.rs
index 9bda7635eff..8a682ef0a11 100644
--- a/src/test/ui/issues/issue-54521-1.rs
+++ b/src/test/ui/issues/issue-54521-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // This test checks that the `remove extra angle brackets` error doesn't happen for some
 // potential edge-cases..
diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs
index eca27819a40..ec682d96081 100644
--- a/src/test/ui/issues/issue-54943-1.rs
+++ b/src/test/ui/issues/issue-54943-1.rs
@@ -1,7 +1,7 @@
 // This test is a minimal version of an ICE in the dropck-eyepatch tests
 // found in the fix for #54943.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn foo<T>(_t: T) {
 }
diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs
index c32f85dbe1a..d400ae58db4 100644
--- a/src/test/ui/issues/issue-54943-2.rs
+++ b/src/test/ui/issues/issue-54943-2.rs
@@ -2,7 +2,7 @@
 // found in the fix for #54943. In particular, this test is in unreachable
 // code as the initial fix for this ICE only worked if the code was reachable.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn foo<T>(_t: T) {
 }
diff --git a/src/test/ui/issues/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs
index ef705946ad4..e6c2611b683 100644
--- a/src/test/ui/issues/issue-54943-3.rs
+++ b/src/test/ui/issues/issue-54943-3.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // FIXME(#54943) This test targets the scenario where proving the WF requirements requires
 // knowing the value of the `_` type present in the user type annotation - unfortunately, figuring
 // out the value of that `_` requires type-checking the surrounding code, but that code is dead,
diff --git a/src/test/ui/issues/issue-5500-1.rs b/src/test/ui/issues/issue-5500-1.rs
index edbbe33c66f..98d6e1a14cb 100644
--- a/src/test/ui/issues/issue-5500-1.rs
+++ b/src/test/ui/issues/issue-5500-1.rs
@@ -2,7 +2,7 @@
 // is OK because the test is here to check that the compiler doesn't ICE (cf.
 // #5500).
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct TrieMapIterator<'a> {
     node: &'a usize
diff --git a/src/test/ui/issues/issue-5572.rs b/src/test/ui/issues/issue-5572.rs
index db26b0372a6..175dc879dda 100644
--- a/src/test/ui/issues/issue-5572.rs
+++ b/src/test/ui/issues/issue-5572.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs
index 32d87586cf4..10b50943c23 100644
--- a/src/test/ui/issues/issue-56128.rs
+++ b/src/test/ui/issues/issue-56128.rs
@@ -1,7 +1,7 @@
 // Regression test for #56128. When this `pub(super) use...` gets
 // exploded in the HIR, we were not handling ids correctly.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 mod bar {
     pub(super) use self::baz::{x, y};
diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs
index 6d6f23d2844..0952843e60a 100644
--- a/src/test/ui/issues/issue-56202.rs
+++ b/src/test/ui/issues/issue-56202.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 trait FooTrait {}
 
diff --git a/src/test/ui/issues/issue-56411-aux.rs b/src/test/ui/issues/issue-56411-aux.rs
index 6880a8a98d2..c8e5a059810 100644
--- a/src/test/ui/issues/issue-56411-aux.rs
+++ b/src/test/ui/issues/issue-56411-aux.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct T {}
 
diff --git a/src/test/ui/issues/issue-57156.rs b/src/test/ui/issues/issue-57156.rs
index b6cd8c927a2..9f5ec9f2771 100644
--- a/src/test/ui/issues/issue-57156.rs
+++ b/src/test/ui/issues/issue-57156.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo<Args> {
     type Output;
diff --git a/src/test/ui/issues/issue-57162.rs b/src/test/ui/issues/issue-57162.rs
index 7ba2f9cea84..65070060287 100644
--- a/src/test/ui/issues/issue-57162.rs
+++ b/src/test/ui/issues/issue-57162.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo {}
 impl Foo for dyn Send {}
diff --git a/src/test/ui/issues/issue-57399-self-return-impl-trait.rs b/src/test/ui/issues/issue-57399-self-return-impl-trait.rs
index 23d68263b3a..c7fe40e7b50 100644
--- a/src/test/ui/issues/issue-57399-self-return-impl-trait.rs
+++ b/src/test/ui/issues/issue-57399-self-return-impl-trait.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 trait T {
     type T;
diff --git a/src/test/ui/issues/issue-57399-self-return-impl-trait.stderr b/src/test/ui/issues/issue-57399-self-return-impl-trait.stderr
deleted file mode 100644
index 5c71410a827..00000000000
--- a/src/test/ui/issues/issue-57399-self-return-impl-trait.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: field is never used: `a`
-  --> $DIR/issue-57399-self-return-impl-trait.rs:12:5
-   |
-LL |     a: A,
-   |     ^^^^
-   |
-   = note: `#[warn(dead_code)]` on by default
-
diff --git a/src/test/ui/issues/issue-57410-1.rs b/src/test/ui/issues/issue-57410-1.rs
index c4247b3b11c..d825cb18008 100644
--- a/src/test/ui/issues/issue-57410-1.rs
+++ b/src/test/ui/issues/issue-57410-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Originally from #53925.
 // Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.
diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/issues/issue-57410.rs
index de7ae4b3c07..0cf4b8068e4 100644
--- a/src/test/ui/issues/issue-57410.rs
+++ b/src/test/ui/issues/issue-57410.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.
 
diff --git a/src/test/ui/issues/issue-5754.rs b/src/test/ui/issues/issue-5754.rs
index a629729d395..d90816635ab 100644
--- a/src/test/ui/issues/issue-5754.rs
+++ b/src/test/ui/issues/issue-5754.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
diff --git a/src/test/ui/issues/issue-5884.rs b/src/test/ui/issues/issue-5884.rs
index acb3e19765e..2f64342a6dd 100644
--- a/src/test/ui/issues/issue-5884.rs
+++ b/src/test/ui/issues/issue-5884.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-58856-2.stderr b/src/test/ui/issues/issue-58856-2.stderr
index a83dd674a87..01d70d861e2 100644
--- a/src/test/ui/issues/issue-58856-2.stderr
+++ b/src/test/ui/issues/issue-58856-2.stderr
@@ -11,7 +11,7 @@ error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pu
   --> $DIR/issue-58856-2.rs:11:1
    |
 LL |     }
-   |      - expected one of 10 possible tokens here
+   |      - expected one of 10 possible tokens
 LL | }
    | ^ unexpected token
 
diff --git a/src/test/ui/issues/issue-5900.rs b/src/test/ui/issues/issue-5900.rs
index 850e67db629..a7dc0eff43a 100644
--- a/src/test/ui/issues/issue-5900.rs
+++ b/src/test/ui/issues/issue-5900.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-5950.rs b/src/test/ui/issues/issue-5950.rs
index 5c2250e25fc..492a9d5723a 100644
--- a/src/test/ui/issues/issue-5950.rs
+++ b/src/test/ui/issues/issue-5950.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-60075.stderr b/src/test/ui/issues/issue-60075.stderr
index 961a546d8d6..39e3ad7b6b4 100644
--- a/src/test/ui/issues/issue-60075.stderr
+++ b/src/test/ui/issues/issue-60075.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, `else`, or an operator, found `}`
   --> $DIR/issue-60075.rs:6:10
    |
 LL |         });
-   |          ^ expected one of `.`, `;`, `?`, `else`, or an operator here
+   |          ^ expected one of `.`, `;`, `?`, `else`, or an operator
 
 error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `;`
   --> $DIR/issue-60075.rs:6:11
diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs
index dcf935c5780..967c5f8ed73 100644
--- a/src/test/ui/issues/issue-60662.rs
+++ b/src/test/ui/issues/issue-60662.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags: -Z unpretty=hir
 
 #![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout
index e2a88dec97f..5a4b49cfa1e 100644
--- a/src/test/ui/issues/issue-60662.stdout
+++ b/src/test/ui/issues/issue-60662.stdout
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags: -Z unpretty=hir
 
 #![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/issues/issue-6341.rs b/src/test/ui/issues/issue-6341.rs
index 2fb0fee60ba..1be1394dfae 100644
--- a/src/test/ui/issues/issue-6341.rs
+++ b/src/test/ui/issues/issue-6341.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/issues/issue-6470.rs b/src/test/ui/issues/issue-6470.rs
index 305f46c6d4e..0c86a648828 100644
--- a/src/test/ui/issues/issue-6470.rs
+++ b/src/test/ui/issues/issue-6470.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
diff --git a/src/test/ui/issues/issue-65462.rs b/src/test/ui/issues/issue-65462.rs
new file mode 100644
index 00000000000..8c39ea531d2
--- /dev/null
+++ b/src/test/ui/issues/issue-65462.rs
@@ -0,0 +1,15 @@
+// build-pass
+
+enum Empty {}
+enum Enum {
+    Empty( Empty )
+}
+
+fn foobar() -> Option< Enum > {
+    let value: Option< Empty > = None;
+    Some( Enum::Empty( value? ) )
+}
+
+fn main() {
+    foobar();
+}
diff --git a/src/test/ui/issues/issue-6557.rs b/src/test/ui/issues/issue-6557.rs
index 70b301d3d9c..e066aa52923 100644
--- a/src/test/ui/issues/issue-6557.rs
+++ b/src/test/ui/issues/issue-6557.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-6898.rs b/src/test/ui/issues/issue-6898.rs
index 6bf20d71d1f..44fd4bd0735 100644
--- a/src/test/ui/issues/issue-6898.rs
+++ b/src/test/ui/issues/issue-6898.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 use std::mem;
diff --git a/src/test/ui/issues/issue-6991.rs b/src/test/ui/issues/issue-6991.rs
index aae67637f2c..f00cd9aeffd 100644
--- a/src/test/ui/issues/issue-6991.rs
+++ b/src/test/ui/issues/issue-6991.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-7268.rs b/src/test/ui/issues/issue-7268.rs
index 69901e97894..309176fb0c5 100644
--- a/src/test/ui/issues/issue-7268.rs
+++ b/src/test/ui/issues/issue-7268.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-7607-2.rs b/src/test/ui/issues/issue-7607-2.rs
index e336e0b47b2..420a0ffd3cc 100644
--- a/src/test/ui/issues/issue-7607-2.rs
+++ b/src/test/ui/issues/issue-7607-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
index 9570386730a..2961dc79f10 100644
--- a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
index 653d002fa61..505e7b84b5c 100644
--- a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
+++ b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-8398.rs b/src/test/ui/issues/issue-8398.rs
index 5fe88854b39..0ef39b6a6b3 100644
--- a/src/test/ui/issues/issue-8398.rs
+++ b/src/test/ui/issues/issue-8398.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-8521.rs b/src/test/ui/issues/issue-8521.rs
index 02a0e14d55e..15fbd4465a0 100644
--- a/src/test/ui/issues/issue-8521.rs
+++ b/src/test/ui/issues/issue-8521.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait Foo1 {}
 
 trait A {}
diff --git a/src/test/ui/issues/issue-8578.rs b/src/test/ui/issues/issue-8578.rs
index 6ffb721372a..2346ef5a950 100644
--- a/src/test/ui/issues/issue-8578.rs
+++ b/src/test/ui/issues/issue-8578.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
diff --git a/src/test/ui/issues/issue-9110.rs b/src/test/ui/issues/issue-9110.rs
index f3bab42ee16..cbf3c92d033 100644
--- a/src/test/ui/issues/issue-9110.rs
+++ b/src/test/ui/issues/issue-9110.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 #![allow(non_snake_case)]
diff --git a/src/test/ui/issues/issue-9243.rs b/src/test/ui/issues/issue-9243.rs
index 78237421c98..59fdb466285 100644
--- a/src/test/ui/issues/issue-9243.rs
+++ b/src/test/ui/issues/issue-9243.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // Regression test for issue 9243
 #![allow(non_upper_case_globals)]
diff --git a/src/test/ui/issues/issue-9249.rs b/src/test/ui/issues/issue-9249.rs
index b1f2bd7569a..caaba668ad7 100644
--- a/src/test/ui/issues/issue-9249.rs
+++ b/src/test/ui/issues/issue-9249.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-9719.rs b/src/test/ui/issues/issue-9719.rs
index 58eb32b111d..e8c3c9c194a 100644
--- a/src/test/ui/issues/issue-9719.rs
+++ b/src/test/ui/issues/issue-9719.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.fixed b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
new file mode 100644
index 00000000000..f88a52d3159
--- /dev/null
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
@@ -0,0 +1,33 @@
+// run-pass
+// run-rustfix
+
+fn main() {
+    let small = [1, 2];
+    let big = [0u8; 33];
+
+    // Expressions that should trigger the lint
+    small.iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [1, 2].iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    big.iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [0u8; 33].iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+
+
+    // Expressions that should not
+    (&[1, 2]).into_iter();
+    (&small).into_iter();
+    (&[0u8; 33]).into_iter();
+    (&big).into_iter();
+
+    for _ in &[1, 2] {}
+    (&small as &[_]).into_iter();
+    small[..].into_iter();
+    std::iter::IntoIterator::into_iter(&[1, 2]);
+}
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.rs b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
new file mode 100644
index 00000000000..e1a4b535f38
--- /dev/null
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
@@ -0,0 +1,33 @@
+// run-pass
+// run-rustfix
+
+fn main() {
+    let small = [1, 2];
+    let big = [0u8; 33];
+
+    // Expressions that should trigger the lint
+    small.into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [1, 2].into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    big.into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [0u8; 33].into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+
+
+    // Expressions that should not
+    (&[1, 2]).into_iter();
+    (&small).into_iter();
+    (&[0u8; 33]).into_iter();
+    (&big).into_iter();
+
+    for _ in &[1, 2] {}
+    (&small as &[_]).into_iter();
+    small[..].into_iter();
+    std::iter::IntoIterator::into_iter(&[1, 2]);
+}
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
new file mode 100644
index 00000000000..b5964bd44bf
--- /dev/null
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
@@ -0,0 +1,37 @@
+warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:9:11
+   |
+LL |     small.into_iter();
+   |           ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = note: `#[warn(array_into_iter)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
+warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:12:12
+   |
+LL |     [1, 2].into_iter();
+   |            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
+warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:15:9
+   |
+LL |     big.into_iter();
+   |         ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
+warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:18:15
+   |
+LL |     [0u8; 33].into_iter();
+   |               ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
diff --git a/src/test/ui/label/label_break_value_illegal_uses.stderr b/src/test/ui/label/label_break_value_illegal_uses.stderr
index 80b4329ad40..0036f0f1db0 100644
--- a/src/test/ui/label/label_break_value_illegal_uses.stderr
+++ b/src/test/ui/label/label_break_value_illegal_uses.stderr
@@ -2,7 +2,7 @@ error: expected one of `extern`, `fn`, or `{`, found `'b`
   --> $DIR/label_break_value_illegal_uses.rs:6:12
    |
 LL |     unsafe 'b: {}
-   |            ^^ expected one of `extern`, `fn`, or `{` here
+   |            ^^ expected one of `extern`, `fn`, or `{`
 
 error: expected `{`, found `'b`
   --> $DIR/label_break_value_illegal_uses.rs:10:13
@@ -27,7 +27,7 @@ error: expected one of `.`, `?`, `{`, or an operator, found `'b`
   --> $DIR/label_break_value_illegal_uses.rs:18:17
    |
 LL |     match false 'b: {}
-   |     -----       ^^ expected one of `.`, `?`, `{`, or an operator here
+   |     -----       ^^ expected one of `.`, `?`, `{`, or an operator
    |     |
    |     while parsing this match expression
 
diff --git a/src/test/ui/lint/command-line-lint-group-warn.rs b/src/test/ui/lint/command-line-lint-group-warn.rs
index d3a4201ba60..f4536f9c9e2 100644
--- a/src/test/ui/lint/command-line-lint-group-warn.rs
+++ b/src/test/ui/lint/command-line-lint-group-warn.rs
@@ -1,6 +1,7 @@
 // compile-flags: -W bad-style
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     let _InappropriateCamelCasing = true;
+    //~^ WARNING should have a snake case name
 }
diff --git a/src/test/ui/dead-code-alias-in-pat.rs b/src/test/ui/lint/dead-code/alias-in-pat.rs
index 69d455f3b60..69d455f3b60 100644
--- a/src/test/ui/dead-code-alias-in-pat.rs
+++ b/src/test/ui/lint/dead-code/alias-in-pat.rs
diff --git a/src/test/ui/lint-dead-code-associated-type.rs b/src/test/ui/lint/dead-code/associated-type.rs
index 1cf66e75a95..1cf66e75a95 100644
--- a/src/test/ui/lint-dead-code-associated-type.rs
+++ b/src/test/ui/lint/dead-code/associated-type.rs
diff --git a/src/test/ui/fail-no-dead-code.rs b/src/test/ui/lint/dead-code/basic.rs
index 2b69985d33d..2b69985d33d 100644
--- a/src/test/ui/fail-no-dead-code.rs
+++ b/src/test/ui/lint/dead-code/basic.rs
diff --git a/src/test/ui/fail-no-dead-code.stderr b/src/test/ui/lint/dead-code/basic.stderr
index 8babcffaa8d..194398e5a07 100644
--- a/src/test/ui/fail-no-dead-code.stderr
+++ b/src/test/ui/lint/dead-code/basic.stderr
@@ -1,11 +1,11 @@
 error: function is never used: `foo`
-  --> $DIR/fail-no-dead-code.rs:4:1
+  --> $DIR/basic.rs:4:4
    |
 LL | fn foo() {
-   | ^^^^^^^^
+   |    ^^^
    |
 note: lint level defined here
-  --> $DIR/fail-no-dead-code.rs:1:9
+  --> $DIR/basic.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/dead-code-closure-bang.rs b/src/test/ui/lint/dead-code/closure-bang.rs
index 8e8636b1180..8e8636b1180 100644
--- a/src/test/ui/dead-code-closure-bang.rs
+++ b/src/test/ui/lint/dead-code/closure-bang.rs
diff --git a/src/test/ui/lint/lint-dead-code-const-and-self.rs b/src/test/ui/lint/dead-code/const-and-self.rs
index 1a7b3f43cda..1a7b3f43cda 100644
--- a/src/test/ui/lint/lint-dead-code-const-and-self.rs
+++ b/src/test/ui/lint/dead-code/const-and-self.rs
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs b/src/test/ui/lint/dead-code/empty-unused-enum.rs
index 834681d77e6..834681d77e6 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs
+++ b/src/test/ui/lint/dead-code/empty-unused-enum.rs
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr b/src/test/ui/lint/dead-code/empty-unused-enum.stderr
index 4e3bebfc48b..44b0a8f613e 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr
+++ b/src/test/ui/lint/dead-code/empty-unused-enum.stderr
@@ -1,11 +1,11 @@
 error: enum is never used: `E`
-  --> $DIR/lint-dead-code-empty-unused-enum.rs:3:1
+  --> $DIR/empty-unused-enum.rs:3:6
    |
 LL | enum E {}
-   | ^^^^^^
+   |      ^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-empty-unused-enum.rs:1:9
+  --> $DIR/empty-unused-enum.rs:1:9
    |
 LL | #![deny(unused)]
    |         ^^^^^^
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs b/src/test/ui/lint/dead-code/empty-unused-public-enum.rs
index 15b04496ba7..15b04496ba7 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
+++ b/src/test/ui/lint/dead-code/empty-unused-public-enum.rs
diff --git a/src/test/ui/lint-dead-code-variant.rs b/src/test/ui/lint/dead-code/enum-variants.rs
index 91c97232eed..91c97232eed 100644
--- a/src/test/ui/lint-dead-code-variant.rs
+++ b/src/test/ui/lint/dead-code/enum-variants.rs
diff --git a/src/test/ui/lint/lint-dead-code-impl-trait.rs b/src/test/ui/lint/dead-code/impl-trait.rs
index a2736d97308..a2736d97308 100644
--- a/src/test/ui/lint/lint-dead-code-impl-trait.rs
+++ b/src/test/ui/lint/dead-code/impl-trait.rs
diff --git a/src/test/ui/lint/lint-dead-code-impl-trait.stderr b/src/test/ui/lint/dead-code/impl-trait.stderr
index 61d0954bf31..f2a78cc65e2 100644
--- a/src/test/ui/lint/lint-dead-code-impl-trait.stderr
+++ b/src/test/ui/lint/dead-code/impl-trait.stderr
@@ -1,11 +1,11 @@
 error: type alias is never used: `Unused`
-  --> $DIR/lint-dead-code-impl-trait.rs:12:1
+  --> $DIR/impl-trait.rs:12:1
    |
 LL | type Unused = ();
    | ^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-impl-trait.rs:1:9
+  --> $DIR/impl-trait.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/dead-code-leading-underscore.rs b/src/test/ui/lint/dead-code/leading-underscore.rs
index 1b6e03ab887..1b6e03ab887 100644
--- a/src/test/ui/dead-code-leading-underscore.rs
+++ b/src/test/ui/lint/dead-code/leading-underscore.rs
diff --git a/src/test/ui/lint/lint-dead-code-1.rs b/src/test/ui/lint/dead-code/lint-dead-code-1.rs
index 09977f8df51..09977f8df51 100644
--- a/src/test/ui/lint/lint-dead-code-1.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-1.rs
diff --git a/src/test/ui/lint/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr
index be96c697d99..bac46a2e843 100644
--- a/src/test/ui/lint/lint-dead-code-1.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr
@@ -1,8 +1,8 @@
 error: struct is never constructed: `Bar`
-  --> $DIR/lint-dead-code-1.rs:12:5
+  --> $DIR/lint-dead-code-1.rs:12:16
    |
 LL |     pub struct Bar;
-   |     ^^^^^^^^^^^^^^^
+   |                ^^^
    |
 note: lint level defined here
   --> $DIR/lint-dead-code-1.rs:5:9
@@ -23,16 +23,16 @@ LL | const priv_const: isize = 0;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: struct is never constructed: `PrivStruct`
-  --> $DIR/lint-dead-code-1.rs:35:1
+  --> $DIR/lint-dead-code-1.rs:35:8
    |
 LL | struct PrivStruct;
-   | ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^
 
 error: enum is never used: `priv_enum`
-  --> $DIR/lint-dead-code-1.rs:64:1
+  --> $DIR/lint-dead-code-1.rs:64:6
    |
 LL | enum priv_enum { foo2, bar2 }
-   | ^^^^^^^^^^^^^^
+   |      ^^^^^^^^^
 
 error: variant is never constructed: `bar3`
   --> $DIR/lint-dead-code-1.rs:67:5
@@ -41,28 +41,28 @@ LL |     bar3
    |     ^^^^
 
 error: function is never used: `priv_fn`
-  --> $DIR/lint-dead-code-1.rs:88:1
+  --> $DIR/lint-dead-code-1.rs:88:4
    |
 LL | fn priv_fn() {
-   | ^^^^^^^^^^^^
+   |    ^^^^^^^
 
 error: function is never used: `foo`
-  --> $DIR/lint-dead-code-1.rs:93:1
+  --> $DIR/lint-dead-code-1.rs:93:4
    |
 LL | fn foo() {
-   | ^^^^^^^^
+   |    ^^^
 
 error: function is never used: `bar`
-  --> $DIR/lint-dead-code-1.rs:98:1
+  --> $DIR/lint-dead-code-1.rs:98:4
    |
 LL | fn bar() {
-   | ^^^^^^^^
+   |    ^^^
 
 error: function is never used: `baz`
-  --> $DIR/lint-dead-code-1.rs:102:1
+  --> $DIR/lint-dead-code-1.rs:102:4
    |
 LL | fn baz() -> impl Copy {
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |    ^^^
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/lint/lint-dead-code-2.rs b/src/test/ui/lint/dead-code/lint-dead-code-2.rs
index 88db4f88c3f..88db4f88c3f 100644
--- a/src/test/ui/lint/lint-dead-code-2.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-2.rs
diff --git a/src/test/ui/lint/lint-dead-code-2.stderr b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr
index 1226f9823ac..a578a76d9a0 100644
--- a/src/test/ui/lint/lint-dead-code-2.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr
@@ -1,8 +1,8 @@
 error: function is never used: `dead_fn`
-  --> $DIR/lint-dead-code-2.rs:22:1
+  --> $DIR/lint-dead-code-2.rs:22:4
    |
 LL | fn dead_fn() {}
-   | ^^^^^^^^^^^^
+   |    ^^^^^^^
    |
 note: lint level defined here
   --> $DIR/lint-dead-code-2.rs:2:9
@@ -11,16 +11,16 @@ LL | #![deny(dead_code)]
    |         ^^^^^^^^^
 
 error: function is never used: `dead_fn2`
-  --> $DIR/lint-dead-code-2.rs:25:1
+  --> $DIR/lint-dead-code-2.rs:25:4
    |
 LL | fn dead_fn2() {}
-   | ^^^^^^^^^^^^^
+   |    ^^^^^^^^
 
 error: function is never used: `main`
-  --> $DIR/lint-dead-code-2.rs:38:1
+  --> $DIR/lint-dead-code-2.rs:38:4
    |
 LL | fn main() {
-   | ^^^^^^^^^
+   |    ^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/lint/lint-dead-code-3.rs b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
index 4397522f3f3..4397522f3f3 100644
--- a/src/test/ui/lint/lint-dead-code-3.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
diff --git a/src/test/ui/lint/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr
index 2408da0af89..569196fffdd 100644
--- a/src/test/ui/lint/lint-dead-code-3.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -1,8 +1,8 @@
 error: struct is never constructed: `Foo`
-  --> $DIR/lint-dead-code-3.rs:13:1
+  --> $DIR/lint-dead-code-3.rs:13:8
    |
 LL | struct Foo;
-   | ^^^^^^^^^^^
+   |        ^^^
    |
 note: lint level defined here
   --> $DIR/lint-dead-code-3.rs:3:9
@@ -17,16 +17,16 @@ LL |     fn foo(&self) {
    |     ^^^^^^^^^^^^^
 
 error: function is never used: `bar`
-  --> $DIR/lint-dead-code-3.rs:20:1
+  --> $DIR/lint-dead-code-3.rs:20:4
    |
 LL | fn bar() {
-   | ^^^^^^^^
+   |    ^^^
 
 error: enum is never used: `c_void`
-  --> $DIR/lint-dead-code-3.rs:59:1
+  --> $DIR/lint-dead-code-3.rs:59:6
    |
 LL | enum c_void {}
-   | ^^^^^^^^^^^
+   |      ^^^^^^
 
 error: foreign function is never used: `free`
   --> $DIR/lint-dead-code-3.rs:61:5
diff --git a/src/test/ui/lint/lint-dead-code-4.rs b/src/test/ui/lint/dead-code/lint-dead-code-4.rs
index 3f4a9e21040..3f4a9e21040 100644
--- a/src/test/ui/lint/lint-dead-code-4.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-4.rs
diff --git a/src/test/ui/lint/lint-dead-code-4.stderr b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr
index b7ceee99998..8eaf789f8f7 100644
--- a/src/test/ui/lint/lint-dead-code-4.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr
@@ -27,10 +27,10 @@ LL | |     },
    | |_____^
 
 error: enum is never used: `ABC`
-  --> $DIR/lint-dead-code-4.rs:24:1
+  --> $DIR/lint-dead-code-4.rs:24:6
    |
 LL | enum ABC {
-   | ^^^^^^^^
+   |      ^^^
 
 error: variant is never constructed: `I`
   --> $DIR/lint-dead-code-4.rs:36:5
diff --git a/src/test/ui/lint/lint-dead-code-5.rs b/src/test/ui/lint/dead-code/lint-dead-code-5.rs
index 764a23e4e49..764a23e4e49 100644
--- a/src/test/ui/lint/lint-dead-code-5.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-5.rs
diff --git a/src/test/ui/lint/lint-dead-code-5.stderr b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr
index 740cfde2c06..9670d8e7a32 100644
--- a/src/test/ui/lint/lint-dead-code-5.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr
@@ -23,10 +23,10 @@ LL |     Variant6(isize),
    |     ^^^^^^^^^^^^^^^
 
 error: enum is never used: `Enum3`
-  --> $DIR/lint-dead-code-5.rs:18:1
+  --> $DIR/lint-dead-code-5.rs:18:6
    |
 LL | enum Enum3 {
-   | ^^^^^^^^^^
+   |      ^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/lint/dead-code/newline-span.rs b/src/test/ui/lint/dead-code/newline-span.rs
new file mode 100644
index 00000000000..a4342056419
--- /dev/null
+++ b/src/test/ui/lint/dead-code/newline-span.rs
@@ -0,0 +1,19 @@
+#![deny(dead_code)]
+
+fn unused() { //~ error: function is never used:
+    println!("blah");
+}
+
+fn unused2(var: i32) { //~ error: function is never used:
+    println!("foo {}", var);
+}
+
+fn unused3( //~ error: function is never used:
+    var: i32,
+) {
+    println!("bar {}", var);
+}
+
+fn main() {
+    println!("Hello world!");
+}
diff --git a/src/test/ui/lint/dead-code/newline-span.stderr b/src/test/ui/lint/dead-code/newline-span.stderr
new file mode 100644
index 00000000000..c5d0d605067
--- /dev/null
+++ b/src/test/ui/lint/dead-code/newline-span.stderr
@@ -0,0 +1,26 @@
+error: function is never used: `unused`
+  --> $DIR/newline-span.rs:3:4
+   |
+LL | fn unused() {
+   |    ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/newline-span.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: function is never used: `unused2`
+  --> $DIR/newline-span.rs:7:4
+   |
+LL | fn unused2(var: i32) {
+   |    ^^^^^^^
+
+error: function is never used: `unused3`
+  --> $DIR/newline-span.rs:11:4
+   |
+LL | fn unused3(
+   |    ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/dead-code-tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs
index 92a67950986..92a67950986 100644
--- a/src/test/ui/dead-code-tuple-struct-field.rs
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs
diff --git a/src/test/ui/lint/lint-dead-code-type-alias.rs b/src/test/ui/lint/dead-code/type-alias.rs
index 86daf3ea04d..86daf3ea04d 100644
--- a/src/test/ui/lint/lint-dead-code-type-alias.rs
+++ b/src/test/ui/lint/dead-code/type-alias.rs
diff --git a/src/test/ui/lint/lint-dead-code-type-alias.stderr b/src/test/ui/lint/dead-code/type-alias.stderr
index 4198ddfb6cb..82df23bd944 100644
--- a/src/test/ui/lint/lint-dead-code-type-alias.stderr
+++ b/src/test/ui/lint/dead-code/type-alias.stderr
@@ -1,11 +1,11 @@
 error: type alias is never used: `Unused`
-  --> $DIR/lint-dead-code-type-alias.rs:4:1
+  --> $DIR/type-alias.rs:4:1
    |
 LL | type Unused = u8;
    | ^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-type-alias.rs:1:9
+  --> $DIR/type-alias.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/lint/lint-dead-code-unused-enum.rs b/src/test/ui/lint/dead-code/unused-enum.rs
index e57fac259c5..e57fac259c5 100644
--- a/src/test/ui/lint/lint-dead-code-unused-enum.rs
+++ b/src/test/ui/lint/dead-code/unused-enum.rs
diff --git a/src/test/ui/lint/lint-dead-code-unused-enum.stderr b/src/test/ui/lint/dead-code/unused-enum.stderr
index ea711e7b05e..142c2ccb99b 100644
--- a/src/test/ui/lint/lint-dead-code-unused-enum.stderr
+++ b/src/test/ui/lint/dead-code/unused-enum.stderr
@@ -1,27 +1,27 @@
 error: struct is never constructed: `F`
-  --> $DIR/lint-dead-code-unused-enum.rs:3:1
+  --> $DIR/unused-enum.rs:3:8
    |
 LL | struct F;
-   | ^^^^^^^^^
+   |        ^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-unused-enum.rs:1:9
+  --> $DIR/unused-enum.rs:1:9
    |
 LL | #![deny(unused)]
    |         ^^^^^^
    = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
 
 error: struct is never constructed: `B`
-  --> $DIR/lint-dead-code-unused-enum.rs:4:1
+  --> $DIR/unused-enum.rs:4:8
    |
 LL | struct B;
-   | ^^^^^^^^^
+   |        ^
 
 error: enum is never used: `E`
-  --> $DIR/lint-dead-code-unused-enum.rs:6:1
+  --> $DIR/unused-enum.rs:6:6
    |
 LL | enum E {
-   | ^^^^^^
+   |      ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant.rs b/src/test/ui/lint/dead-code/unused-struct-variant.rs
index 69ab29042e5..69ab29042e5 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant.rs
+++ b/src/test/ui/lint/dead-code/unused-struct-variant.rs
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant.stderr b/src/test/ui/lint/dead-code/unused-struct-variant.stderr
index 919996ec300..0037592e3de 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-struct-variant.stderr
@@ -1,11 +1,11 @@
 error: variant is never constructed: `Bar`
-  --> $DIR/lint-dead-code-unused-variant.rs:8:5
+  --> $DIR/unused-struct-variant.rs:8:5
    |
 LL |     Bar(B),
    |     ^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-unused-variant.rs:1:9
+  --> $DIR/unused-struct-variant.rs:1:9
    |
 LL | #![deny(unused)]
    |         ^^^^^^
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs b/src/test/ui/lint/dead-code/unused-variant-pub.rs
index 3a9061340eb..3a9061340eb 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
+++ b/src/test/ui/lint/dead-code/unused-variant-pub.rs
diff --git a/src/test/ui/lint/lint-dead-code-variant.rs b/src/test/ui/lint/dead-code/unused-variant.rs
index 295ed16d4cf..295ed16d4cf 100644
--- a/src/test/ui/lint/lint-dead-code-variant.rs
+++ b/src/test/ui/lint/dead-code/unused-variant.rs
diff --git a/src/test/ui/lint/lint-dead-code-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr
index a79432dc68d..2167b9d910d 100644
--- a/src/test/ui/lint/lint-dead-code-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-variant.stderr
@@ -1,11 +1,11 @@
 error: variant is never constructed: `Variant1`
-  --> $DIR/lint-dead-code-variant.rs:5:5
+  --> $DIR/unused-variant.rs:5:5
    |
 LL |     Variant1,
    |     ^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-variant.rs:1:9
+  --> $DIR/unused-variant.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/fail-no-dead-code-core.rs b/src/test/ui/lint/dead-code/with-core-crate.rs
index bc74e807783..bc74e807783 100644
--- a/src/test/ui/fail-no-dead-code-core.rs
+++ b/src/test/ui/lint/dead-code/with-core-crate.rs
diff --git a/src/test/ui/fail-no-dead-code-core.stderr b/src/test/ui/lint/dead-code/with-core-crate.stderr
index 2540242f9f6..0b6ab67d9bf 100644
--- a/src/test/ui/fail-no-dead-code-core.stderr
+++ b/src/test/ui/lint/dead-code/with-core-crate.stderr
@@ -1,11 +1,11 @@
 error: function is never used: `foo`
-  --> $DIR/fail-no-dead-code-core.rs:7:1
+  --> $DIR/with-core-crate.rs:7:4
    |
 LL | fn foo() {
-   | ^^^^^^^^
+   |    ^^^
    |
 note: lint level defined here
-  --> $DIR/fail-no-dead-code-core.rs:1:9
+  --> $DIR/with-core-crate.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/dead-code-impl.rs b/src/test/ui/lint/dead-code/with-impl.rs
index 84829c98e57..84829c98e57 100644
--- a/src/test/ui/dead-code-impl.rs
+++ b/src/test/ui/lint/dead-code/with-impl.rs
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
index 7870d394c8b..0ad014e3361 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(box_syntax)]
 #![feature(box_patterns)]
@@ -23,7 +23,7 @@ enum Large {
 struct Tuple(Large, ());
 
 fn main() {
-    let i_think_continually = 2;
+    let i_think_continually = 2; //~ WARNING unused variable: `i_think_continually`
     let who_from_the_womb_remembered = SoulHistory {
         corridors_of_light: 5,
         hours_are_suns: true,
@@ -31,20 +31,25 @@ fn main() {
     };
 
     let mut mut_unused_var = 1;
+    //~^ WARNING unused variable: `mut_unused_var`
+    //~| WARNING variable does not need to be mutable
 
     let (mut var, unused_var) = (1, 2);
+    //~^ WARNING unused variable: `var`
+    //~| WARNING unused variable: `unused_var`
+    //~| WARNING variable does not need to be mutable
     // NOTE: `var` comes after `unused_var` lexicographically yet the warning
     // for `var` will be emitted before the one for `unused_var`. We use an
     // `IndexMap` to ensure this is the case instead of a `BTreeMap`.
 
-    if let SoulHistory { corridors_of_light,
-                         mut hours_are_suns,
+    if let SoulHistory { corridors_of_light, //~ WARNING unused variable: `corridors_of_light`
+                         mut hours_are_suns, //~ WARNING `hours_are_suns` is assigned to, but
                          endless_and_singing: true } = who_from_the_womb_remembered {
-        hours_are_suns = false;
+        hours_are_suns = false; //~ WARNING unused_assignments
     }
 
     let the_spirit = LovelyAmbition { lips: 1, fire: 2 };
-    let LovelyAmbition { lips, fire } = the_spirit;
+    let LovelyAmbition { lips, fire } = the_spirit; //~ WARNING unused variable: `fire`
     println!("{}", lips);
 
     let bag = Large::Suit {
@@ -53,31 +58,31 @@ fn main() {
 
     // Plain struct
     match bag {
-        Large::Suit { case } => {}
+        Large::Suit { case } => {} //~ WARNING unused variable: `case`
     };
 
     // Referenced struct
     match &bag {
-        &Large::Suit { case } => {}
+        &Large::Suit { case } => {} //~ WARNING unused variable: `case`
     };
 
     // Boxed struct
     match box bag {
-        box Large::Suit { case } => {}
+        box Large::Suit { case } => {} //~ WARNING unused variable: `case`
     };
 
     // Tuple with struct
     match (bag,) {
-        (Large::Suit { case },) => {}
+        (Large::Suit { case },) => {} //~ WARNING unused variable: `case`
     };
 
     // Slice with struct
     match [bag] {
-        [Large::Suit { case }] => {}
+        [Large::Suit { case }] => {} //~ WARNING unused variable: `case`
     };
 
     // Tuple struct with struct
     match Tuple(bag, ()) {
-        Tuple(Large::Suit { case }, ()) => {}
+        Tuple(Large::Suit { case }, ()) => {} //~ WARNING unused variable: `case`
     };
 }
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
index 74bbef8adad..0e18abc03fa 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -18,25 +18,25 @@ LL |     let mut mut_unused_var = 1;
    |             ^^^^^^^^^^^^^^ help: consider prefixing with an underscore: `_mut_unused_var`
 
 warning: unused variable: `var`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:14
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14
    |
 LL |     let (mut var, unused_var) = (1, 2);
    |              ^^^ help: consider prefixing with an underscore: `_var`
 
 warning: unused variable: `unused_var`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:19
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19
    |
 LL |     let (mut var, unused_var) = (1, 2);
    |                   ^^^^^^^^^^ help: consider prefixing with an underscore: `_unused_var`
 
 warning: unused variable: `corridors_of_light`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:40:26
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:45:26
    |
 LL |     if let SoulHistory { corridors_of_light,
    |                          ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _`
 
 warning: variable `hours_are_suns` is assigned to, but never used
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:41:30
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30
    |
 LL |                          mut hours_are_suns,
    |                              ^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL |                          mut hours_are_suns,
    = note: consider using `_hours_are_suns` instead
 
 warning: value assigned to `hours_are_suns` is never read
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:43:9
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:9
    |
 LL |         hours_are_suns = false;
    |         ^^^^^^^^^^^^^^
@@ -58,43 +58,43 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    = help: maybe it is overwritten before being read?
 
 warning: unused variable: `fire`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:47:32
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32
    |
 LL |     let LovelyAmbition { lips, fire } = the_spirit;
    |                                ^^^^ help: try ignoring the field: `fire: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:56:23
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:61:23
    |
 LL |         Large::Suit { case } => {}
    |                       ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:61:24
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:66:24
    |
 LL |         &Large::Suit { case } => {}
    |                        ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:66:27
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:71:27
    |
 LL |         box Large::Suit { case } => {}
    |                           ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:71:24
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:76:24
    |
 LL |         (Large::Suit { case },) => {}
    |                        ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:76:24
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:81:24
    |
 LL |         [Large::Suit { case }] => {}
    |                        ^^^^ help: try ignoring the field: `case: _`
 
 warning: unused variable: `case`
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:81:29
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:86:29
    |
 LL |         Tuple(Large::Suit { case }, ()) => {}
    |                             ^^^^ help: try ignoring the field: `case: _`
@@ -115,7 +115,7 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896)
    = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]`
 
 warning: variable does not need to be mutable
-  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:35:10
+  --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10
    |
 LL |     let (mut var, unused_var) = (1, 2);
    |          ----^^^
diff --git a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
index 47063a7c267..ab9baa79b8b 100644
--- a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
+++ b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(unused_parens)]
 
diff --git a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
index 3802e01a775..b2bf87358a4 100644
--- a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
+++ b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![forbid(non_camel_case_types)]
 #![allow(dead_code)]
diff --git a/src/test/ui/lint/lint-ctypes-fn.rs b/src/test/ui/lint/lint-ctypes-fn.rs
new file mode 100644
index 00000000000..2daac70fedf
--- /dev/null
+++ b/src/test/ui/lint/lint-ctypes-fn.rs
@@ -0,0 +1,186 @@
+#![feature(rustc_private)]
+
+#![allow(private_in_public)]
+#![deny(improper_ctypes)]
+
+extern crate libc;
+
+use std::default::Default;
+use std::marker::PhantomData;
+
+trait Mirror { type It: ?Sized; }
+
+impl<T: ?Sized> Mirror for T { type It = Self; }
+
+#[repr(C)]
+pub struct StructWithProjection(*mut <StructWithProjection as Mirror>::It);
+
+#[repr(C)]
+pub struct StructWithProjectionAndLifetime<'a>(
+    &'a mut <StructWithProjectionAndLifetime<'a> as Mirror>::It
+);
+
+pub type I32Pair = (i32, i32);
+
+#[repr(C)]
+pub struct ZeroSize;
+
+pub type RustFn = fn();
+
+pub type RustBadRet = extern fn() -> Box<u32>;
+
+pub type CVoidRet = ();
+
+pub struct Foo;
+
+#[repr(transparent)]
+pub struct TransparentI128(i128);
+
+#[repr(transparent)]
+pub struct TransparentStr(&'static str);
+
+#[repr(transparent)]
+pub struct TransparentBadFn(RustBadRet);
+
+#[repr(transparent)]
+pub struct TransparentInt(u32);
+
+#[repr(transparent)]
+pub struct TransparentRef<'a>(&'a TransparentInt);
+
+#[repr(transparent)]
+pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
+
+#[repr(transparent)]
+pub struct TransparentUnit<U>(f32, PhantomData<U>);
+
+#[repr(transparent)]
+pub struct TransparentCustomZst(i32, ZeroSize);
+
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
+
+pub extern "C" fn ptr_type1(size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn ptr_type2(size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn slice_type(p: &[u32]) { }
+//~^ ERROR: uses type `[u32]`
+
+pub extern "C" fn str_type(p: &str) { }
+//~^ ERROR: uses type `str`
+
+pub extern "C" fn box_type(p: Box<u32>) { }
+//~^ ERROR uses type `std::boxed::Box<u32>`
+
+pub extern "C" fn char_type(p: char) { }
+//~^ ERROR uses type `char`
+
+pub extern "C" fn i128_type(p: i128) { }
+//~^ ERROR uses type `i128`
+
+pub extern "C" fn u128_type(p: u128) { }
+//~^ ERROR uses type `u128`
+
+pub extern "C" fn tuple_type(p: (i32, i32)) { }
+//~^ ERROR uses type `(i32, i32)`
+
+pub extern "C" fn tuple_type2(p: I32Pair) { }
+//~^ ERROR uses type `(i32, i32)`
+
+pub extern "C" fn zero_size(p: ZeroSize) { }
+//~^ ERROR uses type `ZeroSize`
+
+pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
+//~^ ERROR uses type `ZeroSizeWithPhantomData`
+
+pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
+//~^ ERROR uses type `std::marker::PhantomData<bool>`
+    Default::default()
+}
+
+pub extern "C" fn fn_type(p: RustFn) { }
+//~^ ERROR uses type `fn()`
+
+pub extern "C" fn fn_type2(p: fn()) { }
+//~^ ERROR uses type `fn()`
+
+pub extern "C" fn fn_contained(p: RustBadRet) { }
+//~^ ERROR: uses type `std::boxed::Box<u32>`
+
+pub extern "C" fn transparent_i128(p: TransparentI128) { }
+//~^ ERROR: uses type `i128`
+
+pub extern "C" fn transparent_str(p: TransparentStr) { }
+//~^ ERROR: uses type `str`
+
+pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
+//~^ ERROR: uses type `std::boxed::Box<u32>`
+
+pub extern "C" fn good3(fptr: Option<extern fn()>) { }
+
+pub extern "C" fn good4(aptr: &[u8; 4 as usize]) { }
+
+pub extern "C" fn good5(s: StructWithProjection) { }
+
+pub extern "C" fn good6(s: StructWithProjectionAndLifetime) { }
+
+pub extern "C" fn good7(fptr: extern fn() -> ()) { }
+
+pub extern "C" fn good8(fptr: extern fn() -> !) { }
+
+pub extern "C" fn good9() -> () { }
+
+pub extern "C" fn good10() -> CVoidRet { }
+
+pub extern "C" fn good11(size: isize) { }
+
+pub extern "C" fn good12(size: usize) { }
+
+pub extern "C" fn good13(n: TransparentInt) { }
+
+pub extern "C" fn good14(p: TransparentRef) { }
+
+pub extern "C" fn good15(p: TransparentLifetime) { }
+
+pub extern "C" fn good16(p: TransparentUnit<ZeroSize>) { }
+
+pub extern "C" fn good17(p: TransparentCustomZst) { }
+
+#[allow(improper_ctypes)]
+pub extern "C" fn good18(_: &String) { }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub extern "C" fn good1(size: *const libc::c_int) { }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub extern "C" fn good2(size: *const libc::c_uint) { }
+
+pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
+//~^ ERROR uses type `std::marker::PhantomData<bool>`
+    Default::default()
+}
+
+pub extern "C" fn used_generic1<T>(x: T) { }
+
+pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn used_generic3<T: Default>() -> T {
+    Default::default()
+}
+
+pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
+//~^ ERROR: uses type `std::vec::Vec<T>`
+
+pub extern "C" fn used_generic5<T>() -> Vec<T> {
+//~^ ERROR: uses type `std::vec::Vec<T>`
+    Default::default()
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr
new file mode 100644
index 00000000000..59bd6bfc5af
--- /dev/null
+++ b/src/test/ui/lint/lint-ctypes-fn.stderr
@@ -0,0 +1,247 @@
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:63:35
+   |
+LL | pub extern "C" fn ptr_type1(size: *const Foo) { }
+   |                                   ^^^^^^^^^^ not FFI-safe
+   |
+note: lint level defined here
+  --> $DIR/lint-ctypes-fn.rs:4:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:66:35
+   |
+LL | pub extern "C" fn ptr_type2(size: *const Foo) { }
+   |                                   ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `[u32]`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:69:33
+   |
+LL | pub extern "C" fn slice_type(p: &[u32]) { }
+   |                                 ^^^^^^ not FFI-safe
+   |
+   = help: consider using a raw pointer instead
+   = note: slices have no C equivalent
+
+error: `extern` fn uses type `str`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:72:31
+   |
+LL | pub extern "C" fn str_type(p: &str) { }
+   |                               ^^^^ not FFI-safe
+   |
+   = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
+
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:75:31
+   |
+LL | pub extern "C" fn box_type(p: Box<u32>) { }
+   |                               ^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `char`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:78:32
+   |
+LL | pub extern "C" fn char_type(p: char) { }
+   |                                ^^^^ not FFI-safe
+   |
+   = help: consider using `u32` or `libc::wchar_t` instead
+   = note: the `char` type has no C equivalent
+
+error: `extern` fn uses type `i128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:81:32
+   |
+LL | pub extern "C" fn i128_type(p: i128) { }
+   |                                ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `u128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:84:32
+   |
+LL | pub extern "C" fn u128_type(p: u128) { }
+   |                                ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:87:33
+   |
+LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
+   |                                 ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using a struct instead
+   = note: tuples have unspecified layout
+
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:90:34
+   |
+LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
+   |                                  ^^^^^^^ not FFI-safe
+   |
+   = help: consider using a struct instead
+   = note: tuples have unspecified layout
+
+error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:93:32
+   |
+LL | pub extern "C" fn zero_size(p: ZeroSize) { }
+   |                                ^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a member to this struct
+   = note: this struct has no fields
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:26:1
+   |
+LL | pub struct ZeroSize;
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:96:40
+   |
+LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:61:1
+   |
+LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:99:51
+   |
+LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
+   |                                                   ^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+
+error: `extern` fn uses type `fn()`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:104:30
+   |
+LL | pub extern "C" fn fn_type(p: RustFn) { }
+   |                              ^^^^^^ not FFI-safe
+   |
+   = help: consider using an `extern fn(...) -> ...` function pointer instead
+   = note: this function pointer has Rust-specific calling convention
+
+error: `extern` fn uses type `fn()`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:107:31
+   |
+LL | pub extern "C" fn fn_type2(p: fn()) { }
+   |                               ^^^^ not FFI-safe
+   |
+   = help: consider using an `extern fn(...) -> ...` function pointer instead
+   = note: this function pointer has Rust-specific calling convention
+
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:110:35
+   |
+LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
+   |                                   ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `i128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:113:39
+   |
+LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
+   |                                       ^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `str`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:116:38
+   |
+LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
+   |                                      ^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
+
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:119:37
+   |
+LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
+   |                                     ^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:161:44
+   |
+LL | pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
+   |                                            ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:164:43
+   |
+LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
+   |                                           ^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:171:48
+   |
+LL | pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
+   |                                                ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:178:39
+   |
+LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
+   |                                       ^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:181:41
+   |
+LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
+   |                                         ^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: aborting due to 24 previous errors
+
diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/must-use-ops.rs
index d0adf6a875d..3e425727e78 100644
--- a/src/test/ui/lint/must-use-ops.rs
+++ b/src/test/ui/lint/must-use-ops.rs
@@ -1,6 +1,6 @@
 // Issue #50124 - Test warning for unused operator expressions
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(unused_must_use)]
 
@@ -9,33 +9,33 @@ fn main() {
     let val_pointer = &val;
 
 // Comparison Operators
-    val == 1;
-    val < 1;
-    val <= 1;
-    val != 1;
-    val >= 1;
-    val > 1;
+    val == 1; //~ WARNING unused comparison
+    val < 1; //~ WARNING unused comparison
+    val <= 1; //~ WARNING unused comparison
+    val != 1; //~ WARNING unused comparison
+    val >= 1; //~ WARNING unused comparison
+    val > 1; //~ WARNING unused comparison
 
 // Arithmetic Operators
-    val + 2;
-    val - 2;
-    val / 2;
-    val * 2;
-    val % 2;
+    val + 2; //~ WARNING unused arithmetic operation
+    val - 2; //~ WARNING unused arithmetic operation
+    val / 2; //~ WARNING unused arithmetic operation
+    val * 2; //~ WARNING unused arithmetic operation
+    val % 2; //~ WARNING unused arithmetic operation
 
 // Logical Operators
-    true && true;
-    false || true;
+    true && true; //~ WARNING unused logical operation
+    false || true; //~ WARNING unused logical operation
 
 // Bitwise Operators
-    5 ^ val;
-    5 & val;
-    5 | val;
-    5 << val;
-    5 >> val;
+    5 ^ val; //~ WARNING unused bitwise operation
+    5 & val; //~ WARNING unused bitwise operation
+    5 | val; //~ WARNING unused bitwise operation
+    5 << val; //~ WARNING unused bitwise operation
+    5 >> val; //~ WARNING unused bitwise operation
 
 // Unary Operators
-    !val;
-    -val;
-    *val_pointer;
+    !val; //~ WARNING unused unary operation
+    -val; //~ WARNING unused unary operation
+    *val_pointer; //~ WARNING unused unary operation
 }
diff --git a/src/test/ui/lint/not_found.rs b/src/test/ui/lint/not_found.rs
index 979a67b1558..de120b6e084 100644
--- a/src/test/ui/lint/not_found.rs
+++ b/src/test/ui/lint/not_found.rs
@@ -1,13 +1,21 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // this tests the `unknown_lint` lint, especially the suggestions
 
 // the suggestion only appears if a lint with the lowercase name exists
 #[allow(FOO_BAR)]
+//~^ WARNING unknown lint
+
 // the suggestion appears on all-uppercase names
 #[warn(DEAD_CODE)]
+//~^ WARNING unknown lint
+//~| HELP did you mean
+
 // the suggestion appears also on mixed-case names
 #[deny(Warnings)]
+//~^ WARNING unknown lint
+//~| HELP did you mean
+
 fn main() {
     unimplemented!();
 }
diff --git a/src/test/ui/lint/not_found.stderr b/src/test/ui/lint/not_found.stderr
index 5016d9b97d6..5a651e9ce0f 100644
--- a/src/test/ui/lint/not_found.stderr
+++ b/src/test/ui/lint/not_found.stderr
@@ -7,13 +7,13 @@ LL | #[allow(FOO_BAR)]
    = note: `#[warn(unknown_lints)]` on by default
 
 warning: unknown lint: `DEAD_CODE`
-  --> $DIR/not_found.rs:8:8
+  --> $DIR/not_found.rs:10:8
    |
 LL | #[warn(DEAD_CODE)]
    |        ^^^^^^^^^ help: did you mean: `dead_code`
 
 warning: unknown lint: `Warnings`
-  --> $DIR/not_found.rs:10:8
+  --> $DIR/not_found.rs:15:8
    |
 LL | #[deny(Warnings)]
    |        ^^^^^^^^ help: did you mean (notice the capitalization): `warnings`
diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs
index 5cf62b86912..473be434a75 100644
--- a/src/test/ui/lint/uninitialized-zeroed.rs
+++ b/src/test/ui/lint/uninitialized-zeroed.rs
@@ -67,6 +67,9 @@ fn main() {
         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
 
+        let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: *const dyn Send = 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
@@ -82,10 +85,16 @@ fn main() {
         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
 
+        // `MaybeUninit` cases
+        let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); //~ ERROR: does not permit zero-initialization
+        let _val: NonNull<i32> = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized
+        let _val: bool = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized
+
         // 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: i32 = mem::zeroed();
+        let _val: bool = MaybeUninit::zeroed().assume_init();
     }
 }
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
index a36a32a39a1..bdb5959953f 100644
--- a/src/test/ui/lint/uninitialized-zeroed.stderr
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -5,7 +5,7 @@ LL |         let _val: &'static T = mem::zeroed();
    |                                ^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: lint level defined here
   --> $DIR/uninitialized-zeroed.rs:7:9
@@ -21,7 +21,7 @@ LL |         let _val: &'static T = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
@@ -32,7 +32,7 @@ LL |         let _val: Wrap<&'static T> = mem::zeroed();
    |                                      ^^^^^^^^^^^^^
    |                                      |
    |                                      this code causes undefined behavior when executed
-   |                                      help: use `MaybeUninit<T>` instead
+   |                                      help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -47,7 +47,7 @@ LL |         let _val: Wrap<&'static T> = mem::uninitialized();
    |                                      ^^^^^^^^^^^^^^^^^^^^
    |                                      |
    |                                      this code causes undefined behavior when executed
-   |                                      help: use `MaybeUninit<T>` instead
+   |                                      help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -62,7 +62,7 @@ LL |         let _val: ! = mem::zeroed();
    |                       ^^^^^^^^^^^^^
    |                       |
    |                       this code causes undefined behavior when executed
-   |                       help: use `MaybeUninit<T>` instead
+   |                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -73,7 +73,7 @@ LL |         let _val: ! = mem::uninitialized();
    |                       ^^^^^^^^^^^^^^^^^^^^
    |                       |
    |                       this code causes undefined behavior when executed
-   |                       help: use `MaybeUninit<T>` instead
+   |                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -84,7 +84,7 @@ LL |         let _val: (i32, !) = mem::zeroed();
    |                              ^^^^^^^^^^^^^
    |                              |
    |                              this code causes undefined behavior when executed
-   |                              help: use `MaybeUninit<T>` instead
+   |                              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -95,7 +95,7 @@ LL |         let _val: (i32, !) = mem::uninitialized();
    |                              ^^^^^^^^^^^^^^^^^^^^
    |                              |
    |                              this code causes undefined behavior when executed
-   |                              help: use `MaybeUninit<T>` instead
+   |                              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -106,7 +106,7 @@ LL |         let _val: Void = mem::zeroed();
    |                          ^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: 0-variant enums have no valid value
 
@@ -117,7 +117,7 @@ LL |         let _val: Void = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: 0-variant enums have no valid value
 
@@ -128,7 +128,7 @@ LL |         let _val: &'static i32 = mem::zeroed();
    |                                  ^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
@@ -139,7 +139,7 @@ LL |         let _val: &'static i32 = mem::uninitialized();
    |                                  ^^^^^^^^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
@@ -150,7 +150,7 @@ LL |         let _val: Ref = mem::zeroed();
    |                         ^^^^^^^^^^^^^
    |                         |
    |                         this code causes undefined behavior when executed
-   |                         help: use `MaybeUninit<T>` instead
+   |                         help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:15:12
@@ -165,7 +165,7 @@ LL |         let _val: Ref = mem::uninitialized();
    |                         ^^^^^^^^^^^^^^^^^^^^
    |                         |
    |                         this code causes undefined behavior when executed
-   |                         help: use `MaybeUninit<T>` instead
+   |                         help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:15:12
@@ -180,7 +180,7 @@ LL |         let _val: fn() = mem::zeroed();
    |                          ^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: Function pointers must be non-null
 
@@ -191,7 +191,7 @@ LL |         let _val: fn() = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: Function pointers must be non-null
 
@@ -202,7 +202,7 @@ LL |         let _val: Wrap<fn()> = mem::zeroed();
    |                                ^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -217,7 +217,7 @@ LL |         let _val: Wrap<fn()> = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -232,7 +232,7 @@ LL |         let _val: WrapEnum<fn()> = mem::zeroed();
    |                                    ^^^^^^^^^^^^^
    |                                    |
    |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead
+   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this enum field)
   --> $DIR/uninitialized-zeroed.rs:19:28
@@ -247,7 +247,7 @@ LL |         let _val: WrapEnum<fn()> = mem::uninitialized();
    |                                    ^^^^^^^^^^^^^^^^^^^^
    |                                    |
    |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead
+   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this enum field)
   --> $DIR/uninitialized-zeroed.rs:19:28
@@ -262,7 +262,7 @@ LL |         let _val: Wrap<(RefPair, i32)> = mem::zeroed();
    |                                          ^^^^^^^^^^^^^
    |                                          |
    |                                          this code causes undefined behavior when executed
-   |                                          help: use `MaybeUninit<T>` instead
+   |                                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:16:16
@@ -277,7 +277,7 @@ LL |         let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
    |                                          ^^^^^^^^^^^^^^^^^^^^
    |                                          |
    |                                          this code causes undefined behavior when executed
-   |                                          help: use `MaybeUninit<T>` instead
+   |                                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:16:16
@@ -292,7 +292,7 @@ LL |         let _val: NonNull<i32> = mem::zeroed();
    |                                  ^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: std::ptr::NonNull<i32> must be non-null
 
@@ -303,29 +303,51 @@ LL |         let _val: NonNull<i32> = mem::uninitialized();
    |                                  ^^^^^^^^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: std::ptr::NonNull<i32> must be non-null
 
+error: the type `*const dyn std::marker::Send` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:70:37
+   |
+LL |         let _val: *const dyn Send = mem::zeroed();
+   |                                     ^^^^^^^^^^^^^
+   |                                     |
+   |                                     this code causes undefined behavior when executed
+   |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: The vtable of a wide raw pointer must be non-null
+
+error: the type `*const dyn std::marker::Send` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:71:37
+   |
+LL |         let _val: *const dyn Send = mem::uninitialized();
+   |                                     ^^^^^^^^^^^^^^^^^^^^
+   |                                     |
+   |                                     this code causes undefined behavior when executed
+   |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: The vtable of a wide raw pointer must be non-null
+
 error: the type `bool` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:72:26
+  --> $DIR/uninitialized-zeroed.rs:75:26
    |
 LL |         let _val: bool = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: Booleans must be `true` or `false`
 
 error: the type `Wrap<char>` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:75:32
+  --> $DIR/uninitialized-zeroed.rs:78:32
    |
 LL |         let _val: Wrap<char> = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Characters must be a valid unicode codepoint (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -334,48 +356,81 @@ LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `NonBig` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:78:28
+  --> $DIR/uninitialized-zeroed.rs:81:28
    |
 LL |         let _val: NonBig = mem::uninitialized();
    |                            ^^^^^^^^^^^^^^^^^^^^
    |                            |
    |                            this code causes undefined behavior when executed
-   |                            help: use `MaybeUninit<T>` instead
+   |                            help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = 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
+  --> $DIR/uninitialized-zeroed.rs:84:34
    |
 LL |         let _val: &'static i32 = mem::transmute(0usize);
    |                                  ^^^^^^^^^^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
 error: the type `&'static [i32]` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:82:36
+  --> $DIR/uninitialized-zeroed.rs:85:36
    |
 LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                    |
    |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead
+   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
 error: the type `std::num::NonZeroU32` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:83:32
+  --> $DIR/uninitialized-zeroed.rs:86:32
    |
 LL |         let _val: NonZeroU32 = mem::transmute(0);
    |                                ^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: std::num::NonZeroU32 must be non-null
 
-error: aborting due to 30 previous errors
+error: the type `std::ptr::NonNull<i32>` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:89:34
+   |
+LL |         let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = 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:90:34
+   |
+LL |         let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `bool` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:91:26
+   |
+LL |         let _val: bool = MaybeUninit::uninit().assume_init();
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                          |
+   |                          this code causes undefined behavior when executed
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: Booleans must be `true` or `false`
+
+error: aborting due to 35 previous errors
 
diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.rs b/src/test/ui/lint/unreachable_pub-pub_crate.rs
index 27b437b22eb..94f79d69751 100644
--- a/src/test/ui/lint/unreachable_pub-pub_crate.rs
+++ b/src/test/ui/lint/unreachable_pub-pub_crate.rs
@@ -4,44 +4,45 @@
 // suggestions to use `crate` given when it is on). When that feature becomes
 // stable, this test can be deleted.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 
-#![allow(unused)]
 #![warn(unreachable_pub)]
 
 mod private_mod {
     // non-leaked `pub` items in private module should be linted
-    pub use std::fmt;
+    pub use std::fmt; //~ WARNING unreachable_pub
     pub use std::env::{Args}; // braced-use has different item spans than unbraced
+    //~^ WARNING unreachable_pub
 
-    pub struct Hydrogen {
+    pub struct Hydrogen { //~ WARNING unreachable_pub
         // `pub` struct fields, too
-        pub neutrons: usize,
+        pub neutrons: usize, //~ WARNING unreachable_pub
         // (... but not more-restricted fields)
         pub(crate) electrons: usize
     }
     impl Hydrogen {
         // impls, too
-        pub fn count_neutrons(&self) -> usize { self.neutrons }
+        pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
         pub(crate) fn count_electrons(&self) -> usize { self.electrons }
     }
 
-    pub enum Helium {}
-    pub union Lithium { c1: usize, c2: u8 }
-    pub fn beryllium() {}
-    pub trait Boron {}
-    pub const CARBON: usize = 1;
-    pub static NITROGEN: usize = 2;
-    pub type Oxygen = bool;
+    pub enum Helium {} //~ WARNING unreachable_pub
+    pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub
+    pub fn beryllium() {} //~ WARNING unreachable_pub
+    pub trait Boron {} //~ WARNING unreachable_pub
+    pub const CARBON: usize = 1; //~ WARNING unreachable_pub
+    pub static NITROGEN: usize = 2; //~ WARNING unreachable_pub
+    pub type Oxygen = bool; //~ WARNING unreachable_pub
 
     macro_rules! define_empty_struct_with_visibility {
         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
+        //~^ WARNING unreachable_pub
     }
     define_empty_struct_with_visibility!(pub, Fluorine);
 
     extern {
-        pub fn catalyze() -> bool;
+        pub fn catalyze() -> bool; //~ WARNING unreachable_pub
     }
 
     // items leaked through signatures (see `get_neon` below) are OK
diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.stderr b/src/test/ui/lint/unreachable_pub-pub_crate.stderr
index 2b3f74a18af..da21c2ac4ab 100644
--- a/src/test/ui/lint/unreachable_pub-pub_crate.stderr
+++ b/src/test/ui/lint/unreachable_pub-pub_crate.stderr
@@ -1,5 +1,5 @@
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:15:5
+  --> $DIR/unreachable_pub-pub_crate.rs:14:5
    |
 LL |     pub use std::fmt;
    |     ---^^^^^^^^^^^^^^
@@ -7,14 +7,14 @@ LL |     pub use std::fmt;
    |     help: consider restricting its visibility: `pub(crate)`
    |
 note: lint level defined here
-  --> $DIR/unreachable_pub-pub_crate.rs:11:9
+  --> $DIR/unreachable_pub-pub_crate.rs:10:9
    |
 LL | #![warn(unreachable_pub)]
    |         ^^^^^^^^^^^^^^^
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:16:24
+  --> $DIR/unreachable_pub-pub_crate.rs:15:24
    |
 LL |     pub use std::env::{Args}; // braced-use has different item spans than unbraced
    |     ---                ^^^^
@@ -124,7 +124,7 @@ warning: unreachable `pub` item
    |
 LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^
-LL |     }
+...
 LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    |     ----------------------------------------------------
    |     |                                    |
@@ -134,7 +134,7 @@ LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub-pub_crate.rs:44:9
+  --> $DIR/unreachable_pub-pub_crate.rs:45:9
    |
 LL |         pub fn catalyze() -> bool;
    |         ---^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/unreachable_pub.rs b/src/test/ui/lint/unreachable_pub.rs
index 545281604ea..a4c14970139 100644
--- a/src/test/ui/lint/unreachable_pub.rs
+++ b/src/test/ui/lint/unreachable_pub.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(crate_visibility_modifier)]
 
@@ -7,36 +7,38 @@
 
 mod private_mod {
     // non-leaked `pub` items in private module should be linted
-    pub use std::fmt;
+    pub use std::fmt; //~ WARNING unreachable_pub
     pub use std::env::{Args}; // braced-use has different item spans than unbraced
+    //~^ WARNING unreachable_pub
 
-    pub struct Hydrogen {
+    pub struct Hydrogen { //~ WARNING unreachable_pub
         // `pub` struct fields, too
-        pub neutrons: usize,
+        pub neutrons: usize, //~ WARNING unreachable_pub
         // (... but not more-restricted fields)
         crate electrons: usize
     }
     impl Hydrogen {
         // impls, too
-        pub fn count_neutrons(&self) -> usize { self.neutrons }
+        pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub
         crate fn count_electrons(&self) -> usize { self.electrons }
     }
 
-    pub enum Helium {}
-    pub union Lithium { c1: usize, c2: u8 }
-    pub fn beryllium() {}
-    pub trait Boron {}
-    pub const CARBON: usize = 1;
-    pub static NITROGEN: usize = 2;
-    pub type Oxygen = bool;
+    pub enum Helium {} //~ WARNING unreachable_pub
+    pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub
+    pub fn beryllium() {} //~ WARNING unreachable_pub
+    pub trait Boron {} //~ WARNING unreachable_pub
+    pub const CARBON: usize = 1; //~ WARNING unreachable_pub
+    pub static NITROGEN: usize = 2; //~ WARNING unreachable_pub
+    pub type Oxygen = bool; //~ WARNING unreachable_pub
 
     macro_rules! define_empty_struct_with_visibility {
         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
+        //~^ WARNING unreachable_pub
     }
     define_empty_struct_with_visibility!(pub, Fluorine);
 
     extern {
-        pub fn catalyze() -> bool;
+        pub fn catalyze() -> bool; //~ WARNING unreachable_pub
     }
 
     // items leaked through signatures (see `get_neon` below) are OK
diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr
index 6352f3e2c5c..2cb27a770ed 100644
--- a/src/test/ui/lint/unreachable_pub.stderr
+++ b/src/test/ui/lint/unreachable_pub.stderr
@@ -24,7 +24,7 @@ LL |     pub use std::env::{Args}; // braced-use has different item spans than u
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:13:5
+  --> $DIR/unreachable_pub.rs:14:5
    |
 LL |     pub struct Hydrogen {
    |     ---^^^^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ LL |     pub struct Hydrogen {
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` field
-  --> $DIR/unreachable_pub.rs:15:9
+  --> $DIR/unreachable_pub.rs:16:9
    |
 LL |         pub neutrons: usize,
    |         ---^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL |         pub neutrons: usize,
    |         help: consider restricting its visibility: `crate`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:21:9
+  --> $DIR/unreachable_pub.rs:22:9
    |
 LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +50,7 @@ LL |         pub fn count_neutrons(&self) -> usize { self.neutrons }
    |         help: consider restricting its visibility: `crate`
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:25:5
+  --> $DIR/unreachable_pub.rs:26:5
    |
 LL |     pub enum Helium {}
    |     ---^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL |     pub enum Helium {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:26:5
+  --> $DIR/unreachable_pub.rs:27:5
    |
 LL |     pub union Lithium { c1: usize, c2: u8 }
    |     ---^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     pub union Lithium { c1: usize, c2: u8 }
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:27:5
+  --> $DIR/unreachable_pub.rs:28:5
    |
 LL |     pub fn beryllium() {}
    |     ---^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     pub fn beryllium() {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:28:5
+  --> $DIR/unreachable_pub.rs:29:5
    |
 LL |     pub trait Boron {}
    |     ---^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     pub trait Boron {}
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:29:5
+  --> $DIR/unreachable_pub.rs:30:5
    |
 LL |     pub const CARBON: usize = 1;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@ LL |     pub const CARBON: usize = 1;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:30:5
+  --> $DIR/unreachable_pub.rs:31:5
    |
 LL |     pub static NITROGEN: usize = 2;
    |     ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,7 +110,7 @@ LL |     pub static NITROGEN: usize = 2;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:31:5
+  --> $DIR/unreachable_pub.rs:32:5
    |
 LL |     pub type Oxygen = bool;
    |     ---^^^^^^^^^^^^^^^^^^^^
@@ -120,11 +120,11 @@ LL |     pub type Oxygen = bool;
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:34:47
+  --> $DIR/unreachable_pub.rs:35:47
    |
 LL |         ($visibility: vis, $name: ident) => { $visibility struct $name {} }
    |                                               ^^^^^^^^^^^^^^^^^^^^^^^^
-LL |     }
+...
 LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    |     ----------------------------------------------------
    |     |                                    |
@@ -134,7 +134,7 @@ LL |     define_empty_struct_with_visibility!(pub, Fluorine);
    = help: or consider exporting it for use by other crates
 
 warning: unreachable `pub` item
-  --> $DIR/unreachable_pub.rs:39:9
+  --> $DIR/unreachable_pub.rs:41:9
    |
 LL |         pub fn catalyze() -> bool;
    |         ---^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/unused_import_warning_issue_45268.rs b/src/test/ui/lint/unused_import_warning_issue_45268.rs
index 68a5819c9c7..5ae48286340 100644
--- a/src/test/ui/lint/unused_import_warning_issue_45268.rs
+++ b/src/test/ui/lint/unused_import_warning_issue_45268.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(unused_imports)] // Warning explanation here, it's OK
 
@@ -24,6 +24,7 @@ mod test {
 }
 
 use test::Unused;   // This is really unused, so warning is OK
+                    //~^ WARNING unused import
 use test::A;        // This is used by the test2::func() through import of super::*
 use test::B;        // This is used by the test2::func() through import of super::*
 
diff --git a/src/test/ui/macro_backtrace/main.stderr b/src/test/ui/macro_backtrace/main.stderr
index e7bd141ccd5..c4950e0fdf5 100644
--- a/src/test/ui/macro_backtrace/main.stderr
+++ b/src/test/ui/macro_backtrace/main.stderr
@@ -3,7 +3,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
    |
 LL | / macro_rules! pong {
 LL | |     () => { syntax error };
-   | |                    ^^^^^ expected one of 8 possible tokens here
+   | |                    ^^^^^ expected one of 8 possible tokens
 LL | | }
    | |_- in this expansion of `pong!`
 ...
@@ -15,7 +15,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
    |
 LL | / macro_rules! pong {
 LL | |     () => { syntax error };
-   | |                    ^^^^^ expected one of 8 possible tokens here
+   | |                    ^^^^^ expected one of 8 possible tokens
 LL | | }
    | |_- in this expansion of `pong!`
 ...
@@ -35,7 +35,7 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
    |
 LL | / macro_rules! pong {
 LL | |     () => { syntax error };
-   | |                    ^^^^^ expected one of 8 possible tokens here
+   | |                    ^^^^^ expected one of 8 possible tokens
 LL | | }
    | |_- in this expansion of `pong!` (#5)
 ...
diff --git a/src/test/ui/macros/assert-trailing-junk.stderr b/src/test/ui/macros/assert-trailing-junk.stderr
index 6fc0a278461..4d18a531a80 100644
--- a/src/test/ui/macros/assert-trailing-junk.stderr
+++ b/src/test/ui/macros/assert-trailing-junk.stderr
@@ -2,13 +2,13 @@ error: expected one of `,`, `.`, `?`, or an operator, found `some`
   --> $DIR/assert-trailing-junk.rs:6:18
    |
 LL |     assert!(true some extra junk, "whatever");
-   |                  ^^^^ expected one of `,`, `.`, `?`, or an operator here
+   |                  ^^^^ expected one of `,`, `.`, `?`, or an operator
 
 error: expected one of `,`, `.`, `?`, or an operator, found `some`
   --> $DIR/assert-trailing-junk.rs:9:18
    |
 LL |     assert!(true some extra junk);
-   |                  ^^^^ expected one of `,`, `.`, `?`, or an operator here
+   |                  ^^^^ expected one of `,`, `.`, `?`, or an operator
 
 error: no rules expected the token `blah`
   --> $DIR/assert-trailing-junk.rs:12:30
diff --git a/src/test/ui/macros/issue-54441.stderr b/src/test/ui/macros/issue-54441.stderr
index 287d579c76d..1139ef06a12 100644
--- a/src/test/ui/macros/issue-54441.stderr
+++ b/src/test/ui/macros/issue-54441.stderr
@@ -2,7 +2,7 @@ error: expected one of `crate`, `fn`, `pub`, `static`, or `type`, found keyword
   --> $DIR/issue-54441.rs:3:9
    |
 LL |         let
-   |         ^^^ expected one of `crate`, `fn`, `pub`, `static`, or `type` here
+   |         ^^^ expected one of `crate`, `fn`, `pub`, `static`, or `type`
 ...
 LL |     m!();
    |     ----- in this macro invocation
diff --git a/src/test/ui/macros/macro-lifetime-used-with-labels.rs b/src/test/ui/macros/macro-lifetime-used-with-labels.rs
index 4c4bccbc12b..86a3e9f44c3 100644
--- a/src/test/ui/macros/macro-lifetime-used-with-labels.rs
+++ b/src/test/ui/macros/macro-lifetime-used-with-labels.rs
@@ -18,7 +18,7 @@ macro_rules! br {
 }
 macro_rules! br2 {
     ($b:lifetime) => {
-        'b: loop {
+        'b: loop { //~ WARNING `'b` shadows a label name that is already in scope
             break $b; // this $b should refer to the outer loop.
         }
     }
diff --git a/src/test/ui/macros/macro-path-prelude-pass.rs b/src/test/ui/macros/macro-path-prelude-pass.rs
index 8daa1c84f1d..7cf346286ea 100644
--- a/src/test/ui/macros/macro-path-prelude-pass.rs
+++ b/src/test/ui/macros/macro-path-prelude-pass.rs
@@ -1,6 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
-
-#![feature(extern_prelude)]
+// check-pass
 
 mod m {
     fn check() {
diff --git a/src/test/ui/macros/macro-path-prelude-pass.stderr b/src/test/ui/macros/macro-path-prelude-pass.stderr
deleted file mode 100644
index c6e7fd77cd9..00000000000
--- a/src/test/ui/macros/macro-path-prelude-pass.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-warning: the feature `extern_prelude` has been stable since 1.30.0 and no longer requires an attribute to enable
-  --> $DIR/macro-path-prelude-pass.rs:3:12
-   |
-LL | #![feature(extern_prelude)]
-   |            ^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(stable_features)]` on by default
-
diff --git a/src/test/ui/macros/macro-use-all-and-none.rs b/src/test/ui/macros/macro-use-all-and-none.rs
index e5f67d458d2..c8bd44008b0 100644
--- a/src/test/ui/macros/macro-use-all-and-none.rs
+++ b/src/test/ui/macros/macro-use-all-and-none.rs
@@ -4,7 +4,7 @@
 #![warn(unused_attributes)]
 
 #[macro_use]
-#[macro_use()]
+#[macro_use()] //~ WARNING unused attribute
 extern crate two_macros_rpass;
 
 pub fn main() {
diff --git a/src/test/ui/malformed/malformed-derive-entry.stderr b/src/test/ui/malformed/malformed-derive-entry.stderr
index f7500febe97..8d750b66838 100644
--- a/src/test/ui/malformed/malformed-derive-entry.stderr
+++ b/src/test/ui/malformed/malformed-derive-entry.stderr
@@ -2,13 +2,13 @@ error: expected one of `)`, `,`, or `::`, found `(`
   --> $DIR/malformed-derive-entry.rs:1:14
    |
 LL | #[derive(Copy(Bad))]
-   |              ^ expected one of `)`, `,`, or `::` here
+   |              ^ expected one of `)`, `,`, or `::`
 
 error: expected one of `)`, `,`, or `::`, found `=`
   --> $DIR/malformed-derive-entry.rs:4:14
    |
 LL | #[derive(Copy="bad")]
-   |              ^ expected one of `)`, `,`, or `::` here
+   |              ^ expected one of `)`, `,`, or `::`
 
 error: malformed `derive` attribute input
   --> $DIR/malformed-derive-entry.rs:7:1
diff --git a/src/test/ui/malformed/malformed-regressions.rs b/src/test/ui/malformed/malformed-regressions.rs
index 1eca8c73904..ac1444bbaef 100644
--- a/src/test/ui/malformed/malformed-regressions.rs
+++ b/src/test/ui/malformed/malformed-regressions.rs
@@ -1,18 +1,12 @@
-// build-pass (FIXME(62277): could be check-pass?)
+#[doc] //~ ERROR attribute must be of the form
+//~^ WARN this was previously accepted
+#[ignore()] //~ ERROR attribute must be of the form
+//~^ WARN this was previously accepted
+#[inline = ""] //~ ERROR attribute must be of the form
+//~^ WARN this was previously accepted
+#[link] //~ ERROR attribute must be of the form
+//~^ WARN this was previously accepted
+#[link = ""] //~ ERROR attribute must be of the form
+//~^ WARN this was previously accepted
 
-#[doc]
-//~^ WARN attribute must be of the form
-//~| WARN this was previously accepted
-#[ignore()]
-//~^ WARN attribute must be of the form
-//~| WARN this was previously accepted
-#[inline = ""]
-//~^ WARN attribute must be of the form
-//~| WARN this was previously accepted
-#[link]
-//~^WARN attribute must be of the form
-//~| WARN this was previously accepted
-#[link = ""]
-//~^ WARN attribute must be of the form
-//~| WARN this was previously accepted
 fn main() {}
diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index 8f4e952338f..b14f99be50c 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -1,15 +1,15 @@
-warning: attribute must be of the form `#[doc(hidden|inline|...)]` or `#[doc = "string"]`
-  --> $DIR/malformed-regressions.rs:3:1
+error: attribute must be of the form `#[doc(hidden|inline|...)]` or `#[doc = "string"]`
+  --> $DIR/malformed-regressions.rs:1:1
    |
 LL | #[doc]
    | ^^^^^^
    |
-   = note: `#[warn(ill_formed_attribute_input)]` on by default
+   = note: `#[deny(ill_formed_attribute_input)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-warning: attribute must be of the form `#[ignore]` or `#[ignore = "reason"]`
-  --> $DIR/malformed-regressions.rs:6:1
+error: attribute must be of the form `#[ignore]` or `#[ignore = "reason"]`
+  --> $DIR/malformed-regressions.rs:3:1
    |
 LL | #[ignore()]
    | ^^^^^^^^^^^
@@ -17,8 +17,8 @@ LL | #[ignore()]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-warning: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
-  --> $DIR/malformed-regressions.rs:9:1
+error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
+  --> $DIR/malformed-regressions.rs:5:1
    |
 LL | #[inline = ""]
    | ^^^^^^^^^^^^^^
@@ -26,8 +26,8 @@ LL | #[inline = ""]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
-  --> $DIR/malformed-regressions.rs:12:1
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
+  --> $DIR/malformed-regressions.rs:7:1
    |
 LL | #[link]
    | ^^^^^^^
@@ -35,8 +35,8 @@ LL | #[link]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
-  --> $DIR/malformed-regressions.rs:15:1
+error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
+  --> $DIR/malformed-regressions.rs:9:1
    |
 LL | #[link = ""]
    | ^^^^^^^^^^^^
@@ -44,3 +44,5 @@ LL | #[link = ""]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/mir/mir_assign_eval_order.rs b/src/test/ui/mir/mir_assign_eval_order.rs
new file mode 100644
index 00000000000..1594421b0b1
--- /dev/null
+++ b/src/test/ui/mir/mir_assign_eval_order.rs
@@ -0,0 +1,67 @@
+// Test evaluation order of assignment expressions is right to left.
+
+// run-pass
+
+// We would previously not finish evaluating borrow and FRU expressions before
+// starting on the LHS
+
+struct S(i32);
+
+fn evaluate_reborrow_before_assign() {
+    let mut x = &1;
+    let y = &mut &2;
+    let z = &3;
+    // There's an implicit reborrow of `x` on the right-hand side of the
+    // assignement. Note that writing an explicit reborrow would not show this
+    // bug, as now there would be two reborrows on the right-hand side and at
+    // least one of them would happen before the left-hand side is evaluated.
+    *{ x = z; &mut *y } = x;
+    assert_eq!(*x, 3);
+    assert_eq!(**y, 1);             // y should be assigned the original value of `x`.
+}
+
+fn evaluate_mut_reborrow_before_assign() {
+    let mut x = &mut 1;
+    let y = &mut &mut 2;
+    let z = &mut 3;
+    *{ x = z; &mut *y } = x;
+    assert_eq!(*x, 3);
+    assert_eq!(**y, 1);            // y should be assigned the original value of `x`.
+}
+
+// We should evaluate `x[2]` and borrow the value out *before* evaluating the
+// LHS and changing its value.
+fn evaluate_ref_to_temp_before_assign_slice() {
+    let mut x = &[S(0), S(1), S(2)][..];
+    let y = &mut &S(7);
+    *{ x = &[S(3), S(4), S(5)]; &mut *y } = &x[2];
+    assert_eq!(2, y.0);
+    assert_eq!(5, x[2].0);
+}
+
+// We should evaluate `x[2]` and copy the value out *before* evaluating the LHS
+// and changing its value.
+fn evaluate_fru_to_temp_before_assign_slice() {
+    let mut x = &[S(0), S(1), S(2)][..];
+    let y = &mut S(7);
+    *{ x = &[S(3), S(4), S(5)]; &mut *y } = S { ..x[2] };
+    assert_eq!(2, y.0);
+    assert_eq!(5, x[2].0);
+}
+
+// We should evaluate `*x` and copy the value out *before* evaluating the LHS
+// and dropping `x`.
+fn evaluate_fru_to_temp_before_assign_box() {
+    let x = Box::new(S(0));
+    let y = &mut S(1);
+    *{ drop(x); &mut *y } = S { ..*x };
+    assert_eq!(0, y.0);
+}
+
+fn main() {
+    evaluate_reborrow_before_assign();
+    evaluate_mut_reborrow_before_assign();
+    evaluate_ref_to_temp_before_assign_slice();
+    evaluate_fru_to_temp_before_assign_slice();
+    evaluate_fru_to_temp_before_assign_box();
+}
diff --git a/src/test/ui/mir/mir_cast_fn_ret.rs b/src/test/ui/mir/mir_cast_fn_ret.rs
index 69fd64c1c09..6b37ac37040 100644
--- a/src/test/ui/mir/mir_cast_fn_ret.rs
+++ b/src/test/ui/mir/mir_cast_fn_ret.rs
@@ -1,8 +1,10 @@
 // run-pass
+#[allow(improper_ctypes)]
 pub extern "C" fn tuple2() -> (u16, u8) {
     (1, 2)
 }
 
+#[allow(improper_ctypes)]
 pub extern "C" fn tuple3() -> (u8, u8, u8) {
     (1, 2, 3)
 }
diff --git a/src/test/ui/mir/mir_codegen_calls.rs b/src/test/ui/mir/mir_codegen_calls.rs
index fc0db03e3a9..c45629eddff 100644
--- a/src/test/ui/mir/mir_codegen_calls.rs
+++ b/src/test/ui/mir/mir_codegen_calls.rs
@@ -74,6 +74,7 @@ fn test8() -> isize {
     Two::two()
 }
 
+#[allow(improper_ctypes)]
 extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
     x + y.0 * y.1
 }
diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr
index 4a9afb9d249..39eca93f88d 100644
--- a/src/test/ui/mismatched_types/issue-35030.stderr
+++ b/src/test/ui/mismatched_types/issue-35030.stderr
@@ -1,10 +1,13 @@
 error[E0308]: mismatched types
   --> $DIR/issue-35030.rs:9:14
    |
+LL | impl<bool> Parser<bool> for bool {
+   |      ---- this type parameter
+LL |     fn parse(text: &str) -> Option<bool> {
 LL |         Some(true)
-   |              ^^^^ expected type parameter, found bool
+   |              ^^^^ expected type parameter `bool`, found bool
    |
-   = note: expected type `bool` (type parameter)
+   = note: expected type `bool` (type parameter `bool`)
               found type `bool` (bool)
    = help: type parameters must be constrained to match other types
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
diff --git a/src/test/ui/mismatched_types/recovered-block.stderr b/src/test/ui/mismatched_types/recovered-block.stderr
index 207dc78a4b9..525d09b8fc1 100644
--- a/src/test/ui/mismatched_types/recovered-block.stderr
+++ b/src/test/ui/mismatched_types/recovered-block.stderr
@@ -13,7 +13,7 @@ error: expected one of `(` or `<`, found `{`
   --> $DIR/recovered-block.rs:19:9
    |
 LL |     Foo { text: "".to_string() }
-   |         ^ expected one of `(` or `<` here
+   |         ^ expected one of `(` or `<`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/missing/missing-comma-in-match.fixed b/src/test/ui/missing/missing-comma-in-match.fixed
index de1b9506af9..f091082f35f 100644
--- a/src/test/ui/missing/missing-comma-in-match.fixed
+++ b/src/test/ui/missing/missing-comma-in-match.fixed
@@ -5,7 +5,7 @@ fn main() {
         &None => 1,
         &Some(2) => { 3 }
         //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
-        //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here
+        //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator
         _ => 2
     };
 }
diff --git a/src/test/ui/missing/missing-comma-in-match.rs b/src/test/ui/missing/missing-comma-in-match.rs
index d7d16155cf2..54dab4e9750 100644
--- a/src/test/ui/missing/missing-comma-in-match.rs
+++ b/src/test/ui/missing/missing-comma-in-match.rs
@@ -5,7 +5,7 @@ fn main() {
         &None => 1
         &Some(2) => { 3 }
         //~^ ERROR expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
-        //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator here
+        //~| NOTE expected one of `,`, `.`, `?`, `}`, or an operator
         _ => 2
     };
 }
diff --git a/src/test/ui/missing/missing-comma-in-match.stderr b/src/test/ui/missing/missing-comma-in-match.stderr
index ae46516f8d1..fe210f697c4 100644
--- a/src/test/ui/missing/missing-comma-in-match.stderr
+++ b/src/test/ui/missing/missing-comma-in-match.stderr
@@ -4,7 +4,7 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
 LL |         &None => 1
    |                   - help: missing a comma here to end this `match` arm
 LL |         &Some(2) => { 3 }
-   |                  ^^ expected one of `,`, `.`, `?`, `}`, or an operator here
+   |                  ^^ expected one of `,`, `.`, `?`, `}`, or an operator
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/missing/missing-items/m2.stderr b/src/test/ui/missing/missing-items/m2.stderr
index d2dac4ca645..f8243528d72 100644
--- a/src/test/ui/missing/missing-items/m2.stderr
+++ b/src/test/ui/missing/missing-items/m2.stderr
@@ -4,9 +4,9 @@ error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `met
 LL | impl m1::X for X {
    | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method` in implementation
    |
-   = note: `CONSTANT` from trait: `const CONSTANT: u32;`
-   = note: `Type` from trait: `type Type;`
-   = note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type`
+   = help: implement the missing item: `const CONSTANT: u32 = 42;`
+   = help: implement the missing item: `type Type = Type;`
+   = help: implement the missing item: `fn method(&self, _: std::string::String) -> <Self as m1::X>::Type { unimplemented!() }`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index cc5ffca1047..1f15ce5c212 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -4,7 +4,7 @@ note: No external requirements
 LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                      ^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:13 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:4 ~ escape_argument_callee[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's, 't0> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't0)) i32)),
            ]
@@ -30,7 +30,7 @@ LL | |     deref(p);
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:12 ~ escape_argument_callee[317d]::test[0]) with substs []
+   = note: defining type: DefId(0:3 ~ escape_argument_callee[317d]::test[0]) with substs []
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr
index fdf95b8aceb..610a4aed796 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr
@@ -4,7 +4,7 @@ note: No external requirements
 LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                      ^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:13 ~ escape_argument[317d]::test[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:4 ~ escape_argument[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) mut &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) i32)),
            ]
@@ -21,7 +21,7 @@ LL | |     deref(p);
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:12 ~ escape_argument[317d]::test[0]) with substs []
+   = note: defining type: DefId(0:3 ~ escape_argument[317d]::test[0]) with substs []
 
 error[E0597]: `y` does not live long enough
   --> $DIR/escape-argument.rs:27:25
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
index 186f25a3c89..7c4d48cdf9f 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |             let mut closure1 = || p = &y;
    |                                ^^^^^^^^^
    |
-   = note: defining type: DefId(0:14 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:5 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]::{{closure}}[0]) with closure substs [
                i16,
                extern "rust-call" fn(()),
                &'_#1r i32,
@@ -23,7 +23,7 @@ LL | |             closure1();
 LL | |         };
    | |_________^
    |
-   = note: defining type: DefId(0:13 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:4 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
                extern "rust-call" fn(()),
                &'_#1r i32,
@@ -44,7 +44,7 @@ LL | |     deref(p);
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:12 ~ escape_upvar_nested[317d]::test[0]) with substs []
+   = note: defining type: DefId(0:3 ~ escape_upvar_nested[317d]::test[0]) with substs []
 
 error[E0597]: `y` does not live long enough
   --> $DIR/escape-upvar-nested.rs:21:40
diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
index 0df2c0f69a7..4446486808b 100644
--- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |         let mut closure = || p = &y;
    |                           ^^^^^^^^^
    |
-   = note: defining type: DefId(0:13 ~ escape_upvar_ref[317d]::test[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:4 ~ escape_upvar_ref[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
                extern "rust-call" fn(()),
                &'_#1r i32,
@@ -25,7 +25,7 @@ LL | |     deref(p);
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:12 ~ escape_upvar_ref[317d]::test[0]) with substs []
+   = note: defining type: DefId(0:3 ~ escape_upvar_ref[317d]::test[0]) with substs []
 
 error[E0597]: `y` does not live long enough
   --> $DIR/escape-upvar-ref.rs:23:35
diff --git a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
index 7679bf22e3c..a83ebc21f5f 100644
--- a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
+++ b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Test that we propagate region relations from closures precisely when there is
 // more than one non-local lower bound.
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index 8916fdcfc88..43406c05a25 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -8,7 +8,7 @@ LL | |             demand_y(x, y, p)
 LL | |         },
    | |_________^
    |
-   = note: defining type: DefId(0:27 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:18 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>)),
            ]
@@ -39,7 +39,7 @@ LL | |     );
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:23 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:14 ~ propagate_approximated_fail_no_postdom[317d]::supply[0]) with substs []
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index fa8384311ea..3bd3fc517ce 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -9,7 +9,7 @@ LL | |
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:25 ~ propagate_approximated_ref[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:16 ~ propagate_approximated_ref[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) u32>)),
            ]
@@ -30,7 +30,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:22 ~ propagate_approximated_ref[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:13 ~ propagate_approximated_ref[317d]::supply[0]) with substs []
 
 error: lifetime may not live long enough
   --> $DIR/propagate-approximated-ref.rs:45:9
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index cfaa75b8ef8..5ebc22da036 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -8,7 +8,7 @@ LL | |
 LL | |     })
    | |_____^
    |
-   = note: defining type: DefId(0:18 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case1[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:9 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case1[0]::{{closure}}[0]) with closure substs [
                i32,
                for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>)),
            ]
@@ -35,7 +35,7 @@ LL | |     })
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:17 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case1[0]) with substs []
+   = note: defining type: DefId(0:8 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case1[0]) with substs []
 
 note: External requirements
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:35:15
@@ -46,7 +46,7 @@ LL | |         cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static
 LL | |     })
    | |_____^
    |
-   = note: defining type: DefId(0:20 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case2[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:11 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case2[0]::{{closure}}[0]) with closure substs [
                i32,
                for<'r> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>)),
            ]
@@ -65,7 +65,7 @@ LL | |     })
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:19 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case2[0]) with substs []
+   = note: defining type: DefId(0:10 ~ propagate_approximated_shorter_to_static_comparing_against_free[317d]::case2[0]) with substs []
 
 error[E0597]: `a` does not live long enough
   --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:30:26
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index 601b3577e0e..e93634aa3da 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -10,7 +10,7 @@ LL | |         demand_y(x, y, x.get())
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:25 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:16 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't2)) u32>)),
            ]
@@ -31,7 +31,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:22 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:13 ~ propagate_approximated_shorter_to_static_no_bound[317d]::supply[0]) with substs []
 
 error[E0521]: borrowed data escapes outside of function
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:32:5
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 5b5440e7a96..2127eab4344 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -10,7 +10,7 @@ LL | |         demand_y(x, y, x.get())
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:25 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:16 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't0)) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) u32>)),
            ]
@@ -31,7 +31,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:22 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:13 ~ propagate_approximated_shorter_to_static_wrong_bound[317d]::supply[0]) with substs []
 
 error[E0521]: borrowed data escapes outside of function
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:35:5
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
index a08cde2c9c6..9078877492f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -9,7 +9,7 @@ LL | |
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:25 ~ propagate_approximated_val[317d]::test[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:16 ~ propagate_approximated_val[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>)),
            ]
@@ -30,7 +30,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:22 ~ propagate_approximated_val[317d]::test[0]) with substs []
+   = note: defining type: DefId(0:13 ~ propagate_approximated_val[317d]::test[0]) with substs []
 
 error: lifetime may not live long enough
   --> $DIR/propagate-approximated-val.rs:38:9
diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 60847bb2e92..c5468e73cfa 100644
--- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -8,7 +8,7 @@ LL | |             demand_y(x, y, p)
 LL | |         },
    | |_________^
    |
-   = note: defining type: DefId(0:23 ~ propagate_despite_same_free_region[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:14 ~ propagate_despite_same_free_region[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>)),
            ]
@@ -28,5 +28,5 @@ LL | |     );
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:21 ~ propagate_despite_same_free_region[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:12 ~ propagate_despite_same_free_region[317d]::supply[0]) with substs []
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index a660c763bff..bf43c893865 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -9,7 +9,7 @@ LL | |
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:25 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:16 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>)),
            ]
@@ -39,7 +39,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:22 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:13 ~ propagate_fail_to_approximate_longer_no_bounds[317d]::supply[0]) with substs []
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 9671b8ebff3..569bae999dd 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -9,7 +9,7 @@ LL | |
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:25 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:16 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's, 't0, 't1, 't2, 't3> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) u32>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't3)) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 't1)) u32>)),
            ]
@@ -39,7 +39,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:22 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]) with substs []
+   = note: defining type: DefId(0:13 ~ propagate_fail_to_approximate_longer_wrong_bounds[317d]::supply[0]) with substs []
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
index 457b5950b7f..0d622654c52 100644
--- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr
@@ -11,7 +11,7 @@ LL | |         require(value);
 LL | |     });
    | |_____^
    |
-   = note: defining type: DefId(0:23 ~ propagate_from_trait_match[317d]::supply[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:14 ~ propagate_from_trait_match[317d]::supply[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -32,7 +32,7 @@ LL | |     });
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:20 ~ propagate_from_trait_match[317d]::supply[0]) with substs [
+   = note: defining type: DefId(0:11 ~ propagate_from_trait_match[317d]::supply[0]) with substs [
                '_#1r,
                T,
            ]
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 8aff6d5b892..00c56a796d1 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -4,7 +4,7 @@ note: No external requirements
 LL |     expect_sig(|a, b| b); // ought to return `a`
    |                ^^^^^^^^
    |
-   = note: defining type: DefId(0:13 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:4 ~ return_wrong_bound_region[317d]::test[0]::{{closure}}[0]) with closure substs [
                i16,
                for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) i32, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) i32)) -> &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) i32,
            ]
@@ -27,7 +27,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:12 ~ return_wrong_bound_region[317d]::test[0]) with substs []
+   = note: defining type: DefId(0:3 ~ return_wrong_bound_region[317d]::test[0]) with substs []
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-16223.rs b/src/test/ui/nll/issue-16223.rs
index c1205ba96ad..0ae0ed3d87f 100644
--- a/src/test/ui/nll/issue-16223.rs
+++ b/src/test/ui/nll/issue-16223.rs
@@ -13,7 +13,7 @@
 //    |
 //    = note: move occurs because the value has type `A`, which does not implement the `Copy` trait
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(box_patterns)]
 
diff --git a/src/test/ui/nll/issue-21114-ebfull.rs b/src/test/ui/nll/issue-21114-ebfull.rs
index 5a5db1a17f3..fc4a6845a4f 100644
--- a/src/test/ui/nll/issue-21114-ebfull.rs
+++ b/src/test/ui/nll/issue-21114-ebfull.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::collections::HashMap;
 use std::sync::Mutex;
diff --git a/src/test/ui/nll/issue-21114-kixunil.rs b/src/test/ui/nll/issue-21114-kixunil.rs
index 32c97a651c5..666f89f356d 100644
--- a/src/test/ui/nll/issue-21114-kixunil.rs
+++ b/src/test/ui/nll/issue-21114-kixunil.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn from_stdin(min: u64) -> Vec<u64> {
     use std::io::BufRead;
diff --git a/src/test/ui/nll/issue-22323-temp-destruction.rs b/src/test/ui/nll/issue-22323-temp-destruction.rs
index 1add91b1bd0..3f2ece1cf6c 100644
--- a/src/test/ui/nll/issue-22323-temp-destruction.rs
+++ b/src/test/ui/nll/issue-22323-temp-destruction.rs
@@ -1,7 +1,7 @@
 // rust-lang/rust#22323: regression test demonstrating that NLL
 // precisely tracks temporary destruction order.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     let _s = construct().borrow().consume_borrowed();
diff --git a/src/test/ui/nll/issue-30104.rs b/src/test/ui/nll/issue-30104.rs
index 3f4818a28c8..38850cd3fdf 100644
--- a/src/test/ui/nll/issue-30104.rs
+++ b/src/test/ui/nll/issue-30104.rs
@@ -1,6 +1,6 @@
 // Regression test for #30104
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
index bffff650158..a8a8e693026 100644
--- a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
+++ b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#32382: Borrow checker used to complain about
 // `foobar_3` in the `impl` below, presumably due to some interaction
diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs
index 8bf9028690f..227888d17d3 100644
--- a/src/test/ui/nll/issue-43058.rs
+++ b/src/test/ui/nll/issue-43058.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::borrow::Cow;
 
diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs
index ecd7071ecc7..521643c664d 100644
--- a/src/test/ui/nll/issue-47022.rs
+++ b/src/test/ui/nll/issue-47022.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct LoadedObject {
     bodies: Vec<Body>,
diff --git a/src/test/ui/nll/issue-50716-1.rs b/src/test/ui/nll/issue-50716-1.rs
index 1e602f27247..9c3e24de46e 100644
--- a/src/test/ui/nll/issue-50716-1.rs
+++ b/src/test/ui/nll/issue-50716-1.rs
@@ -3,7 +3,7 @@
 // bounds derived from `Sized` requirements” that checks that the fixed compiler
 // accepts this code fragment with both AST and MIR borrow checkers.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Qey<Q: ?Sized>(Q);
 
diff --git a/src/test/ui/nll/issue-51351.rs b/src/test/ui/nll/issue-51351.rs
index efffe80aae4..591d49584ee 100644
--- a/src/test/ui/nll/issue-51351.rs
+++ b/src/test/ui/nll/issue-51351.rs
@@ -6,7 +6,7 @@
 // of the closure, as they were not present in the closure's generic
 // declarations otherwise.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn creash<'a>() {
     let x: &'a () = &();
diff --git a/src/test/ui/nll/issue-52078.rs b/src/test/ui/nll/issue-52078.rs
index 935bf8cda5e..a2bcb91acf2 100644
--- a/src/test/ui/nll/issue-52078.rs
+++ b/src/test/ui/nll/issue-52078.rs
@@ -2,7 +2,7 @@
 // between `'a` and `'b` below due to inference variables introduced
 // during the normalization process.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Drain<'a, T: 'a> {
     _marker: ::std::marker::PhantomData<&'a T>,
diff --git a/src/test/ui/nll/issue-52534-2.stderr b/src/test/ui/nll/issue-52534-2.stderr
index dd8a87f7e29..cef4aba0240 100644
--- a/src/test/ui/nll/issue-52534-2.stderr
+++ b/src/test/ui/nll/issue-52534-2.stderr
@@ -1,8 +1,8 @@
 error[E0597]: `x` does not live long enough
-  --> $DIR/issue-52534-2.rs:6:9
+  --> $DIR/issue-52534-2.rs:6:13
    |
 LL |         y = &x
-   |         ^^^^^^ borrowed value does not live long enough
+   |             ^^ borrowed value does not live long enough
 LL |
 LL |     }
    |     - `x` dropped here while still borrowed
diff --git a/src/test/ui/nll/issue-53119.rs b/src/test/ui/nll/issue-53119.rs
index f5400aaad8b..03c9c071c9b 100644
--- a/src/test/ui/nll/issue-53119.rs
+++ b/src/test/ui/nll/issue-53119.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::ops::Deref;
 
diff --git a/src/test/ui/nll/issue-53570.rs b/src/test/ui/nll/issue-53570.rs
index 25c1929b227..35860ba9c21 100644
--- a/src/test/ui/nll/issue-53570.rs
+++ b/src/test/ui/nll/issue-53570.rs
@@ -6,7 +6,7 @@
 // parameter `x` -- since `'b` cannot be expressed in the caller's
 // space, that got promoted th `'static`.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::cell::{RefCell, Ref};
 
diff --git a/src/test/ui/nll/issue-55344.rs b/src/test/ui/nll/issue-55344.rs
index a65635585db..20f18dc465d 100644
--- a/src/test/ui/nll/issue-55344.rs
+++ b/src/test/ui/nll/issue-55344.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![deny(unused_mut)]
 
diff --git a/src/test/ui/nll/issue-55651.rs b/src/test/ui/nll/issue-55651.rs
index 73fce288f8b..46255bf74a1 100644
--- a/src/test/ui/nll/issue-55651.rs
+++ b/src/test/ui/nll/issue-55651.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(untagged_unions)]
 
diff --git a/src/test/ui/nll/issue-57280-1.rs b/src/test/ui/nll/issue-57280-1.rs
index f9cea42e7c4..b8979624e50 100644
--- a/src/test/ui/nll/issue-57280-1.rs
+++ b/src/test/ui/nll/issue-57280-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo<'a> {
     const C: &'a u32;
diff --git a/src/test/ui/nll/issue-57280.rs b/src/test/ui/nll/issue-57280.rs
index 65ca23cc88f..b9d336ec395 100644
--- a/src/test/ui/nll/issue-57280.rs
+++ b/src/test/ui/nll/issue-57280.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo {
     const BLAH: &'static str;
diff --git a/src/test/ui/nll/issue-61311-normalize.rs b/src/test/ui/nll/issue-61311-normalize.rs
index 9237c27f57e..77d67b07a40 100644
--- a/src/test/ui/nll/issue-61311-normalize.rs
+++ b/src/test/ui/nll/issue-61311-normalize.rs
@@ -1,7 +1,7 @@
 // Regression test for #61311
 // We would ICE after failing to normalize `Self::Proj` in the `impl` below.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub struct Unit;
 trait Obj {}
diff --git a/src/test/ui/nll/issue-61320-normalize.rs b/src/test/ui/nll/issue-61320-normalize.rs
index 59bceed08f9..095bef03f7c 100644
--- a/src/test/ui/nll/issue-61320-normalize.rs
+++ b/src/test/ui/nll/issue-61320-normalize.rs
@@ -1,7 +1,7 @@
 // Regression test for #61320
 // This is the same issue as #61311, just a larger test case.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub struct AndThen<A, B, F>
 where
diff --git a/src/test/ui/nll/relate_tys/issue-48071.rs b/src/test/ui/nll/relate_tys/issue-48071.rs
index 36cd57a1b2d..73361a0d319 100644
--- a/src/test/ui/nll/relate_tys/issue-48071.rs
+++ b/src/test/ui/nll/relate_tys/issue-48071.rs
@@ -4,7 +4,7 @@
 // placeholder region, but in NLL land it would fail because we had
 // rewritten `'static` to a region variable.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo {
     fn foo(&self) { }
diff --git a/src/test/ui/nll/ty-outlives/issue-53789-1.rs b/src/test/ui/nll/ty-outlives/issue-53789-1.rs
index 2293d7d4bbc..a5201d4bbe8 100644
--- a/src/test/ui/nll/ty-outlives/issue-53789-1.rs
+++ b/src/test/ui/nll/ty-outlives/issue-53789-1.rs
@@ -1,6 +1,6 @@
 // Regression test for #53789.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::collections::BTreeMap;
 
diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs
index 313b615fe80..7dcdd58bb24 100644
--- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs
+++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs
@@ -1,6 +1,6 @@
 // Regression test for #53789.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::collections::BTreeMap;
 use std::ops::Range;
diff --git a/src/test/ui/nll/ty-outlives/issue-55756.rs b/src/test/ui/nll/ty-outlives/issue-55756.rs
index 147ea203489..e1a3bc3c4eb 100644
--- a/src/test/ui/nll/ty-outlives/issue-55756.rs
+++ b/src/test/ui/nll/ty-outlives/issue-55756.rs
@@ -16,7 +16,7 @@
 // Fixed by tweaking the solver to recognize that the constraint from
 // the environment duplicates one from the trait.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![crate_type="lib"]
 
diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
index 9fa54e83812..dd61023a15b 100644
--- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |     with_signature(x, |mut y| Box::new(y.next()))
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:22 ~ projection_no_regions_closure[317d]::no_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:13 ~ projection_no_regions_closure[317d]::no_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -25,7 +25,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:19 ~ projection_no_regions_closure[317d]::no_region[0]) with substs [
+   = note: defining type: DefId(0:10 ~ projection_no_regions_closure[317d]::no_region[0]) with substs [
                '_#1r,
                T,
            ]
@@ -44,7 +44,7 @@ note: External requirements
 LL |     with_signature(x, |mut y| Box::new(y.next()))
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:26 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:17 ~ projection_no_regions_closure[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -64,7 +64,7 @@ LL | |     with_signature(x, |mut y| Box::new(y.next()))
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:23 ~ projection_no_regions_closure[317d]::correct_region[0]) with substs [
+   = note: defining type: DefId(0:14 ~ projection_no_regions_closure[317d]::correct_region[0]) with substs [
                '_#1r,
                T,
            ]
@@ -75,7 +75,7 @@ note: External requirements
 LL |     with_signature(x, |mut y| Box::new(y.next()))
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:31 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:22 ~ projection_no_regions_closure[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -97,7 +97,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:27 ~ projection_no_regions_closure[317d]::wrong_region[0]) with substs [
+   = note: defining type: DefId(0:18 ~ projection_no_regions_closure[317d]::wrong_region[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -117,7 +117,7 @@ note: External requirements
 LL |     with_signature(x, |mut y| Box::new(y.next()))
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:36 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:27 ~ projection_no_regions_closure[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -139,7 +139,7 @@ LL | |     with_signature(x, |mut y| Box::new(y.next()))
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:32 ~ projection_no_regions_closure[317d]::outlives_region[0]) with substs [
+   = note: defining type: DefId(0:23 ~ projection_no_regions_closure[317d]::outlives_region[0]) with substs [
                '_#1r,
                '_#2r,
                T,
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
index 10b2bd1af47..c5c0e106c8a 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:28 ~ projection_one_region_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:19 ~ projection_one_region_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -27,7 +27,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:24 ~ projection_one_region_closure[317d]::no_relationships_late[0]) with substs [
+   = note: defining type: DefId(0:15 ~ projection_one_region_closure[317d]::no_relationships_late[0]) with substs [
                '_#1r,
                T,
            ]
@@ -38,7 +38,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:24 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(25), 'a))`...
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:15 ~ projection_one_region_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(16), 'a))`...
 
 error: lifetime may not live long enough
   --> $DIR/projection-one-region-closure.rs:45:39
@@ -57,7 +57,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:33 ~ projection_one_region_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:24 ~ projection_one_region_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -80,7 +80,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:29 ~ projection_one_region_closure[317d]::no_relationships_early[0]) with substs [
+   = note: defining type: DefId(0:20 ~ projection_one_region_closure[317d]::no_relationships_early[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -111,7 +111,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:38 ~ projection_one_region_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:29 ~ projection_one_region_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -133,7 +133,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:34 ~ projection_one_region_closure[317d]::projection_outlives[0]) with substs [
+   = note: defining type: DefId(0:25 ~ projection_one_region_closure[317d]::projection_outlives[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -145,7 +145,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:43 ~ projection_one_region_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:34 ~ projection_one_region_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -168,7 +168,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:39 ~ projection_one_region_closure[317d]::elements_outlive[0]) with substs [
+   = note: defining type: DefId(0:30 ~ projection_one_region_closure[317d]::elements_outlive[0]) with substs [
                '_#1r,
                '_#2r,
                T,
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
index b4b74bfc128..3fcf9731fc3 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:28 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:19 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -26,7 +26,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:24 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [
+   = note: defining type: DefId(0:15 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [
                '_#1r,
                T,
            ]
@@ -48,7 +48,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:33 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:24 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -70,7 +70,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:29 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [
+   = note: defining type: DefId(0:20 ~ projection_one_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -93,7 +93,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:38 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:29 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -115,7 +115,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:34 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [
+   = note: defining type: DefId(0:25 ~ projection_one_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -127,7 +127,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:43 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:34 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -149,7 +149,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:39 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]) with substs [
+   = note: defining type: DefId(0:30 ~ projection_one_region_trait_bound_closure[317d]::elements_outlive[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -161,7 +161,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:47 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:38 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -182,7 +182,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:44 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]) with substs [
+   = note: defining type: DefId(0:35 ~ projection_one_region_trait_bound_closure[317d]::one_region[0]) with substs [
                '_#1r,
                T,
            ]
diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
index a757a43499f..9cc2e504e10 100644
--- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr
@@ -4,7 +4,7 @@ note: No external requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:28 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:19 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -23,7 +23,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:24 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [
+   = note: defining type: DefId(0:15 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_late[0]) with substs [
                '_#1r,
                T,
            ]
@@ -34,7 +34,7 @@ note: No external requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:33 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:24 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -54,7 +54,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:29 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]) with substs [
+   = note: defining type: DefId(0:20 ~ projection_one_region_trait_bound_static_closure[317d]::no_relationships_early[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -66,7 +66,7 @@ note: No external requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:38 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:29 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -86,7 +86,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:34 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]) with substs [
+   = note: defining type: DefId(0:25 ~ projection_one_region_trait_bound_static_closure[317d]::projection_outlives[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -98,7 +98,7 @@ note: No external requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:43 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:34 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -118,7 +118,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:39 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]) with substs [
+   = note: defining type: DefId(0:30 ~ projection_one_region_trait_bound_static_closure[317d]::elements_outlive[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -130,7 +130,7 @@ note: No external requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:47 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:38 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -149,7 +149,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:44 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]) with substs [
+   = note: defining type: DefId(0:35 ~ projection_one_region_trait_bound_static_closure[317d]::one_region[0]) with substs [
                '_#1r,
                T,
            ]
diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
index a48766cd734..c4f65a29b8e 100644
--- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
+++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:31 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:22 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -27,7 +27,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:26 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [
+   = note: defining type: DefId(0:17 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -39,7 +39,7 @@ error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: ReFree(DefId(0:26 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(27), 'a))`...
+   = help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: ReFree(DefId(0:17 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(crate0:DefIndex(18), 'a))`...
 
 note: External requirements
   --> $DIR/projection-two-region-trait-bound-closure.rs:48:29
@@ -47,7 +47,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:37 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:28 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -70,7 +70,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:32 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [
+   = note: defining type: DefId(0:23 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_early[0]) with substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -91,7 +91,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:43 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:34 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -114,7 +114,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:38 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [
+   = note: defining type: DefId(0:29 ~ projection_two_region_trait_bound_closure[317d]::projection_outlives[0]) with substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -127,7 +127,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:49 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:40 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -150,7 +150,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:44 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]) with substs [
+   = note: defining type: DefId(0:35 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive1[0]) with substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -163,7 +163,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:55 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:46 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -186,7 +186,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:50 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]) with substs [
+   = note: defining type: DefId(0:41 ~ projection_two_region_trait_bound_closure[317d]::elements_outlive2[0]) with substs [
                '_#1r,
                '_#2r,
                '_#3r,
@@ -199,7 +199,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:60 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:51 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -221,7 +221,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:56 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]) with substs [
+   = note: defining type: DefId(0:47 ~ projection_two_region_trait_bound_closure[317d]::two_regions[0]) with substs [
                '_#1r,
                T,
            ]
@@ -243,7 +243,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:65 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:56 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -265,7 +265,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:61 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]) with substs [
+   = note: defining type: DefId(0:52 ~ projection_two_region_trait_bound_closure[317d]::two_regions_outlive[0]) with substs [
                '_#1r,
                '_#2r,
                T,
@@ -277,7 +277,7 @@ note: External requirements
 LL |     with_signature(cell, t, |cell, t| require(cell, t));
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:69 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:60 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -298,7 +298,7 @@ LL | |     with_signature(cell, t, |cell, t| require(cell, t));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:66 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]) with substs [
+   = note: defining type: DefId(0:57 ~ projection_two_region_trait_bound_closure[317d]::one_region[0]) with substs [
                '_#1r,
                T,
            ]
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 2ed94df1f34..fd8d8917c18 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |     twice(cell, value, |a, b| invoke(a, b));
    |                        ^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:20 ~ ty_param_closure_approximate_lower_bound[317d]::generic[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:11 ~ ty_param_closure_approximate_lower_bound[317d]::generic[0]::{{closure}}[0]) with closure substs [
                T,
                i16,
                for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) T)),
@@ -21,7 +21,7 @@ LL | |     twice(cell, value, |a, b| invoke(a, b));
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:18 ~ ty_param_closure_approximate_lower_bound[317d]::generic[0]) with substs [
+   = note: defining type: DefId(0:9 ~ ty_param_closure_approximate_lower_bound[317d]::generic[0]) with substs [
                T,
            ]
 
@@ -31,7 +31,7 @@ note: External requirements
 LL |     twice(cell, value, |a, b| invoke(a, b));
    |                        ^^^^^^^^^^^^^^^^^^^
    |
-   = note: defining type: DefId(0:24 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:15 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]::{{closure}}[0]) with closure substs [
                T,
                i16,
                for<'r, 's> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 'r)) ()>>, &ReLateBound(DebruijnIndex(0), BrNamed(crate0:DefIndex(0), 's)) T)),
@@ -49,7 +49,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:21 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]) with substs [
+   = note: defining type: DefId(0:12 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]) with substs [
                T,
            ]
 
@@ -59,7 +59,7 @@ error[E0309]: the parameter type `T` may not live long enough
 LL |     twice(cell, value, |a, b| invoke(a, b));
    |                        ^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:21 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(crate0:DefIndex(22), 'a))`...
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:12 ~ ty_param_closure_approximate_lower_bound[317d]::generic_fail[0]), BrNamed(crate0:DefIndex(13), 'a))`...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
index d689949969d..7c8dc94eda9 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr
@@ -4,7 +4,7 @@ note: External requirements
 LL |     with_signature(x, |y| y)
    |                       ^^^^^
    |
-   = note: defining type: DefId(0:20 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:11 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -25,7 +25,7 @@ LL | |
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:17 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]) with substs [
+   = note: defining type: DefId(0:8 ~ ty_param_closure_outlives_from_return_type[317d]::no_region[0]) with substs [
                '_#1r,
                T,
            ]
diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
index 11444c9f72b..97b84d1bdf8 100644
--- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
+++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr
@@ -11,7 +11,7 @@ LL | |         require(&x, &y)
 LL | |     })
    | |_____^
    |
-   = note: defining type: DefId(0:23 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:14 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]::{{closure}}[0]) with closure substs [
                T,
                i32,
                extern "rust-call" fn((std::cell::Cell<&'_#1r ()>, T)),
@@ -32,7 +32,7 @@ LL | |     })
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:20 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]) with substs [
+   = note: defining type: DefId(0:11 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]) with substs [
                T,
            ]
 
@@ -49,7 +49,7 @@ LL | |         require(&x, &y)
 LL | |     })
    | |_____^
    |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:20 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(crate0:DefIndex(21), 'a))`...
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:11 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(crate0:DefIndex(12), 'a))`...
 
 note: External requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26
@@ -64,7 +64,7 @@ LL | |         require(&x, &y)
 LL | |     })
    | |_____^
    |
-   = note: defining type: DefId(0:27 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:18 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -85,7 +85,7 @@ LL | |     })
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:24 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]) with substs [
+   = note: defining type: DefId(0:15 ~ ty_param_closure_outlives_from_where_clause[317d]::correct_region[0]) with substs [
                '_#1r,
                T,
            ]
@@ -101,7 +101,7 @@ LL | |         require(&x, &y)
 LL | |     })
    | |_____^
    |
-   = note: defining type: DefId(0:32 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:23 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                T,
                i32,
@@ -123,7 +123,7 @@ LL | |     })
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:28 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]) with substs [
+   = note: defining type: DefId(0:19 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]) with substs [
                '_#1r,
                T,
            ]
@@ -139,7 +139,7 @@ LL | |         require(&x, &y)
 LL | |     })
    | |_____^
    |
-   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:28 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(crate0:DefIndex(29), 'a))`...
+   = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:19 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(crate0:DefIndex(20), 'a))`...
 
 note: External requirements
   --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26
@@ -151,7 +151,7 @@ LL | |         require(&x, &y)
 LL | |     })
    | |_____^
    |
-   = note: defining type: DefId(0:37 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
+   = note: defining type: DefId(0:28 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]::{{closure}}[0]) with closure substs [
                '_#1r,
                '_#2r,
                T,
@@ -173,7 +173,7 @@ LL | |     })
 LL | | }
    | |_^
    |
-   = note: defining type: DefId(0:33 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]) with substs [
+   = note: defining type: DefId(0:24 ~ ty_param_closure_outlives_from_where_clause[317d]::outlives_region[0]) with substs [
                '_#1r,
                '_#2r,
                T,
diff --git a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
index 66b3110d2af..ff5b2244e48 100644
--- a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
+++ b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // This test is reduced from a scenario pnkfelix encountered while
 // bootstrapping the compiler.
diff --git a/src/test/ui/no-send-res-ports.rs b/src/test/ui/no-send-res-ports.rs
index 01fc29713a4..85d812dd619 100644
--- a/src/test/ui/no-send-res-ports.rs
+++ b/src/test/ui/no-send-res-ports.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::thread;
 use std::rc::Rc;
 
diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr
index dc186f7c85e..f23a3bf832a 100644
--- a/src/test/ui/no-send-res-ports.stderr
+++ b/src/test/ui/no-send-res-ports.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
-  --> $DIR/no-send-res-ports.rs:27:5
+  --> $DIR/no-send-res-ports.rs:26:5
    |
 LL |     thread::spawn(move|| {
    |     ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -9,10 +9,10 @@ LL |     thread::spawn(move|| {
 LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |                          ---- required by this bound in `std::thread::spawn`
    |
-   = help: within `[closure@$DIR/no-send-res-ports.rs:27:19: 31:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
+   = help: within `[closure@$DIR/no-send-res-ports.rs:26:19: 30:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `Port<()>`
    = note: required because it appears within the type `main::Foo`
-   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:27:19: 31:6 x:main::Foo]`
+   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:26:19: 30:6 x:main::Foo]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no-warn-on-field-replace-issue-34101.rs b/src/test/ui/no-warn-on-field-replace-issue-34101.rs
index eb701b9184e..15df6d25c5d 100644
--- a/src/test/ui/no-warn-on-field-replace-issue-34101.rs
+++ b/src/test/ui/no-warn-on-field-replace-issue-34101.rs
@@ -18,7 +18,7 @@
 
 
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Foo(String);
 
diff --git a/src/test/ui/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs
index 5357c3bff9a..f05436b8c04 100644
--- a/src/test/ui/on-unimplemented/bad-annotation.rs
+++ b/src/test/ui/on-unimplemented/bad-annotation.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 #![allow(unused)]
 
diff --git a/src/test/ui/on-unimplemented/expected-comma-found-token.rs b/src/test/ui/on-unimplemented/expected-comma-found-token.rs
index d8717f360e9..77c0ea17269 100644
--- a/src/test/ui/on-unimplemented/expected-comma-found-token.rs
+++ b/src/test/ui/on-unimplemented/expected-comma-found-token.rs
@@ -2,7 +2,7 @@
 // access to the variable, whether that mutable access be used
 // for direct assignment or for taking mutable ref. Issue #6801.
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 #[rustc_on_unimplemented(
     message="the message"
diff --git a/src/test/ui/on-unimplemented/expected-comma-found-token.stderr b/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
index 5bbdbe29416..738bf7c6c6b 100644
--- a/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
+++ b/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
@@ -2,7 +2,7 @@ error: expected one of `)` or `,`, found `label`
   --> $DIR/expected-comma-found-token.rs:9:5
    |
 LL |     message="the message"
-   |                          - expected one of `)` or `,` here
+   |                          - expected one of `)` or `,`
 LL |     label="the label"
    |     ^^^^^ unexpected token
 
diff --git a/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
new file mode 100644
index 00000000000..3cc50e3499a
--- /dev/null
+++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
@@ -0,0 +1,8 @@
+// Test that `#[rustc_on_unimplemented]` is gated by `rustc_attrs` feature gate.
+
+#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
+//~^ ERROR this is an internal attribute that will never be stable
+trait Foo<Bar>
+{}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr
index 6c230f8cada..ec1eaff52bd 100644
--- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr
+++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr
@@ -1,11 +1,11 @@
-error[E0658]: the `#[rustc_on_unimplemented]` attribute is an experimental feature
-  --> $DIR/feature-gate-on-unimplemented.rs:4:1
+error[E0658]: this is an internal attribute that will never be stable
+  --> $DIR/feature-gate-on-unimplemented.rs:3:1
    |
 LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29628
-   = help: add `#![feature(on_unimplemented)]` to the crate attributes to enable
+   = 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: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs
index 0aee98b2090..b74957ebcd4 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.rs
+++ b/src/test/ui/on-unimplemented/multiple-impls.rs
@@ -1,6 +1,6 @@
 // Test if the on_unimplemented message override works
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 
 struct Foo<T>(T);
diff --git a/src/test/ui/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs
index 9e4c2f6edd7..ab3e67d01fe 100644
--- a/src/test/ui/on-unimplemented/on-impl.rs
+++ b/src/test/ui/on-unimplemented/on-impl.rs
@@ -1,6 +1,6 @@
 // Test if the on_unimplemented message override works
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 
 #[rustc_on_unimplemented = "invalid"]
diff --git a/src/test/ui/on-unimplemented/on-trait.rs b/src/test/ui/on-unimplemented/on-trait.rs
index 109cb5ba969..556813cd479 100644
--- a/src/test/ui/on-unimplemented/on-trait.rs
+++ b/src/test/ui/on-unimplemented/on-trait.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 pub mod Bar {
   #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
index 5fe72caf9c1..73c1477c281 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
@@ -3,7 +3,7 @@
 
 // check-pass
 
-#![feature(or_patterns)]
+#![feature(or_patterns)] //~ WARNING the feature `or_patterns` is incomplete
 
 fn main() {}
 
diff --git a/src/test/ui/parser/assoc-oddities-1.stderr b/src/test/ui/parser/assoc-oddities-1.stderr
index 376ddf4d68b..acf71b4893a 100644
--- a/src/test/ui/parser/assoc-oddities-1.stderr
+++ b/src/test/ui/parser/assoc-oddities-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, or `}`, found `[`
   --> $DIR/assoc-oddities-1.rs:10:28
    |
 LL |     ..if c { a } else { b }[n];
-   |                            ^ expected one of `.`, `;`, `?`, or `}` here
+   |                            ^ expected one of `.`, `;`, `?`, or `}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/assoc-oddities-2.stderr b/src/test/ui/parser/assoc-oddities-2.stderr
index 4b3893d2c17..d3b90c34c29 100644
--- a/src/test/ui/parser/assoc-oddities-2.stderr
+++ b/src/test/ui/parser/assoc-oddities-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, or `}`, found `[`
   --> $DIR/assoc-oddities-2.rs:5:29
    |
 LL |     x..if c { a } else { b }[n];
-   |                             ^ expected one of `.`, `;`, `?`, or `}` here
+   |                             ^ expected one of `.`, `;`, `?`, or `}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
index 7d0bb0965b6..17bd5b54738 100644
--- a/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
+++ b/src/test/ui/parser/associated-types-project-from-hrtb-explicit.stderr
@@ -13,7 +13,7 @@ error: expected one of `::` or `>`, found `Foo`
   --> $DIR/associated-types-project-from-hrtb-explicit.rs:10:29
    |
 LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A)
-   |                             ^^^ expected one of `::` or `>` here
+   |                             ^^^ expected one of `::` or `>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/attr-bad-meta.stderr b/src/test/ui/parser/attr-bad-meta.stderr
index a452df5e90c..8d65c423c8d 100644
--- a/src/test/ui/parser/attr-bad-meta.stderr
+++ b/src/test/ui/parser/attr-bad-meta.stderr
@@ -2,7 +2,7 @@ error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `*`
   --> $DIR/attr-bad-meta.rs:1:7
    |
 LL | #[path*]
-   |       ^ expected one of `(`, `::`, `=`, `[`, `]`, or `{` here
+   |       ^ expected one of `(`, `::`, `=`, `[`, `]`, or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bad-lit-suffixes.rs b/src/test/ui/parser/bad-lit-suffixes.rs
index 9f301db0995..7db83674efc 100644
--- a/src/test/ui/parser/bad-lit-suffixes.rs
+++ b/src/test/ui/parser/bad-lit-suffixes.rs
@@ -1,9 +1,9 @@
 extern
-    "C"suffix //~ ERROR suffixes on an ABI spec are invalid
+    "C"suffix //~ ERROR suffixes on a string literal are invalid
     fn foo() {}
 
 extern
-    "C"suffix //~ ERROR suffixes on an ABI spec are invalid
+    "C"suffix //~ ERROR suffixes on a string literal are invalid
 {}
 
 fn main() {
diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr
index 208fcf43d91..6b0049298ff 100644
--- a/src/test/ui/parser/bad-lit-suffixes.stderr
+++ b/src/test/ui/parser/bad-lit-suffixes.stderr
@@ -1,10 +1,10 @@
-error: suffixes on an ABI spec are invalid
+error: suffixes on a string literal are invalid
   --> $DIR/bad-lit-suffixes.rs:2:5
    |
 LL |     "C"suffix
    |     ^^^^^^^^^ invalid suffix `suffix`
 
-error: suffixes on an ABI spec are invalid
+error: suffixes on a string literal are invalid
   --> $DIR/bad-lit-suffixes.rs:6:5
    |
 LL |     "C"suffix
diff --git a/src/test/ui/parser/bad-match.stderr b/src/test/ui/parser/bad-match.stderr
index d5baaf5e93b..13784c409cd 100644
--- a/src/test/ui/parser/bad-match.stderr
+++ b/src/test/ui/parser/bad-match.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `x`
   --> $DIR/bad-match.rs:2:13
    |
 LL |   let isize x = 5;
-   |             ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |             ^ expected one of `:`, `;`, `=`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bad-name.stderr b/src/test/ui/parser/bad-name.stderr
index dce4dabedf5..a36b67794fa 100644
--- a/src/test/ui/parser/bad-name.stderr
+++ b/src/test/ui/parser/bad-name.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
   --> $DIR/bad-name.rs:4:8
    |
 LL |   let x.y::<isize>.z foo;
-   |        ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |        ^ expected one of `:`, `;`, `=`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/better-expected.stderr b/src/test/ui/parser/better-expected.stderr
index d100d01e78f..21bf8d19a72 100644
--- a/src/test/ui/parser/better-expected.stderr
+++ b/src/test/ui/parser/better-expected.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `3`
   --> $DIR/better-expected.rs:2:19
    |
 LL |     let x: [isize 3];
-   |         -         ^ expected one of 7 possible tokens here
+   |         -         ^ expected one of 7 possible tokens
    |         |
    |         while parsing the type for `x`
 
diff --git a/src/test/ui/parser/bounds-lifetime-1.stderr b/src/test/ui/parser/bounds-lifetime-1.stderr
index 17d65314d96..000e84f635b 100644
--- a/src/test/ui/parser/bounds-lifetime-1.stderr
+++ b/src/test/ui/parser/bounds-lifetime-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `'b`
   --> $DIR/bounds-lifetime-1.rs:1:17
    |
 LL | type A = for<'a 'b> fn();
-   |                 ^^ expected one of `,`, `:`, or `>` here
+   |                 ^^ expected one of `,`, `:`, or `>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bounds-lifetime-2.stderr b/src/test/ui/parser/bounds-lifetime-2.stderr
index 587e527f0a8..dd3e69c1139 100644
--- a/src/test/ui/parser/bounds-lifetime-2.stderr
+++ b/src/test/ui/parser/bounds-lifetime-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `+`
   --> $DIR/bounds-lifetime-2.rs:1:17
    |
 LL | type A = for<'a + 'b> fn();
-   |                 ^ expected one of `,`, `:`, or `>` here
+   |                 ^ expected one of `,`, `:`, or `>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bounds-lifetime-where.stderr b/src/test/ui/parser/bounds-lifetime-where.stderr
index 9507a459858..05cebd6d351 100644
--- a/src/test/ui/parser/bounds-lifetime-where.stderr
+++ b/src/test/ui/parser/bounds-lifetime-where.stderr
@@ -2,7 +2,7 @@ error: expected one of `=`, lifetime, or type, found `,`
   --> $DIR/bounds-lifetime-where.rs:8:14
    |
 LL | type A where , = u8;
-   |              ^ expected one of `=`, lifetime, or type here
+   |              ^ expected one of `=`, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bounds-lifetime.stderr b/src/test/ui/parser/bounds-lifetime.stderr
index facbd280070..12b9b61ebd1 100644
--- a/src/test/ui/parser/bounds-lifetime.stderr
+++ b/src/test/ui/parser/bounds-lifetime.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
   --> $DIR/bounds-lifetime.rs:9:14
    |
 LL | type A = for<,> fn();
-   |              ^ expected one of `>`, `const`, identifier, or lifetime here
+   |              ^ expected one of `>`, `const`, identifier, or lifetime
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bounds-type-where.stderr b/src/test/ui/parser/bounds-type-where.stderr
index 459d5c3b6ea..5636ee75c97 100644
--- a/src/test/ui/parser/bounds-type-where.stderr
+++ b/src/test/ui/parser/bounds-type-where.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `::`, `:`, `<`, `==`, or `=`, found `,`
   --> $DIR/bounds-type-where.rs:8:15
    |
 LL | type A where T, = u8;
-   |               ^ expected one of 8 possible tokens here
+   |               ^ expected one of 8 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/class-implements-bad-trait.stderr b/src/test/ui/parser/class-implements-bad-trait.stderr
index 45583466adc..3a4dea95d5d 100644
--- a/src/test/ui/parser/class-implements-bad-trait.stderr
+++ b/src/test/ui/parser/class-implements-bad-trait.stderr
@@ -2,7 +2,7 @@ error: expected one of `!` or `::`, found `cat`
   --> $DIR/class-implements-bad-trait.rs:2:7
    |
 LL | class cat : nonexistent {
-   |       ^^^ expected one of `!` or `::` here
+   |       ^^^ expected one of `!` or `::`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/closure-return-syntax.stderr b/src/test/ui/parser/closure-return-syntax.stderr
index dd7ebffd506..bfb7f98c5f5 100644
--- a/src/test/ui/parser/closure-return-syntax.stderr
+++ b/src/test/ui/parser/closure-return-syntax.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, or `{`, found `22`
   --> $DIR/closure-return-syntax.rs:5:23
    |
 LL |     let x = || -> i32 22;
-   |                       ^^ expected one of `!`, `(`, `+`, `::`, `<`, or `{` here
+   |                       ^^ expected one of `!`, `(`, `+`, `::`, `<`, or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr
index 8843fd303ec..dde36cf8dde 100644
--- a/src/test/ui/parser/default.stderr
+++ b/src/test/ui/parser/default.stderr
@@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, fo
   --> $DIR/default.rs:22:13
    |
 LL |     default pub fn foo<T: Default>() -> T { T::default() }
-   |             ^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe` here
+   |             ^^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
 
 error[E0449]: unnecessary visibility qualifier
   --> $DIR/default.rs:16:5
diff --git a/src/test/ui/parser/duplicate-visibility.stderr b/src/test/ui/parser/duplicate-visibility.stderr
index 675adb88d20..313e88e812b 100644
--- a/src/test/ui/parser/duplicate-visibility.stderr
+++ b/src/test/ui/parser/duplicate-visibility.stderr
@@ -2,7 +2,7 @@ error: expected one of `(`, `fn`, `static`, or `type`, found keyword `pub`
   --> $DIR/duplicate-visibility.rs:3:9
    |
 LL |     pub pub fn foo();
-   |         ^^^ expected one of `(`, `fn`, `static`, or `type` here
+   |         ^^^ expected one of `(`, `fn`, `static`, or `type`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/empty-impl-semicolon.stderr b/src/test/ui/parser/empty-impl-semicolon.stderr
index 46f2393cd83..398eb5c898c 100644
--- a/src/test/ui/parser/empty-impl-semicolon.stderr
+++ b/src/test/ui/parser/empty-impl-semicolon.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `
   --> $DIR/empty-impl-semicolon.rs:1:9
    |
 LL | impl Foo;
-   |         ^ expected one of 8 possible tokens here
+   |         ^ expected one of 8 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
new file mode 100644
index 00000000000..cb23f2c808c
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+// In this test we check that the parser accepts an ABI string when it
+// comes from a macro `literal` fragment as opposed to a hardcoded string.
+
+fn main() {}
+
+macro_rules! abi_from_lit_frag {
+    ($abi:literal) => {
+        extern $abi {
+            fn _import();
+        }
+
+        extern $abi fn _export() {}
+
+        type _PTR = extern $abi fn();
+    }
+}
+
+mod rust {
+    abi_from_lit_frag!("Rust");
+}
+
+mod c {
+    abi_from_lit_frag!("C");
+}
diff --git a/src/test/ui/parser/extern-abi-raw-strings.rs b/src/test/ui/parser/extern-abi-raw-strings.rs
new file mode 100644
index 00000000000..fad855a21f6
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-raw-strings.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// Check that the string literal in `extern lit` will accept raw strings.
+
+fn main() {}
+
+extern r#"C"# fn foo() {}
+
+extern r#"C"# {
+    fn bar();
+}
+
+type T = extern r#"C"# fn();
diff --git a/src/test/ui/parser/extern-abi-string-escaping.rs b/src/test/ui/parser/extern-abi-string-escaping.rs
new file mode 100644
index 00000000000..87bd31aabb6
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-string-escaping.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// Check that the string literal in `extern lit` will escapes.
+
+fn main() {}
+
+extern "\x43" fn foo() {}
+
+extern "\x43" {
+    fn bar();
+}
+
+type T = extern "\x43" fn();
diff --git a/src/test/ui/parser/extern-abi-syntactic.rs b/src/test/ui/parser/extern-abi-syntactic.rs
new file mode 100644
index 00000000000..7d2bbfe8a01
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-syntactic.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// Check that from the grammar's point of view,
+// the specific set of ABIs is not part of it.
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn foo() {}
+
+#[cfg(FALSE)]
+extern "some_abi_that_we_are_sure_does_not_exist_semantically" {
+    fn foo();
+}
+
+#[cfg(FALSE)]
+type T = extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn();
diff --git a/src/test/ui/parser/extern-crate-unexpected-token.stderr b/src/test/ui/parser/extern-crate-unexpected-token.stderr
index 04edd46936a..0e745dc582f 100644
--- a/src/test/ui/parser/extern-crate-unexpected-token.stderr
+++ b/src/test/ui/parser/extern-crate-unexpected-token.stderr
@@ -2,7 +2,7 @@ error: expected one of `crate`, `fn`, or `{`, found `crte`
   --> $DIR/extern-crate-unexpected-token.rs:1:8
    |
 LL | extern crte foo;
-   |        ^^^^ expected one of `crate`, `fn`, or `{` here
+   |        ^^^^ expected one of `crate`, `fn`, or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/extern-expected-fn-or-brace.stderr b/src/test/ui/parser/extern-expected-fn-or-brace.stderr
index 691f4cddff2..0ebe9a0d3ea 100644
--- a/src/test/ui/parser/extern-expected-fn-or-brace.stderr
+++ b/src/test/ui/parser/extern-expected-fn-or-brace.stderr
@@ -2,7 +2,7 @@ error: expected one of `fn` or `{`, found keyword `mod`
   --> $DIR/extern-expected-fn-or-brace.rs:4:12
    |
 LL | extern "C" mod foo;
-   |            ^^^ expected one of `fn` or `{` here
+   |            ^^^ expected one of `fn` or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/extern-foreign-crate.stderr b/src/test/ui/parser/extern-foreign-crate.stderr
index de9f0c93232..eb75c0fc9c6 100644
--- a/src/test/ui/parser/extern-foreign-crate.stderr
+++ b/src/test/ui/parser/extern-foreign-crate.stderr
@@ -2,7 +2,7 @@ error: expected one of `;` or `as`, found `{`
   --> $DIR/extern-foreign-crate.rs:4:18
    |
 LL | extern crate foo {}
-   |                  ^ expected one of `;` or `as` here
+   |                  ^ expected one of `;` or `as`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr
index 2bda4460031..51e9087ffc1 100644
--- a/src/test/ui/parser/inverted-parameters.stderr
+++ b/src/test/ui/parser/inverted-parameters.stderr
@@ -4,7 +4,7 @@ error: expected one of `:`, `@`, or `|`, found `bar`
 LL |     fn foo(&self, &str bar) {}
    |                   -----^^^
    |                   |    |
-   |                   |    expected one of `:`, `@`, or `|` here
+   |                   |    expected one of `:`, `@`, or `|`
    |                   help: declare the type after the parameter binding: `<identifier>: <type>`
 
 error: expected one of `:`, `@`, or `|`, found `quux`
@@ -13,26 +13,26 @@ error: expected one of `:`, `@`, or `|`, found `quux`
 LL | fn baz(S quux, xyzzy: i32) {}
    |        --^^^^
    |        | |
-   |        | expected one of `:`, `@`, or `|` here
+   |        | expected one of `:`, `@`, or `|`
    |        help: declare the type after the parameter binding: `<identifier>: <type>`
 
 error: expected one of `:`, `@`, or `|`, found `a`
   --> $DIR/inverted-parameters.rs:15:12
    |
 LL | fn one(i32 a b) {}
-   |            ^ expected one of `:`, `@`, or `|` here
+   |            ^ expected one of `:`, `@`, or `|`
 
 error: expected one of `:` or `|`, found `(`
   --> $DIR/inverted-parameters.rs:18:23
    |
 LL | fn pattern((i32, i32) (a, b)) {}
-   |                       ^ expected one of `:` or `|` here
+   |                       ^ expected one of `:` or `|`
 
 error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/inverted-parameters.rs:21:12
    |
 LL | fn fizz(i32) {}
-   |            ^ expected one of `:`, `@`, or `|` here
+   |            ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -50,7 +50,7 @@ error: expected one of `:`, `@`, or `|`, found `S`
 LL | fn missing_colon(quux S) {}
    |                  -----^
    |                  |    |
-   |                  |    expected one of `:`, `@`, or `|` here
+   |                  |    expected one of `:`, `@`, or `|`
    |                  help: declare the type after the parameter binding: `<identifier>: <type>`
 
 error: aborting due to 6 previous errors
diff --git a/src/test/ui/parser/issue-15980.rs b/src/test/ui/parser/issue-15980.rs
index beb94c8042d..87faa7d5ff1 100644
--- a/src/test/ui/parser/issue-15980.rs
+++ b/src/test/ui/parser/issue-15980.rs
@@ -9,7 +9,7 @@ fn main(){
             //~^ ERROR expected identifier, found keyword `return`
             //~| NOTE expected identifier, found keyword
         }
-        //~^ NOTE expected one of `.`, `=>`, `?`, or an operator here
+        //~^ NOTE expected one of `.`, `=>`, `?`, or an operator
         _ => {}
         //~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_`
         //~| NOTE unexpected token
diff --git a/src/test/ui/parser/issue-15980.stderr b/src/test/ui/parser/issue-15980.stderr
index 26f75d45fa2..5cefead2c74 100644
--- a/src/test/ui/parser/issue-15980.stderr
+++ b/src/test/ui/parser/issue-15980.stderr
@@ -16,7 +16,7 @@ error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier
   --> $DIR/issue-15980.rs:13:9
    |
 LL |         }
-   |          - expected one of `.`, `=>`, `?`, or an operator here
+   |          - expected one of `.`, `=>`, `?`, or an operator
 LL |
 LL |         _ => {}
    |         ^ unexpected token
diff --git a/src/test/ui/parser/issue-17904.stderr b/src/test/ui/parser/issue-17904.stderr
index 38f30099ed5..a3cac676189 100644
--- a/src/test/ui/parser/issue-17904.stderr
+++ b/src/test/ui/parser/issue-17904.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `==`, or `=`, found `;`
   --> $DIR/issue-17904.rs:4:33
    |
 LL | struct Foo<T> where T: Copy, (T);
-   |                                 ^ expected one of `:`, `==`, or `=` here
+   |                                 ^ expected one of `:`, `==`, or `=`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-19096.stderr b/src/test/ui/parser/issue-19096.stderr
index 957b40dbd5e..4df7f878b9e 100644
--- a/src/test/ui/parser/issue-19096.stderr
+++ b/src/test/ui/parser/issue-19096.stderr
@@ -2,13 +2,13 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::`
   --> $DIR/issue-19096.rs:3:8
    |
 LL |     t.0::<isize>;
-   |        ^^ expected one of `.`, `;`, `?`, `}`, or an operator here
+   |        ^^ expected one of `.`, `;`, `?`, `}`, or an operator
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `::`
   --> $DIR/issue-19096.rs:8:8
    |
 LL |     t.0::<isize>;
-   |        ^^ expected one of `.`, `;`, `?`, `}`, or an operator here
+   |        ^^ expected one of `.`, `;`, `?`, `}`, or an operator
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/issue-20711-2.stderr b/src/test/ui/parser/issue-20711-2.stderr
index 56749c107d1..ee484890fad 100644
--- a/src/test/ui/parser/issue-20711-2.stderr
+++ b/src/test/ui/parser/issue-20711-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pu
   --> $DIR/issue-20711-2.rs:7:1
    |
 LL |     #[stable(feature = "rust1", since = "1.0.0")]
-   |                                                  - expected one of 9 possible tokens here
+   |                                                  - expected one of 9 possible tokens
 LL | }
    | ^ unexpected token
 
diff --git a/src/test/ui/parser/issue-20711.stderr b/src/test/ui/parser/issue-20711.stderr
index f7b99a91b51..152c9f1c689 100644
--- a/src/test/ui/parser/issue-20711.stderr
+++ b/src/test/ui/parser/issue-20711.stderr
@@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pu
   --> $DIR/issue-20711.rs:5:1
    |
 LL |     #[stable(feature = "rust1", since = "1.0.0")]
-   |                                                  - expected one of 9 possible tokens here
+   |                                                  - expected one of 9 possible tokens
 LL | }
    | ^ unexpected token
 
diff --git a/src/test/ui/parser/issue-22647.stderr b/src/test/ui/parser/issue-22647.stderr
index 4b1ef4f3dfc..89b454d1973 100644
--- a/src/test/ui/parser/issue-22647.stderr
+++ b/src/test/ui/parser/issue-22647.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
   --> $DIR/issue-22647.rs:2:15
    |
 LL |     let caller<F> = |f: F|
-   |               ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |               ^ expected one of `:`, `;`, `=`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-22712.stderr b/src/test/ui/parser/issue-22712.stderr
index d9e83144b36..30fabac6564 100644
--- a/src/test/ui/parser/issue-22712.stderr
+++ b/src/test/ui/parser/issue-22712.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
   --> $DIR/issue-22712.rs:6:12
    |
 LL |     let Foo<Vec<u8>>
-   |            ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-24197.stderr b/src/test/ui/parser/issue-24197.stderr
index 24818db622a..fd7015ccd39 100644
--- a/src/test/ui/parser/issue-24197.stderr
+++ b/src/test/ui/parser/issue-24197.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
   --> $DIR/issue-24197.rs:2:12
    |
 LL |     let buf[0] = 0;
-   |            ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-24375.stderr b/src/test/ui/parser/issue-24375.stderr
index e45b08be9ab..7aed88768a0 100644
--- a/src/test/ui/parser/issue-24375.stderr
+++ b/src/test/ui/parser/issue-24375.stderr
@@ -2,7 +2,7 @@ error: expected one of `=>`, `@`, `if`, or `|`, found `[`
   --> $DIR/issue-24375.rs:6:12
    |
 LL |         tmp[0] => {}
-   |            ^ expected one of `=>`, `@`, `if`, or `|` here
+   |            ^ expected one of `=>`, `@`, `if`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-24780.stderr b/src/test/ui/parser/issue-24780.stderr
index 469c034795e..d9470191b25 100644
--- a/src/test/ui/parser/issue-24780.stderr
+++ b/src/test/ui/parser/issue-24780.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `+`, `::`, `where`, or `{`, found `>`
   --> $DIR/issue-24780.rs:5:23
    |
 LL | fn foo() -> Vec<usize>> {
-   |                       ^ expected one of `!`, `+`, `::`, `where`, or `{` here
+   |                       ^ expected one of `!`, `+`, `::`, `where`, or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-32446.stderr b/src/test/ui/parser/issue-32446.stderr
index b0c18f4ec5a..ab37dd7c39d 100644
--- a/src/test/ui/parser/issue-32446.stderr
+++ b/src/test/ui/parser/issue-32446.stderr
@@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}
   --> $DIR/issue-32446.rs:4:11
    |
 LL | trait T { ... }
-   |           ^^^ expected one of 7 possible tokens here
+   |           ^^^ expected one of 7 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-33455.stderr b/src/test/ui/parser/issue-33455.stderr
index 4516c388afc..c535ef23b22 100644
--- a/src/test/ui/parser/issue-33455.stderr
+++ b/src/test/ui/parser/issue-33455.stderr
@@ -2,7 +2,7 @@ error: expected one of `::`, `;`, or `as`, found `.`
   --> $DIR/issue-33455.rs:1:8
    |
 LL | use foo.bar;
-   |        ^ expected one of `::`, `;`, or `as` here
+   |        ^ expected one of `::`, `;`, or `as`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-41155.stderr b/src/test/ui/parser/issue-41155.stderr
index 624d1a3d11e..0e191eb7e0a 100644
--- a/src/test/ui/parser/issue-41155.stderr
+++ b/src/test/ui/parser/issue-41155.stderr
@@ -2,7 +2,7 @@ error: expected one of `(`, `async`, `const`, `default`, `extern`, `fn`, `type`,
   --> $DIR/issue-41155.rs:5:1
    |
 LL |     pub
-   |        - expected one of 8 possible tokens here
+   |        - expected one of 8 possible tokens
 LL | }
    | ^ unexpected token
 
diff --git a/src/test/ui/parser/issue-62660.stderr b/src/test/ui/parser/issue-62660.stderr
index 3a8f6797b82..0844da1bd92 100644
--- a/src/test/ui/parser/issue-62660.stderr
+++ b/src/test/ui/parser/issue-62660.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)`
   --> $DIR/issue-62660.rs:7:38
    |
 LL |     pub fn foo(_: i32, self: Box<Self) {}
-   |                                      ^ expected one of 7 possible tokens here
+   |                                      ^ expected one of 7 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-62973.stderr b/src/test/ui/parser/issue-62973.stderr
index 82122ef0b6f..e2a5b4cba06 100644
--- a/src/test/ui/parser/issue-62973.stderr
+++ b/src/test/ui/parser/issue-62973.stderr
@@ -13,7 +13,7 @@ error: expected one of `,` or `}`, found `{`
   --> $DIR/issue-62973.rs:6:25
    |
 LL | fn p() { match s { v, E { [) {) }
-   |        -       -       -^ expected one of `,` or `}` here
+   |        -       -       -^ expected one of `,` or `}`
    |        |       |       |
    |        |       |       help: `}` may belong here
    |        |       while parsing this struct
@@ -36,13 +36,13 @@ LL | )
    |
 
 error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/issue-62973.rs:8:1
+  --> $DIR/issue-62973.rs:8:2
    |
 LL | fn p() { match s { v, E { [) {) }
    |          ----- while parsing this match expression
 LL | 
 LL | 
-   | ^ expected one of `.`, `?`, `{`, or an operator here
+   |  ^ expected one of `.`, `?`, `{`, or an operator
 
 error: incorrect close delimiter: `)`
   --> $DIR/issue-62973.rs:6:28
diff --git a/src/test/ui/parser/issue-63135.stderr b/src/test/ui/parser/issue-63135.stderr
index a077ad454a9..152601b3538 100644
--- a/src/test/ui/parser/issue-63135.stderr
+++ b/src/test/ui/parser/issue-63135.stderr
@@ -23,16 +23,16 @@ LL | fn i(n{...,f #
    |        `..` must be at the end and cannot have a trailing comma
 
 error: expected `[`, found `}`
-  --> $DIR/issue-63135.rs:3:15
+  --> $DIR/issue-63135.rs:3:16
    |
 LL | fn i(n{...,f #
-   |               ^ expected `[`
+   |                ^ expected `[`
 
 error: expected one of `:` or `|`, found `)`
-  --> $DIR/issue-63135.rs:3:15
+  --> $DIR/issue-63135.rs:3:16
    |
 LL | fn i(n{...,f #
-   |               ^ expected one of `:` or `|` here
+   |                ^ expected one of `:` or `|`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs b/src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs
new file mode 100644
index 00000000000..9d68a7bffde
--- /dev/null
+++ b/src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+// Test that failing macro matchers will not cause pre-expansion errors
+// even though they use a feature that is pre-expansion gated.
+
+macro_rules! m {
+    ($e:expr) => { 0 }; // This fails on the input below due to `, foo`.
+    ($e:expr,) => { 1 }; // This also fails to match due to `foo`.
+    (box $e:expr, foo) => { 2 }; // Successful matcher, we should get `2`.
+}
+
+fn main() {
+    assert_eq!(2, m!(box 42, foo));
+}
diff --git a/src/test/ui/parser/lifetime-semicolon.stderr b/src/test/ui/parser/lifetime-semicolon.stderr
index 71ed8200e9a..4641c286cb8 100644
--- a/src/test/ui/parser/lifetime-semicolon.stderr
+++ b/src/test/ui/parser/lifetime-semicolon.stderr
@@ -2,7 +2,7 @@ error: expected one of `,` or `>`, found `;`
   --> $DIR/lifetime-semicolon.rs:5:30
    |
 LL | fn foo<'a, 'b>(x: &mut Foo<'a; 'b>) {}
-   |                              ^ expected one of `,` or `>` here
+   |                              ^ expected one of `,` or `>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/macro/issue-37234.stderr b/src/test/ui/parser/macro/issue-37234.stderr
index 004de9d905f..8cef5ae3758 100644
--- a/src/test/ui/parser/macro/issue-37234.stderr
+++ b/src/test/ui/parser/macro/issue-37234.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, or an operator, found `""`
   --> $DIR/issue-37234.rs:3:19
    |
 LL |         let x = 5 "";
-   |                   ^^ expected one of `.`, `;`, `?`, or an operator here
+   |                   ^^ expected one of `.`, `;`, `?`, or an operator
 ...
 LL |     failed!();
    |     ---------- in this macro invocation
diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.stderr b/src/test/ui/parser/macro/macro-doc-comments-2.stderr
index 6abe95192be..023d1a3e039 100644
--- a/src/test/ui/parser/macro/macro-doc-comments-2.stderr
+++ b/src/test/ui/parser/macro/macro-doc-comments-2.stderr
@@ -5,7 +5,7 @@ LL | macro_rules! inner {
    | ------------------ when calling this macro
 ...
 LL |     /// Outer
-   |     ^ no rules expected this token in macro call
+   |     ^^^^^^^^^ no rules expected this token in macro call
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.stderr b/src/test/ui/parser/macro/macro-incomplete-parse.stderr
index e40919cda94..46cccba74c0 100644
--- a/src/test/ui/parser/macro/macro-incomplete-parse.stderr
+++ b/src/test/ui/parser/macro/macro-incomplete-parse.stderr
@@ -13,7 +13,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
   --> $DIR/macro-incomplete-parse.rs:10:14
    |
 LL |     () => ( 1,
-   |              ^ expected one of `.`, `;`, `?`, `}`, or an operator here
+   |              ^ expected one of `.`, `;`, `?`, `}`, or an operator
 ...
 LL |     ignored_expr!();
    |     ---------------- in this macro invocation
diff --git a/src/test/ui/parser/macro/trait-non-item-macros.stderr b/src/test/ui/parser/macro/trait-non-item-macros.stderr
index a953e23a710..dd97a3afa99 100644
--- a/src/test/ui/parser/macro/trait-non-item-macros.stderr
+++ b/src/test/ui/parser/macro/trait-non-item-macros.stderr
@@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, fo
   --> $DIR/trait-non-item-macros.rs:2:19
    |
 LL |     ($a:expr) => ($a)
-   |                   ^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe` here
+   |                   ^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`
 ...
 LL |     bah!(2);
    |     -------- in this macro invocation
diff --git a/src/test/ui/parser/macros-no-semicolon.stderr b/src/test/ui/parser/macros-no-semicolon.stderr
index 09925eae51d..9492191b8df 100644
--- a/src/test/ui/parser/macros-no-semicolon.stderr
+++ b/src/test/ui/parser/macros-no-semicolon.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `assert_eq`
   --> $DIR/macros-no-semicolon.rs:3:5
    |
 LL |     assert_eq!(1, 2)
-   |                     - expected one of `.`, `;`, `?`, `}`, or an operator here
+   |                     - expected one of `.`, `;`, `?`, `}`, or an operator
 LL |     assert_eq!(3, 4)
    |     ^^^^^^^^^ unexpected token
 
diff --git a/src/test/ui/parser/match-refactor-to-expr.rs b/src/test/ui/parser/match-refactor-to-expr.rs
index 09ebb2e1d83..e10ebf2e2d6 100644
--- a/src/test/ui/parser/match-refactor-to-expr.rs
+++ b/src/test/ui/parser/match-refactor-to-expr.rs
@@ -2,7 +2,7 @@ fn main() {
     let foo =
         match //~ NOTE while parsing this match expression
         Some(4).unwrap_or_else(5)
-        //~^ NOTE expected one of `.`, `?`, `{`, or an operator here
+        //~^ NOTE expected one of `.`, `?`, `{`, or an operator
         ; //~ NOTE unexpected token
         //~^ ERROR expected one of `.`, `?`, `{`, or an operator, found `;`
 
diff --git a/src/test/ui/parser/match-refactor-to-expr.stderr b/src/test/ui/parser/match-refactor-to-expr.stderr
index bf20bc93500..5cbf0232bc3 100644
--- a/src/test/ui/parser/match-refactor-to-expr.stderr
+++ b/src/test/ui/parser/match-refactor-to-expr.stderr
@@ -7,7 +7,7 @@ LL |         match
    |         while parsing this match expression
    |         help: try removing this `match`
 LL |         Some(4).unwrap_or_else(5)
-   |                                  - expected one of `.`, `?`, `{`, or an operator here
+   |                                  - expected one of `.`, `?`, `{`, or an operator
 LL |
 LL |         ;
    |         ^ unexpected token
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
index 9bf54181a07..e1aed8a6b4e 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-impl-trait.stderr
@@ -16,7 +16,7 @@ LL |
 LL | fn foo(&self) {}
    |                 -
    |                 |
-   |                 expected one of 10 possible tokens here
+   |                 expected one of 10 possible tokens
    |                 help: `}` may belong here
 LL | 
 LL | trait T {
diff --git a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
index 4bfb4c1cb3a..1bd8e445fad 100644
--- a/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
+++ b/src/test/ui/parser/mismatched-braces/missing-close-brace-in-trait.stderr
@@ -15,7 +15,7 @@ LL | trait T {
 LL |     fn foo(&self);
    |                   -
    |                   |
-   |                   expected one of 7 possible tokens here
+   |                   expected one of 7 possible tokens
    |                   help: `}` may belong here
 LL | 
 LL | pub(crate) struct Bar<T>();
diff --git a/src/test/ui/parser/missing_right_paren.rs b/src/test/ui/parser/missing_right_paren.rs
new file mode 100644
index 00000000000..4f7c5eea1d1
--- /dev/null
+++ b/src/test/ui/parser/missing_right_paren.rs
@@ -0,0 +1,3 @@
+// ignore-tidy-trailing-newlines
+// error-pattern: aborting due to 2 previous errors
+fn main((ؼ
\ No newline at end of file
diff --git a/src/test/ui/parser/missing_right_paren.stderr b/src/test/ui/parser/missing_right_paren.stderr
new file mode 100644
index 00000000000..ac16ebe6412
--- /dev/null
+++ b/src/test/ui/parser/missing_right_paren.stderr
@@ -0,0 +1,17 @@
+error: this file contains an un-closed delimiter
+  --> $DIR/missing_right_paren.rs:3:11
+   |
+LL | fn main((ؼ
+   |        -- ^
+   |        ||
+   |        |un-closed delimiter
+   |        un-closed delimiter
+
+error: expected one of `:` or `|`, found `)`
+  --> $DIR/missing_right_paren.rs:3:11
+   |
+LL | fn main((ؼ
+   |           ^ expected one of `:` or `|`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/multitrait.stderr b/src/test/ui/parser/multitrait.stderr
index 61dbc823848..5a8bb2f7a45 100644
--- a/src/test/ui/parser/multitrait.stderr
+++ b/src/test/ui/parser/multitrait.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `::`, `<`, `for`, `where`, or `{`, found `
   --> $DIR/multitrait.rs:5:9
    |
 LL | impl Cmp, ToString for S {
-   |         ^ expected one of 8 possible tokens here
+   |         ^ expected one of 8 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/not-a-pred.stderr b/src/test/ui/parser/not-a-pred.stderr
index 46d6038e802..90246b92bf0 100644
--- a/src/test/ui/parser/not-a-pred.stderr
+++ b/src/test/ui/parser/not-a-pred.stderr
@@ -2,7 +2,7 @@ error: expected one of `->`, `where`, or `{`, found `:`
   --> $DIR/not-a-pred.rs:3:26
    |
 LL | fn f(a: isize, b: isize) : lt(a, b) { }
-   |                          ^ expected one of `->`, `where`, or `{` here
+   |                          ^ expected one of `->`, `where`, or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.stderr b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
index 7feb15592c5..c7c76a7f1d4 100644
--- a/src/test/ui/parser/omitted-arg-in-item-fn.stderr
+++ b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/omitted-arg-in-item-fn.rs:1:9
    |
 LL | fn foo(x) {
-   |         ^ expected one of `:`, `@`, or `|` here
+   |         ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
diff --git a/src/test/ui/parser/pat-lt-bracket-1.stderr b/src/test/ui/parser/pat-lt-bracket-1.stderr
index 1bf27161513..e8ccbad668a 100644
--- a/src/test/ui/parser/pat-lt-bracket-1.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
   --> $DIR/pat-lt-bracket-1.rs:3:7
    |
 LL |     x < 7 => (),
-   |       ^ expected one of `=>`, `@`, `if`, or `|` here
+   |       ^ expected one of `=>`, `@`, `if`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr
index 2191e31ad1f..e51dd57f9c7 100644
--- a/src/test/ui/parser/pat-lt-bracket-2.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `<`
   --> $DIR/pat-lt-bracket-2.rs:1:7
    |
 LL | fn a(B<) {}
-   |       ^ expected one of `:`, `@`, or `|` here
+   |       ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a type, explicitly ignore the parameter name
diff --git a/src/test/ui/parser/pat-lt-bracket-3.stderr b/src/test/ui/parser/pat-lt-bracket-3.stderr
index 536d14e1b65..bacf868e3c4 100644
--- a/src/test/ui/parser/pat-lt-bracket-3.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-3.stderr
@@ -2,7 +2,7 @@ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
   --> $DIR/pat-lt-bracket-3.rs:6:16
    |
 LL |             Foo<T>(x, y) => {
-   |                ^ expected one of `=>`, `@`, `if`, or `|` here
+   |                ^ expected one of `=>`, `@`, `if`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-lt-bracket-4.stderr b/src/test/ui/parser/pat-lt-bracket-4.stderr
index d14702acee6..911c276b931 100644
--- a/src/test/ui/parser/pat-lt-bracket-4.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-4.stderr
@@ -2,7 +2,7 @@ error: expected one of `=>`, `@`, `if`, or `|`, found `<`
   --> $DIR/pat-lt-bracket-4.rs:8:12
    |
 LL |         Foo<T>::A(value) => value,
-   |            ^ expected one of `=>`, `@`, `if`, or `|` here
+   |            ^ expected one of `=>`, `@`, `if`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-lt-bracket-5.stderr b/src/test/ui/parser/pat-lt-bracket-5.stderr
index 167314dde06..e23674bcec5 100644
--- a/src/test/ui/parser/pat-lt-bracket-5.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-5.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-5.rs:2:10
    |
 LL |     let v[0] = v[1];
-   |          ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |          ^ expected one of `:`, `;`, `=`, `@`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
index 6f08f0a9d95..234e0c37723 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -2,7 +2,7 @@ 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 `|`
 
 error[E0658]: subslice patterns are unstable
   --> $DIR/pat-lt-bracket-6.rs:5:20
diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr
index 196f1c0ae91..86693ac27bd 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-7.stderr
@@ -2,7 +2,7 @@ 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 `|`
 
 error[E0308]: mismatched types
   --> $DIR/pat-lt-bracket-7.rs:9:30
diff --git a/src/test/ui/parser/pat-ranges-1.stderr b/src/test/ui/parser/pat-ranges-1.stderr
index 4e2c5d28381..b64a3ce5c08 100644
--- a/src/test/ui/parser/pat-ranges-1.stderr
+++ b/src/test/ui/parser/pat-ranges-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, or `|`, found `..=`
   --> $DIR/pat-ranges-1.rs:4:21
    |
 LL |     let macropus!() ..= 11 = 12;
-   |                     ^^^ expected one of `:`, `;`, `=`, or `|` here
+   |                     ^^^ expected one of `:`, `;`, `=`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-2.stderr b/src/test/ui/parser/pat-ranges-2.stderr
index 64df56f5a61..1a9e33bebe9 100644
--- a/src/test/ui/parser/pat-ranges-2.stderr
+++ b/src/test/ui/parser/pat-ranges-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!`
   --> $DIR/pat-ranges-2.rs:4:26
    |
 LL |     let 10 ..= makropulos!() = 12;
-   |                          ^ expected one of `::`, `:`, `;`, `=`, or `|` here
+   |                          ^ expected one of `::`, `:`, `;`, `=`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-3.stderr b/src/test/ui/parser/pat-ranges-3.stderr
index c32c18d98dc..c9787b789a8 100644
--- a/src/test/ui/parser/pat-ranges-3.stderr
+++ b/src/test/ui/parser/pat-ranges-3.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `;`, `=`, or `|`, found `+`
   --> $DIR/pat-ranges-3.rs:4:19
    |
 LL |     let 10 ..= 10 + 3 = 12;
-   |                   ^ expected one of `:`, `;`, `=`, or `|` here
+   |                   ^ expected one of `:`, `;`, `=`, or `|`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-4.stderr b/src/test/ui/parser/pat-ranges-4.stderr
index 53e38bc670b..69084b5a414 100644
--- a/src/test/ui/parser/pat-ranges-4.stderr
+++ b/src/test/ui/parser/pat-ranges-4.stderr
@@ -2,7 +2,7 @@ error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
   --> $DIR/pat-ranges-4.rs:4:12
    |
 LL |     let 10 - 3 ..= 10 = 8;
-   |            ^ expected one of 7 possible tokens here
+   |            ^ expected one of 7 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/range-3.stderr b/src/test/ui/parser/range-3.stderr
index 92c33487ee4..f866ea59983 100644
--- a/src/test/ui/parser/range-3.stderr
+++ b/src/test/ui/parser/range-3.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, or an operator, found `..`
   --> $DIR/range-3.rs:4:17
    |
 LL |     let r = 1..2..3;
-   |                 ^^ expected one of `.`, `;`, `?`, or an operator here
+   |                 ^^ expected one of `.`, `;`, `?`, or an operator
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/range-4.stderr b/src/test/ui/parser/range-4.stderr
index 90ec46165e7..dcb85170c1d 100644
--- a/src/test/ui/parser/range-4.stderr
+++ b/src/test/ui/parser/range-4.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, or an operator, found `..`
   --> $DIR/range-4.rs:4:16
    |
 LL |     let r = ..1..2;
-   |                ^^ expected one of `.`, `;`, `?`, or an operator here
+   |                ^^ expected one of `.`, `;`, `?`, or an operator
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/raw-str-unbalanced.stderr b/src/test/ui/parser/raw-str-unbalanced.stderr
index 26910ff64f5..ddb75722bef 100644
--- a/src/test/ui/parser/raw-str-unbalanced.stderr
+++ b/src/test/ui/parser/raw-str-unbalanced.stderr
@@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, or an operator, found `#`
   --> $DIR/raw-str-unbalanced.rs:3:9
    |
 LL |       "##
-   |         ^ expected one of `.`, `;`, `?`, or an operator here
+   |         ^ expected one of `.`, `;`, `?`, or an operator
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/raw/raw-literal-keywords.stderr b/src/test/ui/parser/raw/raw-literal-keywords.stderr
index 4cea605be6f..fd8eda3770d 100644
--- a/src/test/ui/parser/raw/raw-literal-keywords.stderr
+++ b/src/test/ui/parser/raw/raw-literal-keywords.stderr
@@ -2,19 +2,19 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found
   --> $DIR/raw-literal-keywords.rs:2:10
    |
 LL |     r#if true { }
-   |          ^^^^ expected one of 8 possible tokens here
+   |          ^^^^ expected one of 8 possible tokens
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
   --> $DIR/raw-literal-keywords.rs:6:14
    |
 LL |     r#struct Test;
-   |              ^^^^ expected one of 8 possible tokens here
+   |              ^^^^ expected one of 8 possible tokens
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test`
   --> $DIR/raw-literal-keywords.rs:10:13
    |
 LL |     r#union Test;
-   |             ^^^^ expected one of 8 possible tokens here
+   |             ^^^^ expected one of 8 possible tokens
 
 error[E0425]: cannot find value `if` in this scope
   --> $DIR/raw-literal-keywords.rs:14:13
diff --git a/src/test/ui/parser/recover-enum2.stderr b/src/test/ui/parser/recover-enum2.stderr
index 2311887a6fb..ee29f06638f 100644
--- a/src/test/ui/parser/recover-enum2.stderr
+++ b/src/test/ui/parser/recover-enum2.stderr
@@ -8,7 +8,7 @@ error: expected one of `!`, `(`, `)`, `+`, `,`, `::`, or `<`, found `{`
   --> $DIR/recover-enum2.rs:25:22
    |
 LL |             Nope(i32 {})
-   |                      ^ expected one of 7 possible tokens here
+   |                      ^ expected one of 7 possible tokens
 
 error: aborting due to 2 previous errors
 
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 1a1f395ee21..ccabfbded8b 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
@@ -2,7 +2,7 @@ error: expected one of `)`, `,`, `@`, or `|`, found keyword `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 `|`
 
 error: unexpected closing `)`
   --> $DIR/recover-for-loop-parens-around-head.rs:10:23
diff --git a/src/test/ui/parser/removed-syntax-closure-lifetime.stderr b/src/test/ui/parser/removed-syntax-closure-lifetime.stderr
index f52988cdb20..a100f689fb8 100644
--- a/src/test/ui/parser/removed-syntax-closure-lifetime.stderr
+++ b/src/test/ui/parser/removed-syntax-closure-lifetime.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `/`
   --> $DIR/removed-syntax-closure-lifetime.rs:1:22
    |
 LL | type closure = Box<lt/fn()>;
-   |                      ^ expected one of 7 possible tokens here
+   |                      ^ expected one of 7 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-enum-newtype.stderr b/src/test/ui/parser/removed-syntax-enum-newtype.stderr
index a6d0ff4eaf2..2daa6249b4c 100644
--- a/src/test/ui/parser/removed-syntax-enum-newtype.stderr
+++ b/src/test/ui/parser/removed-syntax-enum-newtype.stderr
@@ -2,7 +2,7 @@ error: expected one of `<`, `where`, or `{`, found `=`
   --> $DIR/removed-syntax-enum-newtype.rs:1:8
    |
 LL | enum e = isize;
-   |        ^ expected one of `<`, `where`, or `{` here
+   |        ^ expected one of `<`, `where`, or `{`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-fixed-vec.stderr b/src/test/ui/parser/removed-syntax-fixed-vec.stderr
index ca6969d1e87..a2b97544f9e 100644
--- a/src/test/ui/parser/removed-syntax-fixed-vec.stderr
+++ b/src/test/ui/parser/removed-syntax-fixed-vec.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `*`
   --> $DIR/removed-syntax-fixed-vec.rs:1:17
    |
 LL | type v = [isize * 3];
-   |                 ^ expected one of 7 possible tokens here
+   |                 ^ expected one of 7 possible tokens
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr b/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr
index 7beef9883bd..5b388ff4ce0 100644
--- a/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr
+++ b/src/test/ui/parser/removed-syntax-ptr-lifetime.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `(`, `::`, `;`, or `<`, found `/`
   --> $DIR/removed-syntax-ptr-lifetime.rs:1:22
    |
 LL | type bptr = &lifetime/isize;
-   |                      ^ expected one of `!`, `(`, `::`, `;`, or `<` here
+   |                      ^ expected one of `!`, `(`, `::`, `;`, or `<`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-static-fn.stderr b/src/test/ui/parser/removed-syntax-static-fn.stderr
index af148e69711..dfadefee23c 100644
--- a/src/test/ui/parser/removed-syntax-static-fn.stderr
+++ b/src/test/ui/parser/removed-syntax-static-fn.stderr
@@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pu
   --> $DIR/removed-syntax-static-fn.rs:4:5
    |
 LL | impl S {
-   |         - expected one of 10 possible tokens here
+   |         - expected one of 10 possible tokens
 LL |     static fn f() {}
    |     ^^^^^^ unexpected token
 
diff --git a/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr
index 9c47e3db67d..0703caf5bed 100644
--- a/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr
+++ b/src/test/ui/parser/removed-syntax-uniq-mut-ty.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, const, lifetime, or type, found keyword `mut`
   --> $DIR/removed-syntax-uniq-mut-ty.rs:1:20
    |
 LL | type mut_box = Box<mut isize>;
-   |                    ^^^ expected one of `>`, const, lifetime, or type here
+   |                    ^^^ expected one of `>`, const, lifetime, or type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-with-1.stderr b/src/test/ui/parser/removed-syntax-with-1.stderr
index a157873916a..193138d7460 100644
--- a/src/test/ui/parser/removed-syntax-with-1.stderr
+++ b/src/test/ui/parser/removed-syntax-with-1.stderr
@@ -2,7 +2,7 @@ error: expected one of `,`, `.`, `?`, `}`, or an operator, found `with`
   --> $DIR/removed-syntax-with-1.rs:8:25
    |
 LL |     let b = S { foo: () with a, bar: () };
-   |             -           ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator here
+   |             -           ^^^^ expected one of `,`, `.`, `?`, `}`, or an operator
    |             |
    |             while parsing this struct
 
diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr
index 7717b49d3a2..024c97cc9c1 100644
--- a/src/test/ui/parser/removed-syntax-with-2.stderr
+++ b/src/test/ui/parser/removed-syntax-with-2.stderr
@@ -2,7 +2,7 @@ error: expected one of `,` or `}`, found `a`
   --> $DIR/removed-syntax-with-2.rs:8:31
    |
 LL |     let b = S { foo: (), with a };
-   |             -                 ^ expected one of `,` or `}` here
+   |             -                 ^ expected one of `,` or `}`
    |             |
    |             while parsing this struct
 
diff --git a/src/test/ui/parser/underscore_item_not_const.stderr b/src/test/ui/parser/underscore_item_not_const.stderr
index 8814aa35271..ebf1ff9ff1e 100644
--- a/src/test/ui/parser/underscore_item_not_const.stderr
+++ b/src/test/ui/parser/underscore_item_not_const.stderr
@@ -86,7 +86,7 @@ error: expected one of `!` or `::`, found reserved identifier `_`
   --> $DIR/underscore_item_not_const.rs:28:7
    |
 LL | union _ { f: u8 }
-   |       ^ expected one of `!` or `::` here
+   |       ^ expected one of `!` or `::`
 
 error: aborting due to 15 previous errors
 
diff --git a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
index c73e17d2fc9..7a461cf630c 100644
--- a/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
+++ b/src/test/ui/parser/use-as-where-use-ends-with-mod-sep.stderr
@@ -13,7 +13,7 @@ error: expected one of `::`, `;`, or `as`, found `foo`
   --> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:19
    |
 LL | use std::any:: as foo;
-   |                   ^^^ expected one of `::`, `;`, or `as` here
+   |                   ^^^ expected one of `::`, `;`, or `as`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/path-lookahead.rs b/src/test/ui/path-lookahead.rs
index fd7509a623e..86bcb08de40 100644
--- a/src/test/ui/path-lookahead.rs
+++ b/src/test/ui/path-lookahead.rs
@@ -1,14 +1,14 @@
 // run-pass
-
-#![warn(unused)]
+#![allow(dead_code)]
+#![warn(unused_parens)]
 
 // Parser test for #37765
 
-fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`
+fn with_parens<T: ToString>(arg: T) -> String {
   return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
 }
 
-fn no_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `no_parens`
+fn no_parens<T: ToString>(arg: T) -> String {
   return <T as ToString>::to_string(&arg);
 }
 
diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr
index 197848e428a..caf9e8303ea 100644
--- a/src/test/ui/path-lookahead.stderr
+++ b/src/test/ui/path-lookahead.stderr
@@ -7,26 +7,6 @@ LL |   return (<T as ToString>::to_string(&arg));
 note: lint level defined here
   --> $DIR/path-lookahead.rs:3:9
    |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(unused_parens)]` implied by `#[warn(unused)]`
-
-warning: function is never used: `with_parens`
-  --> $DIR/path-lookahead.rs:7:1
-   |
-LL | fn with_parens<T: ToString>(arg: T) -> String {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/path-lookahead.rs:3:9
-   |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
-
-warning: function is never used: `no_parens`
-  --> $DIR/path-lookahead.rs:11:1
-   |
-LL | fn no_parens<T: ToString>(arg: T) -> String {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(unused_parens)]
+   |         ^^^^^^^^^^^^^
 
diff --git a/src/test/ui/pathless-extern-ok.rs b/src/test/ui/pathless-extern-ok.rs
new file mode 100644
index 00000000000..0ffa5eb8940
--- /dev/null
+++ b/src/test/ui/pathless-extern-ok.rs
@@ -0,0 +1,9 @@
+// edition:2018
+// compile-flags:--extern alloc
+// build-pass
+
+// Test that `--extern alloc` will load from the sysroot without error.
+
+fn main() {
+    let _: Vec<i32> = alloc::vec::Vec::new();
+}
diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
index d53e2e25b3d..6e52072e3bf 100644
--- a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr
@@ -6,11 +6,11 @@ LL |     match buf {
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 3 more not covered
+error[E0004]: non-exhaustive patterns: `&[..]` not covered
   --> $DIR/match-byte-array-patterns-2.rs:10:11
    |
 LL |     match buf {
-   |           ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 3 more not covered
+   |           ^^^ pattern `&[..]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.rs b/src/test/ui/pattern/usefulness/match-slice-patterns.rs
index afbeb61e441..af7fd53a1f1 100644
--- a/src/test/ui/pattern/usefulness/match-slice-patterns.rs
+++ b/src/test/ui/pattern/usefulness/match-slice-patterns.rs
@@ -2,7 +2,7 @@
 
 fn check(list: &[Option<()>]) {
     match list {
-    //~^ ERROR `&[_, Some(_), None, _]` not covered
+    //~^ ERROR `&[_, Some(_), .., None, _]` not covered
         &[] => {},
         &[_] => {},
         &[_, _] => {},
diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
index 24769db34c9..72ae5d5fe3b 100644
--- a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
+++ b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `&[_, Some(_), None, _]` not covered
+error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered
   --> $DIR/match-slice-patterns.rs:4:11
    |
 LL |     match list {
-   |           ^^^^ pattern `&[_, Some(_), None, _]` not covered
+   |           ^^^^ pattern `&[_, Some(_), .., None, _]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
index 0e5a9203c5f..bfca5352353 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
@@ -44,7 +44,7 @@ fn main() {
     }
     let vec = vec![0.5f32];
     let vec: &[f32] = &vec;
-    match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered
+    match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _, ..]` not covered
         [0.1, 0.2, 0.3] => (),
         [0.1, 0.2] => (),
         [0.1] => (),
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index 5dba05e1642..577867e4e71 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -66,11 +66,11 @@ LL |     match *vec {
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered
+error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
   --> $DIR/non-exhaustive-match.rs:47:11
    |
 LL |     match *vec {
-   |           ^^^^ pattern `[_, _, _, _]` not covered
+   |           ^^^^ pattern `[_, _, _, _, ..]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/pattern/slice-pattern-const-2.rs b/src/test/ui/pattern/usefulness/slice-pattern-const-2.rs
index a36c550f530..a36c550f530 100644
--- a/src/test/ui/pattern/slice-pattern-const-2.rs
+++ b/src/test/ui/pattern/usefulness/slice-pattern-const-2.rs
diff --git a/src/test/ui/pattern/slice-pattern-const-2.stderr b/src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr
index 0c7401269df..0c7401269df 100644
--- a/src/test/ui/pattern/slice-pattern-const-2.stderr
+++ b/src/test/ui/pattern/usefulness/slice-pattern-const-2.stderr
diff --git a/src/test/ui/pattern/slice-pattern-const-3.rs b/src/test/ui/pattern/usefulness/slice-pattern-const-3.rs
index 8805c43ba02..8805c43ba02 100644
--- a/src/test/ui/pattern/slice-pattern-const-3.rs
+++ b/src/test/ui/pattern/usefulness/slice-pattern-const-3.rs
diff --git a/src/test/ui/pattern/slice-pattern-const-3.stderr b/src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr
index eab4fc3f086..eab4fc3f086 100644
--- a/src/test/ui/pattern/slice-pattern-const-3.stderr
+++ b/src/test/ui/pattern/usefulness/slice-pattern-const-3.stderr
diff --git a/src/test/ui/pattern/slice-pattern-const.rs b/src/test/ui/pattern/usefulness/slice-pattern-const.rs
index f0a04513f91..f0a04513f91 100644
--- a/src/test/ui/pattern/slice-pattern-const.rs
+++ b/src/test/ui/pattern/usefulness/slice-pattern-const.rs
diff --git a/src/test/ui/pattern/slice-pattern-const.stderr b/src/test/ui/pattern/usefulness/slice-pattern-const.stderr
index 2dd10a0478a..2dd10a0478a 100644
--- a/src/test/ui/pattern/slice-pattern-const.stderr
+++ b/src/test/ui/pattern/usefulness/slice-pattern-const.stderr
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
new file mode 100644
index 00000000000..86cdf160618
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs
@@ -0,0 +1,75 @@
+#![feature(slice_patterns)]
+
+fn main() {
+    let s: &[bool] = &[true; 0];
+    let s1: &[bool; 1] = &[false; 1];
+    let s2: &[bool; 2] = &[false; 2];
+    let s3: &[bool; 3] = &[false; 3];
+
+    match s1 {
+        [true, ..] => {}
+        [.., false] => {}
+    }
+    match s2 {
+    //~^ ERROR `&[false, true]` not covered
+        [true, ..] => {}
+        [.., false] => {}
+    }
+    match s3 {
+    //~^ ERROR `&[false, _, true]` not covered
+        [true, ..] => {}
+        [.., false] => {}
+    }
+    match s {
+    //~^ ERROR `&[false, .., true]` not covered
+        [] => {}
+        [true, ..] => {}
+        [.., false] => {}
+    }
+
+    match s3 {
+    //~^ ERROR `&[false, _, _]` not covered
+        [true, .., true] => {}
+    }
+    match s {
+    //~^ ERROR `&[_, ..]` not covered
+        [] => {}
+    }
+    match s {
+    //~^ ERROR `&[_, _, ..]` not covered
+        [] => {}
+        [_] => {}
+    }
+    match s {
+    //~^ ERROR `&[false, ..]` not covered
+        [] => {}
+        [true, ..] => {}
+    }
+    match s {
+    //~^ ERROR `&[false, _, ..]` not covered
+        [] => {}
+        [_] => {}
+        [true, ..] => {}
+    }
+    match s {
+    //~^ ERROR `&[_, .., false]` not covered
+        [] => {}
+        [_] => {}
+        [.., true] => {}
+    }
+
+    match s {
+    //~^ ERROR `&[_, _, .., true]` not covered
+        [] => {}
+        [_] => {}
+        [_, _] => {}
+        [.., false] => {}
+    }
+    match s {
+    //~^ ERROR `&[true, _, .., _]` not covered
+        [] => {}
+        [_] => {}
+        [_, _] => {}
+        [false, .., false] => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
new file mode 100644
index 00000000000..1391b520556
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr
@@ -0,0 +1,91 @@
+error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:13:11
+   |
+LL |     match s2 {
+   |           ^^ pattern `&[false, true]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, _, true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:18:11
+   |
+LL |     match s3 {
+   |           ^^ pattern `&[false, _, true]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:23:11
+   |
+LL |     match s {
+   |           ^ pattern `&[false, .., true]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, _, _]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:30:11
+   |
+LL |     match s3 {
+   |           ^^ pattern `&[false, _, _]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:34:11
+   |
+LL |     match s {
+   |           ^ pattern `&[_, ..]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:38:11
+   |
+LL |     match s {
+   |           ^ pattern `&[_, _, ..]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:43:11
+   |
+LL |     match s {
+   |           ^ pattern `&[false, ..]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:48:11
+   |
+LL |     match s {
+   |           ^ pattern `&[false, _, ..]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:54:11
+   |
+LL |     match s {
+   |           ^ pattern `&[_, .., false]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:61:11
+   |
+LL |     match s {
+   |           ^ pattern `&[_, _, .., true]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
+  --> $DIR/slice-patterns-exhaustiveness.rs:68:11
+   |
+LL |     match s {
+   |           ^ pattern `&[true, _, .., _]` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs
new file mode 100644
index 00000000000..3b716bae772
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs
@@ -0,0 +1,27 @@
+// check-pass
+#![feature(slice_patterns)]
+
+fn main() {
+    let s: &[bool] = &[true; 0];
+    let s0: &[bool; 0] = &[];
+    let s1: &[bool; 1] = &[false; 1];
+    let s2: &[bool; 2] = &[false; 2];
+
+    let [] = s0;
+    let [_] = s1;
+    let [_, _] = s2;
+
+    let [..] = s;
+    let [..] = s0;
+    let [..] = s1;
+    let [..] = s2;
+
+    let [_, ..] = s1;
+    let [.., _] = s1;
+    let [_, ..] = s2;
+    let [.., _] = s2;
+
+    let [_, _, ..] = s2;
+    let [_, .., _] = s2;
+    let [.., _, _] = s2;
+}
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs
new file mode 100644
index 00000000000..35d9dc91aee
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs
@@ -0,0 +1,26 @@
+#![feature(slice_patterns)]
+#![deny(unreachable_patterns)]
+
+fn main() {
+    let s: &[bool] = &[true; 0];
+
+    match s {
+        [true, ..] => {}
+        [true, ..] => {} //~ ERROR unreachable pattern
+        [true] => {} //~ ERROR unreachable pattern
+        [..] => {}
+    }
+    match s {
+        [.., true] => {}
+        [.., true] => {} //~ ERROR unreachable pattern
+        [true] => {} //~ ERROR unreachable pattern
+        [..] => {}
+    }
+    match s {
+        [false, .., true] => {}
+        [false, .., true] => {} //~ ERROR unreachable pattern
+        [false, true] => {} //~ ERROR unreachable pattern
+        [false] => {}
+        [..] => {}
+    }
+}
diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr
new file mode 100644
index 00000000000..333ce170283
--- /dev/null
+++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr
@@ -0,0 +1,44 @@
+error: unreachable pattern
+  --> $DIR/slice-patterns-reachability.rs:9:9
+   |
+LL |         [true, ..] => {}
+   |         ^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/slice-patterns-reachability.rs:2:9
+   |
+LL | #![deny(unreachable_patterns)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-patterns-reachability.rs:10:9
+   |
+LL |         [true] => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-patterns-reachability.rs:15:9
+   |
+LL |         [.., true] => {}
+   |         ^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-patterns-reachability.rs:16:9
+   |
+LL |         [true] => {}
+   |         ^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-patterns-reachability.rs:21:9
+   |
+LL |         [false, .., true] => {}
+   |         ^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/slice-patterns-reachability.rs:22:9
+   |
+LL |         [false, true] => {}
+   |         ^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/privacy/issue-57264-1.rs b/src/test/ui/privacy/issue-57264-1.rs
index 5ef6a61fea1..59ebc4f54ee 100644
--- a/src/test/ui/privacy/issue-57264-1.rs
+++ b/src/test/ui/privacy/issue-57264-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // aux-build:issue-57264-1.rs
 
 extern crate issue_57264_1;
diff --git a/src/test/ui/privacy/issue-57264-2.rs b/src/test/ui/privacy/issue-57264-2.rs
index 4d5c9cfa1d5..36ce5fd3b3e 100644
--- a/src/test/ui/privacy/issue-57264-2.rs
+++ b/src/test/ui/privacy/issue-57264-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // aux-build:issue-57264-2.rs
 
 extern crate issue_57264_2;
diff --git a/src/test/ui/privacy/legacy-ctor-visibility.rs b/src/test/ui/privacy/legacy-ctor-visibility.rs
index 7db4be729e8..5732b6446fe 100644
--- a/src/test/ui/privacy/legacy-ctor-visibility.rs
+++ b/src/test/ui/privacy/legacy-ctor-visibility.rs
@@ -1,7 +1,3 @@
-// ignore-tidy-linelength
-
-#![allow(unused)]
-
 use m::S;
 
 mod m {
@@ -11,8 +7,7 @@ mod m {
         use S;
         fn f() {
             S(10);
-            //~^ ERROR private struct constructors are not usable through re-exports in outer modules
-            //~| WARN this was previously accepted
+            //~^ ERROR expected function, tuple struct or tuple variant, found struct `S`
         }
     }
 }
diff --git a/src/test/ui/privacy/legacy-ctor-visibility.stderr b/src/test/ui/privacy/legacy-ctor-visibility.stderr
index 69b6e08befc..74a1f1ceeff 100644
--- a/src/test/ui/privacy/legacy-ctor-visibility.stderr
+++ b/src/test/ui/privacy/legacy-ctor-visibility.stderr
@@ -1,12 +1,13 @@
-error: private struct constructors are not usable through re-exports in outer modules
-  --> $DIR/legacy-ctor-visibility.rs:13:13
+error[E0423]: expected function, tuple struct or tuple variant, found struct `S`
+  --> $DIR/legacy-ctor-visibility.rs:9:13
    |
-LL |             S(10);
-   |             ^
-   |
-   = note: `#[deny(legacy_constructor_visibility)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #39207 <https://github.com/rust-lang/rust/issues/39207>
+LL | /         fn f() {
+LL | |             S(10);
+   | |             ^ help: a function with a similar name exists: `f`
+LL | |
+LL | |         }
+   | |_________- similarly named function `f` defined here
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr
index 1503f62cb6c..021e7cad09b 100644
--- a/src/test/ui/proc-macro/attribute.stderr
+++ b/src/test/ui/proc-macro/attribute.stderr
@@ -1,3 +1,15 @@
+error: malformed `proc_macro_derive` attribute input
+  --> $DIR/attribute.rs:9:1
+   |
+LL | #[proc_macro_derive]
+   | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
+
+error: malformed `proc_macro_derive` attribute input
+  --> $DIR/attribute.rs:12:1
+   |
+LL | #[proc_macro_derive = ""]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
+
 error: attribute must have either one or two arguments
   --> $DIR/attribute.rs:15:1
    |
@@ -88,17 +100,5 @@ error: `self` cannot be a name of derive helper attribute
 LL | #[proc_macro_derive(d17, attributes(self))]
    |                                     ^^^^
 
-error: malformed `proc_macro_derive` attribute input
-  --> $DIR/attribute.rs:9:1
-   |
-LL | #[proc_macro_derive]
-   | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
-
-error: malformed `proc_macro_derive` attribute input
-  --> $DIR/attribute.rs:12:1
-   |
-LL | #[proc_macro_derive = ""]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
-
 error: aborting due to 17 previous errors
 
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs
index 2495e72751b..fb13bb064c7 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs
+++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 // aux-build:test-macros.rs
 
diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.rs b/src/test/ui/proc-macro/expand-to-unstable-2.rs
index da7c89fdd46..4160e5418b7 100644
--- a/src/test/ui/proc-macro/expand-to-unstable-2.rs
+++ b/src/test/ui/proc-macro/expand-to-unstable-2.rs
@@ -1,6 +1,8 @@
 // aux-build:derive-unstable-2.rs
 
-#![feature(custom_attribute)]
+#![feature(register_attr)]
+
+#![register_attr(rustc_foo)]
 
 #[macro_use]
 extern crate derive_unstable_2;
diff --git a/src/test/ui/proc-macro/expand-to-unstable-2.stderr b/src/test/ui/proc-macro/expand-to-unstable-2.stderr
index 01e6a4a8ab9..5b6184afacd 100644
--- a/src/test/ui/proc-macro/expand-to-unstable-2.stderr
+++ b/src/test/ui/proc-macro/expand-to-unstable-2.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes starting with `rustc` are reserved for use by the `rustc` compiler
-  --> $DIR/expand-to-unstable-2.rs:8:10
+  --> $DIR/expand-to-unstable-2.rs:10:10
    |
 LL | #[derive(Unstable)]
    |          ^^^^^^^^
diff --git a/src/test/ui/proc-macro/exports.stderr b/src/test/ui/proc-macro/exports.stderr
index 2f81921358d..0ecbdf98dd3 100644
--- a/src/test/ui/proc-macro/exports.stderr
+++ b/src/test/ui/proc-macro/exports.stderr
@@ -1,22 +1,22 @@
-error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
   --> $DIR/exports.rs:7:1
    |
 LL | pub fn a() {}
    | ^^^^^^^^^^^^^
 
-error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
   --> $DIR/exports.rs:8:1
    |
 LL | pub struct B;
    | ^^^^^^^^^^^^^
 
-error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
   --> $DIR/exports.rs:9:1
    |
 LL | pub enum C {}
    | ^^^^^^^^^^^^^
 
-error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
   --> $DIR/exports.rs:10:1
    |
 LL | pub mod d {}
diff --git a/src/test/ui/proc-macro/issue-41211.rs b/src/test/ui/proc-macro/issue-41211.rs
index 491b89b2f55..072a63baf3a 100644
--- a/src/test/ui/proc-macro/issue-41211.rs
+++ b/src/test/ui/proc-macro/issue-41211.rs
@@ -3,11 +3,13 @@
 // FIXME: https://github.com/rust-lang/rust/issues/41430
 // This is a temporary regression test for the ICE reported in #41211
 
-#![feature(custom_attribute)]
 #![feature(custom_inner_attributes)]
+#![feature(register_attr)]
+
+#![register_attr(identity_attr)]
 
 #![identity_attr]
-//~^ ERROR inconsistent resolution for a macro: first custom attribute, then attribute macro
+//~^ ERROR `identity_attr` is ambiguous
 extern crate test_macros;
 use test_macros::identity_attr;
 
diff --git a/src/test/ui/proc-macro/issue-41211.stderr b/src/test/ui/proc-macro/issue-41211.stderr
index f01cba0c930..22ad4aa147b 100644
--- a/src/test/ui/proc-macro/issue-41211.stderr
+++ b/src/test/ui/proc-macro/issue-41211.stderr
@@ -1,8 +1,21 @@
-error: inconsistent resolution for a macro: first custom attribute, then attribute macro
-  --> $DIR/issue-41211.rs:9:4
+error[E0659]: `identity_attr` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
+  --> $DIR/issue-41211.rs:11:4
    |
 LL | #![identity_attr]
-   |    ^^^^^^^^^^^^^
+   |    ^^^^^^^^^^^^^ ambiguous name
+   |
+note: `identity_attr` could refer to the attribute macro imported here
+  --> $DIR/issue-41211.rs:14:5
+   |
+LL | use test_macros::identity_attr;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use `crate::identity_attr` to refer to this attribute macro unambiguously
+note: `identity_attr` could also refer to the explicitly registered attribute defined here
+  --> $DIR/issue-41211.rs:9:18
+   |
+LL | #![register_attr(identity_attr)]
+   |                  ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/proc-macro/pub-at-crate-root.rs b/src/test/ui/proc-macro/pub-at-crate-root.rs
index 7544245ff67..54cf333a45b 100644
--- a/src/test/ui/proc-macro/pub-at-crate-root.rs
+++ b/src/test/ui/proc-macro/pub-at-crate-root.rs
@@ -5,7 +5,7 @@
 
 extern crate proc_macro;
 
-pub mod a { //~ `proc-macro` crate types cannot export any items
+pub mod a { //~ `proc-macro` crate types currently cannot export any items
     use proc_macro::TokenStream;
 
     #[proc_macro_derive(B)]
diff --git a/src/test/ui/proc-macro/pub-at-crate-root.stderr b/src/test/ui/proc-macro/pub-at-crate-root.stderr
index 66fa499d33b..3b69b7875bd 100644
--- a/src/test/ui/proc-macro/pub-at-crate-root.stderr
+++ b/src/test/ui/proc-macro/pub-at-crate-root.stderr
@@ -1,4 +1,4 @@
-error: `proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
+error: `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
   --> $DIR/pub-at-crate-root.rs:8:1
    |
 LL | / pub mod a {
diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
index ee9e7a364b8..bdd1ae91f7d 100644
--- a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
+++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
@@ -8,7 +8,7 @@
 // follow the same lifetime-elision rules used elsehwere. See
 // rust-lang/rust#56537
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
     let free_dumb = |_x| { p }; // no type annotation at all
diff --git a/src/test/ui/removing-extern-crate.fixed b/src/test/ui/removing-extern-crate.fixed
index d2993dbc4a4..8dbd0395b97 100644
--- a/src/test/ui/removing-extern-crate.fixed
+++ b/src/test/ui/removing-extern-crate.fixed
@@ -1,17 +1,16 @@
 // edition:2018
 // aux-build:removing-extern-crate.rs
 // run-rustfix
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(rust_2018_idioms)]
-#![allow(unused_imports)]
-
-
 
+ //~ WARNING unused extern crate
+ //~ WARNING unused extern crate
 
 mod another {
-    
-    
+     //~ WARNING unused extern crate
+     //~ WARNING unused extern crate
 }
 
 fn main() {}
diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs
index 22fdfc2b0ec..465e1360c2a 100644
--- a/src/test/ui/removing-extern-crate.rs
+++ b/src/test/ui/removing-extern-crate.rs
@@ -1,17 +1,16 @@
 // edition:2018
 // aux-build:removing-extern-crate.rs
 // run-rustfix
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(rust_2018_idioms)]
-#![allow(unused_imports)]
 
-extern crate removing_extern_crate as foo;
-extern crate core;
+extern crate removing_extern_crate as foo; //~ WARNING unused extern crate
+extern crate core; //~ WARNING unused extern crate
 
 mod another {
-    extern crate removing_extern_crate as foo;
-    extern crate core;
+    extern crate removing_extern_crate as foo; //~ WARNING unused extern crate
+    extern crate core; //~ WARNING unused extern crate
 }
 
 fn main() {}
diff --git a/src/test/ui/removing-extern-crate.stderr b/src/test/ui/removing-extern-crate.stderr
index 18d0756e9f4..20d5564c16d 100644
--- a/src/test/ui/removing-extern-crate.stderr
+++ b/src/test/ui/removing-extern-crate.stderr
@@ -1,5 +1,5 @@
 warning: unused extern crate
-  --> $DIR/removing-extern-crate.rs:9:1
+  --> $DIR/removing-extern-crate.rs:8:1
    |
 LL | extern crate removing_extern_crate as foo;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
@@ -12,19 +12,19 @@ LL | #![warn(rust_2018_idioms)]
    = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]`
 
 warning: unused extern crate
-  --> $DIR/removing-extern-crate.rs:10:1
+  --> $DIR/removing-extern-crate.rs:9:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ help: remove it
 
 warning: unused extern crate
-  --> $DIR/removing-extern-crate.rs:13:5
+  --> $DIR/removing-extern-crate.rs:12:5
    |
 LL |     extern crate removing_extern_crate as foo;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
 warning: unused extern crate
-  --> $DIR/removing-extern-crate.rs:14:5
+  --> $DIR/removing-extern-crate.rs:13:5
    |
 LL |     extern crate core;
    |     ^^^^^^^^^^^^^^^^^^ help: remove it
diff --git a/src/test/ui/resolve/issue-57523.rs b/src/test/ui/resolve/issue-57523.rs
index 5dc467d97e2..976238cc3bd 100644
--- a/src/test/ui/resolve/issue-57523.rs
+++ b/src/test/ui/resolve/issue-57523.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct S(u8);
 
diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr
index 57dd7c9f034..dd0e2597850 100644
--- a/src/test/ui/resolve/token-error-correct-3.stderr
+++ b/src/test/ui/resolve/token-error-correct-3.stderr
@@ -10,7 +10,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)`
   --> $DIR/token-error-correct-3.rs:18:9
    |
 LL |             fs::create_dir_all(path.as_ref()).map(|()| true)
-   |                                                             - expected one of `.`, `;`, `?`, `}`, or an operator here
+   |                                                             - expected one of `.`, `;`, `?`, `}`, or an operator
 LL |         } else {
    |         ^ unexpected token
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
index c27cea302fc..a028247ec5c 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
@@ -1,6 +1,5 @@
 // compile-flags: --test
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 
 use std::num::ParseFloatError;
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 6aa95c308f2..9cefef58bf5 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `main` has invalid return type `std::result::Result<f32, std::num::ParseFloatError>`
-  --> $DIR/termination-trait-test-wrong-type.rs:8:1
+  --> $DIR/termination-trait-test-wrong-type.rs:7:1
    |
 LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
 LL | |     "0".parse()
diff --git a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
index ab6c59384c4..1c4d4666fa1 100644
--- a/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
+++ b/src/test/ui/rfc-2091-track-caller/caller-location-intrinsic.rs
@@ -1,9 +1,21 @@
 // run-pass
 
 #![feature(core_intrinsics)]
+
+macro_rules! caller_location_from_macro {
+    () => (core::intrinsics::caller_location());
+}
+
 fn main() {
     let loc = core::intrinsics::caller_location();
     assert_eq!(loc.file(), file!());
-    assert_eq!(loc.line(), 5);
+    assert_eq!(loc.line(), 10);
     assert_eq!(loc.column(), 15);
+
+    // `caller_location()` in a macro should behave similarly to `file!` and `line!`,
+    // i.e. point to where the macro was invoked, instead of the macro itself.
+    let loc2 = caller_location_from_macro!();
+    assert_eq!(loc2.file(), file!());
+    assert_eq!(loc2.line(), 17);
+    assert_eq!(loc2.column(), 16);
 }
diff --git a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
index b662685ae24..c712f15e324 100644
--- a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
+++ b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
@@ -6,7 +6,7 @@
 // strange errors. This test ensures that we do not give compilation
 // errors.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait MyIterator<'a>: Iterator where Self::Item: 'a { }
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index ad4686c1915..65de150b100 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -2,7 +2,7 @@ error: expected one of `,` or `>`, found `&&`
   --> $DIR/disallowed-positions.rs:242:14
    |
 LL |         true && let 1 = 1
-   |              ^^ expected one of `,` or `>` here
+   |              ^^ expected one of `,` or `>`
 
 error: `let` expressions are not supported here
   --> $DIR/disallowed-positions.rs:32:9
diff --git a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs
index b95105b59ed..44298367188 100644
--- a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs
@@ -10,7 +10,7 @@ fn main() {
 
     fn _f1() -> bool {
         // Should associate as `(let _ = (return (true && false)))`.
-        if let _ = return true && false {};
+        if let _ = return true && false {}; //~ WARNING unreachable_code
     }
     assert!(!_f1());
 }
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
index e4248f3b974..1e51567a9b1 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/param-attrs-2018.rs:3:41
    |
 LL | trait Trait2015 { fn foo(#[allow(C)] i32); }
-   |                                         ^ expected one of `:`, `@`, or `|` here
+   |                                         ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a `self` type, give it a parameter name
diff --git a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr
index 749032dbcc2..9c8d3f192da 100644
--- a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr
@@ -2,7 +2,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
   --> $DIR/empty_generics.rs:5:14
    |
 LL |     type Bar<,>;
-   |              ^ expected one of `>`, `const`, identifier, or lifetime here
+   |              ^ expected one of `>`, `const`, identifier, or lifetime
 
 warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash
   --> $DIR/empty_generics.rs:1:12
diff --git a/src/test/ui/rust-2018/remove-extern-crate.fixed b/src/test/ui/rust-2018/remove-extern-crate.fixed
index 7ddd2f547f0..2e10d555590 100644
--- a/src/test/ui/rust-2018/remove-extern-crate.fixed
+++ b/src/test/ui/rust-2018/remove-extern-crate.fixed
@@ -6,7 +6,7 @@
 
 #![warn(rust_2018_idioms)]
 
-
+ //~ WARNING unused extern crate
 // Shouldn't suggest changing to `use`, as `another_name`
 // would no longer be added to the prelude which could cause
 // compilation errors for imports that use `another_name` in other
@@ -29,7 +29,7 @@ fn main() {
 }
 
 mod another {
-    use core;
+    use core; //~ WARNING `extern crate` is not idiomatic
     use remove_extern_crate;
 
     pub fn foo() {
diff --git a/src/test/ui/rust-2018/remove-extern-crate.rs b/src/test/ui/rust-2018/remove-extern-crate.rs
index 298b1614026..9b04f901310 100644
--- a/src/test/ui/rust-2018/remove-extern-crate.rs
+++ b/src/test/ui/rust-2018/remove-extern-crate.rs
@@ -6,7 +6,7 @@
 
 #![warn(rust_2018_idioms)]
 
-extern crate core;
+extern crate core; //~ WARNING unused extern crate
 // Shouldn't suggest changing to `use`, as `another_name`
 // would no longer be added to the prelude which could cause
 // compilation errors for imports that use `another_name` in other
@@ -29,7 +29,7 @@ fn main() {
 }
 
 mod another {
-    extern crate core;
+    extern crate core; //~ WARNING `extern crate` is not idiomatic
     use remove_extern_crate;
 
     pub fn foo() {
diff --git a/src/test/ui/rust-2018/try-ident.fixed b/src/test/ui/rust-2018/try-ident.fixed
index f86a401cdf9..f285b2c0ee6 100644
--- a/src/test/ui/rust-2018/try-ident.fixed
+++ b/src/test/ui/rust-2018/try-ident.fixed
@@ -5,7 +5,11 @@
 
 fn main() {
     r#try();
+    //~^ WARNING `try` is a keyword in the 2018 edition
+    //~| WARNING it will become a hard error in the 2018 edition!
 }
 
 fn r#try() {
+    //~^ WARNING `try` is a keyword in the 2018 edition
+    //~| WARNING it will become a hard error in the 2018 edition!
 }
diff --git a/src/test/ui/rust-2018/try-ident.rs b/src/test/ui/rust-2018/try-ident.rs
index 6cc6aa12ff7..d740801b562 100644
--- a/src/test/ui/rust-2018/try-ident.rs
+++ b/src/test/ui/rust-2018/try-ident.rs
@@ -5,7 +5,11 @@
 
 fn main() {
     try();
+    //~^ WARNING `try` is a keyword in the 2018 edition
+    //~| WARNING it will become a hard error in the 2018 edition!
 }
 
 fn try() {
+    //~^ WARNING `try` is a keyword in the 2018 edition
+    //~| WARNING it will become a hard error in the 2018 edition!
 }
diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr
index 852e3e5aed6..29cc68c439e 100644
--- a/src/test/ui/rust-2018/try-ident.stderr
+++ b/src/test/ui/rust-2018/try-ident.stderr
@@ -14,7 +14,7 @@ LL | #![warn(rust_2018_compatibility)]
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 warning: `try` is a keyword in the 2018 edition
-  --> $DIR/try-ident.rs:10:4
+  --> $DIR/try-ident.rs:12:4
    |
 LL | fn try() {
    |    ^^^ help: you can use a raw identifier to stay compatible: `r#try`
diff --git a/src/test/ui/rust-2018/try-macro.fixed b/src/test/ui/rust-2018/try-macro.fixed
index a7b7d3faf5e..5c899378b94 100644
--- a/src/test/ui/rust-2018/try-macro.fixed
+++ b/src/test/ui/rust-2018/try-macro.fixed
@@ -1,16 +1,17 @@
 // Test that `try!` macros are rewritten.
 
 // run-rustfix
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(rust_2018_compatibility)]
-#![allow(unused_variables)]
 #![allow(dead_code)]
 #![allow(deprecated)]
 
 fn foo() -> Result<usize, ()> {
     let x: Result<usize, ()> = Ok(22);
     r#try!(x);
+    //~^ WARNING `try` is a keyword in the 2018 edition
+    //~| WARNING this was previously accepted
     Ok(44)
 }
 
diff --git a/src/test/ui/rust-2018/try-macro.rs b/src/test/ui/rust-2018/try-macro.rs
index 986e158eb64..db8a198d282 100644
--- a/src/test/ui/rust-2018/try-macro.rs
+++ b/src/test/ui/rust-2018/try-macro.rs
@@ -1,16 +1,17 @@
 // Test that `try!` macros are rewritten.
 
 // run-rustfix
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(rust_2018_compatibility)]
-#![allow(unused_variables)]
 #![allow(dead_code)]
 #![allow(deprecated)]
 
 fn foo() -> Result<usize, ()> {
     let x: Result<usize, ()> = Ok(22);
     try!(x);
+    //~^ WARNING `try` is a keyword in the 2018 edition
+    //~| WARNING this was previously accepted
     Ok(44)
 }
 
diff --git a/src/test/ui/rust-2018/try-macro.stderr b/src/test/ui/rust-2018/try-macro.stderr
index fad1bb9f1b0..eb65d415064 100644
--- a/src/test/ui/rust-2018/try-macro.stderr
+++ b/src/test/ui/rust-2018/try-macro.stderr
@@ -1,5 +1,5 @@
 warning: `try` is a keyword in the 2018 edition
-  --> $DIR/try-macro.rs:13:5
+  --> $DIR/try-macro.rs:12:5
    |
 LL |     try!(x);
    |     ^^^ help: you can use a raw identifier to stay compatible: `r#try`
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
index 446b2d05717..9ea7e496d2b 100644
--- a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
+++ b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 // compile-flags: --extern issue_56596_2
 // aux-build:issue-56596-2.rs
diff --git a/src/test/ui/safe-extern-statics.rs b/src/test/ui/safe-extern-statics.rs
index eda30944468..0535a078d2c 100644
--- a/src/test/ui/safe-extern-statics.rs
+++ b/src/test/ui/safe-extern-statics.rs
@@ -1,7 +1,5 @@
 // aux-build:extern-statics.rs
 
-#![allow(unused)]
-
 extern crate extern_statics;
 use extern_statics::*;
 
@@ -11,11 +9,7 @@ extern {
 
 fn main() {
     let a = A; //~ ERROR use of extern static is unsafe
-               //~^ WARN this was previously accepted by the compiler
     let ra = &A; //~ ERROR use of extern static is unsafe
-                 //~^ WARN this was previously accepted by the compiler
     let xa = XA; //~ ERROR use of extern static is unsafe
-                 //~^ WARN this was previously accepted by the compiler
     let xra = &XA; //~ ERROR use of extern static is unsafe
-                   //~^ WARN this was previously accepted by the compiler
 }
diff --git a/src/test/ui/safe-extern-statics.stderr b/src/test/ui/safe-extern-statics.stderr
index 0948fad74e5..b42572ea3ee 100644
--- a/src/test/ui/safe-extern-statics.stderr
+++ b/src/test/ui/safe-extern-statics.stderr
@@ -1,43 +1,35 @@
-error: use of extern static is unsafe and requires unsafe function or block (error E0133)
-  --> $DIR/safe-extern-statics.rs:13:13
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/safe-extern-statics.rs:11:13
    |
 LL |     let a = A;
-   |             ^
+   |             ^ use of extern static
    |
-   = note: `#[deny(safe_extern_statics)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36247 <https://github.com/rust-lang/rust/issues/36247>
    = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
 
-error: use of extern static is unsafe and requires unsafe function or block (error E0133)
-  --> $DIR/safe-extern-statics.rs:15:14
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/safe-extern-statics.rs:12:14
    |
 LL |     let ra = &A;
-   |              ^^
+   |              ^^ use of extern static
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36247 <https://github.com/rust-lang/rust/issues/36247>
    = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
 
-error: use of extern static is unsafe and requires unsafe function or block (error E0133)
-  --> $DIR/safe-extern-statics.rs:17:14
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/safe-extern-statics.rs:13:14
    |
 LL |     let xa = XA;
-   |              ^^
+   |              ^^ use of extern static
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36247 <https://github.com/rust-lang/rust/issues/36247>
    = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
 
-error: use of extern static is unsafe and requires unsafe function or block (error E0133)
-  --> $DIR/safe-extern-statics.rs:19:15
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/safe-extern-statics.rs:14:15
    |
 LL |     let xra = &XA;
-   |               ^^^
+   |               ^^^ use of extern static
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #36247 <https://github.com/rust-lang/rust/issues/36247>
    = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
 
 error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr
index 3113d4a872d..d3d5b4a6d1e 100644
--- a/src/test/ui/similar-tokens.stderr
+++ b/src/test/ui/similar-tokens.stderr
@@ -2,7 +2,7 @@ error: expected one of `,`, `::`, `as`, or `}`, found `.`
   --> $DIR/similar-tokens.rs:7:10
    |
 LL | use x::{A. B};
-   |          ^ expected one of `,`, `::`, `as`, or `}` here
+   |          ^ expected one of `,`, `::`, `as`, or `}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr
index 81409aac289..f23f421edc7 100644
--- a/src/test/ui/span/impl-wrong-item-for-trait.stderr
+++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr
@@ -64,7 +64,7 @@ error[E0046]: not all trait items implemented, missing: `fmt`
 LL | impl Debug for FooTypeForMethod {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
    |
-   = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+   = help: implement the missing item: `fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { unimplemented!() }`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr
index 865fae917c5..f88ce6c88db 100644
--- a/src/test/ui/span/issue-23729.stderr
+++ b/src/test/ui/span/issue-23729.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item`
 LL |         impl Iterator for Recurrence {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
    |
-   = note: `Item` from trait: `type Item;`
+   = help: implement the missing item: `type Item = Type;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr
index a8e3e9b6b9a..46a820f1b76 100644
--- a/src/test/ui/span/issue-23827.stderr
+++ b/src/test/ui/span/issue-23827.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
 LL | impl<C: Component> FnOnce<(C,)> for Prototype {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
    |
-   = note: `Output` from trait: `type Output;`
+   = help: implement the missing item: `type Output = Type;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr
index 4827e9ddd50..a1f9b255020 100644
--- a/src/test/ui/span/issue-24356.stderr
+++ b/src/test/ui/span/issue-24356.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target`
 LL |         impl Deref for Thing {
    |         ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
    |
-   = note: `Target` from trait: `type Target;`
+   = help: implement the missing item: `type Target = Type;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs
index f51ea55d4e6..2b7349c5503 100644
--- a/src/test/ui/span/issue-24690.rs
+++ b/src/test/ui/span/issue-24690.rs
@@ -1,7 +1,7 @@
 //! A test to ensure that helpful `note` messages aren't emitted more often
 //! than necessary.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Although there are three warnings, we should only get two "lint level defined
 // here" notes pointing at the `warnings` span, one for each error type.
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 8d4a66f142d..26d686f6f50 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `<`
   --> $DIR/issue-34264.rs:1:14
    |
 LL | fn foo(Option<i32>, String) {}
-   |              ^ expected one of `:`, `@`, or `|` here
+   |              ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a type, explicitly ignore the parameter name
@@ -14,7 +14,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/issue-34264.rs:1:27
    |
 LL | fn foo(Option<i32>, String) {}
-   |                           ^ expected one of `:`, `@`, or `|` here
+   |                           ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -30,7 +30,7 @@ error: expected one of `:`, `@`, or `|`, found `,`
   --> $DIR/issue-34264.rs:3:9
    |
 LL | fn bar(x, y: usize) {}
-   |         ^ expected one of `:`, `@`, or `|` here
+   |         ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
diff --git a/src/test/ui/span/issue-36530.rs b/src/test/ui/span/issue-36530.rs
index 14b2c8644e0..4776740d8de 100644
--- a/src/test/ui/span/issue-36530.rs
+++ b/src/test/ui/span/issue-36530.rs
@@ -1,6 +1,8 @@
 // gate-test-custom_inner_attributes
 
-#![feature(custom_attribute)]
+#![feature(register_attr)]
+
+#![register_attr(foo)]
 
 #[foo]
 mod foo {
diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr
index c6b7895e65a..2d3972917df 100644
--- a/src/test/ui/span/issue-36530.stderr
+++ b/src/test/ui/span/issue-36530.stderr
@@ -1,5 +1,5 @@
 error[E0658]: non-builtin inner attributes are unstable
-  --> $DIR/issue-36530.rs:7:5
+  --> $DIR/issue-36530.rs:9:5
    |
 LL |     #![foo]
    |     ^^^^^^^
diff --git a/src/test/ui/span/issue-36537.stderr b/src/test/ui/span/issue-36537.stderr
index edb804e850e..0939584380a 100644
--- a/src/test/ui/span/issue-36537.stderr
+++ b/src/test/ui/span/issue-36537.stderr
@@ -1,8 +1,8 @@
 error[E0597]: `a` does not live long enough
-  --> $DIR/issue-36537.rs:5:9
+  --> $DIR/issue-36537.rs:5:13
    |
 LL |         p = &a;
-   |         ^^^^^^ borrowed value does not live long enough
+   |             ^^ borrowed value does not live long enough
 ...
 LL |     }
    |     - `a` dropped here while still borrowed
diff --git a/src/test/ui/span/unused-warning-point-at-signature.rs b/src/test/ui/span/unused-warning-point-at-identifier.rs
index 3af272a012e..d4d5bc1cbc8 100644
--- a/src/test/ui/span/unused-warning-point-at-signature.rs
+++ b/src/test/ui/span/unused-warning-point-at-identifier.rs
@@ -20,8 +20,8 @@ fn func() -> usize { //~ WARN function is never used
     3
 }
 
-fn //~ WARN function is never used
-func_complete_span()
+fn
+func_complete_span() //~ WARN function is never used
 -> usize
 {
     3
diff --git a/src/test/ui/span/unused-warning-point-at-signature.stderr b/src/test/ui/span/unused-warning-point-at-identifier.stderr
index 83e2ec1987b..a4715d4adeb 100644
--- a/src/test/ui/span/unused-warning-point-at-signature.stderr
+++ b/src/test/ui/span/unused-warning-point-at-identifier.stderr
@@ -1,36 +1,31 @@
 warning: enum is never used: `Enum`
-  --> $DIR/unused-warning-point-at-signature.rs:5:1
+  --> $DIR/unused-warning-point-at-identifier.rs:5:6
    |
 LL | enum Enum {
-   | ^^^^^^^^^
+   |      ^^^^
    |
 note: lint level defined here
-  --> $DIR/unused-warning-point-at-signature.rs:3:9
+  --> $DIR/unused-warning-point-at-identifier.rs:3:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
 
 warning: struct is never constructed: `Struct`
-  --> $DIR/unused-warning-point-at-signature.rs:12:1
+  --> $DIR/unused-warning-point-at-identifier.rs:12:8
    |
 LL | struct Struct {
-   | ^^^^^^^^^^^^^
+   |        ^^^^^^
 
 warning: function is never used: `func`
-  --> $DIR/unused-warning-point-at-signature.rs:19:1
+  --> $DIR/unused-warning-point-at-identifier.rs:19:4
    |
 LL | fn func() -> usize {
-   | ^^^^^^^^^^^^^^^^^^
+   |    ^^^^
 
 warning: function is never used: `func_complete_span`
-  --> $DIR/unused-warning-point-at-signature.rs:23:1
+  --> $DIR/unused-warning-point-at-identifier.rs:24:1
    |
-LL | / fn
-LL | | func_complete_span()
-LL | | -> usize
-LL | | {
-LL | |     3
-LL | | }
-   | |_^
+LL | func_complete_span()
+   | ^^^^^^^^^^^^^^^^^^
 
diff --git a/src/test/ui/structs/struct-path-self-type-mismatch.stderr b/src/test/ui/structs/struct-path-self-type-mismatch.stderr
index b905cd1a294..687d610baf8 100644
--- a/src/test/ui/structs/struct-path-self-type-mismatch.stderr
+++ b/src/test/ui/structs/struct-path-self-type-mismatch.stderr
@@ -7,8 +7,13 @@ LL |         Self { inner: 1.5f32 };
 error[E0308]: mismatched types
   --> $DIR/struct-path-self-type-mismatch.rs:15:20
    |
+LL | impl<T> Foo<T> {
+   |      - expected type parameter
+LL |     fn new<U>(u: U) -> Foo<U> {
+   |            - found type parameter
+...
 LL |             inner: u
-   |                    ^ expected type parameter, found a different type parameter
+   |                    ^ expected type parameter `T`, found type parameter `U`
    |
    = note: expected type `T`
               found type `U`
@@ -18,14 +23,18 @@ LL |             inner: u
 error[E0308]: mismatched types
   --> $DIR/struct-path-self-type-mismatch.rs:13:9
    |
+LL |   impl<T> Foo<T> {
+   |        - found type parameter
 LL |       fn new<U>(u: U) -> Foo<U> {
-   |                          ------ expected `Foo<U>` because of return type
+   |              -           ------ expected `Foo<U>` because of return type
+   |              |
+   |              expected type parameter
 LL | /         Self {
 LL | |
 LL | |             inner: u
 LL | |
 LL | |         }
-   | |_________^ expected type parameter, found a different type parameter
+   | |_________^ expected type parameter `U`, found type parameter `T`
    |
    = note: expected type `Foo<U>`
               found type `Foo<T>`
diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr
index 8c88cacc69e..693ed35cbc9 100644
--- a/src/test/ui/structs/struct-path-self.stderr
+++ b/src/test/ui/structs/struct-path-self.stderr
@@ -1,4 +1,4 @@
-error[E0071]: expected struct, variant or union type, found type parameter
+error[E0071]: expected struct, variant or union type, found type parameter `Self`
   --> $DIR/struct-path-self.rs:5:17
    |
 LL |         let s = Self {};
@@ -10,13 +10,13 @@ error[E0109]: type arguments are not allowed for this type
 LL |         let z = Self::<u8> {};
    |                        ^^ type argument not allowed
 
-error[E0071]: expected struct, variant or union type, found type parameter
+error[E0071]: expected struct, variant or union type, found type parameter `Self`
   --> $DIR/struct-path-self.rs:7:17
    |
 LL |         let z = Self::<u8> {};
    |                 ^^^^^^^^^^ not a struct
 
-error[E0071]: expected struct, variant or union type, found type parameter
+error[E0071]: expected struct, variant or union type, found type parameter `Self`
   --> $DIR/struct-path-self.rs:11:13
    |
 LL |             Self { .. } => {}
diff --git a/src/test/ui/suggestions/issue-57672.rs b/src/test/ui/suggestions/issue-57672.rs
index 0881a631f3a..ee999d83ec2 100644
--- a/src/test/ui/suggestions/issue-57672.rs
+++ b/src/test/ui/suggestions/issue-57672.rs
@@ -1,6 +1,6 @@
 // aux-build:foo.rs
 // compile-flags:--extern foo
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 #![deny(unused_extern_crates)]
diff --git a/src/test/ui/suggestions/issue-64252-self-type.stderr b/src/test/ui/suggestions/issue-64252-self-type.stderr
index fa28a0d684e..4abffb1ad79 100644
--- a/src/test/ui/suggestions/issue-64252-self-type.stderr
+++ b/src/test/ui/suggestions/issue-64252-self-type.stderr
@@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `<`
   --> $DIR/issue-64252-self-type.rs:4:15
    |
 LL | pub fn foo(Box<Self>) { }
-   |               ^ expected one of `:`, `@`, or `|` here
+   |               ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a type, explicitly ignore the parameter name
@@ -14,7 +14,7 @@ error: expected one of `:`, `@`, or `|`, found `<`
   --> $DIR/issue-64252-self-type.rs:10:15
    |
 LL |     fn bar(Box<Self>) { }
-   |               ^ expected one of `:`, `@`, or `|` here
+   |               ^ expected one of `:`, `@`, or `|`
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this is a `self` type, give it a parameter name
diff --git a/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs b/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs
index beea951a18a..94c72a31e5e 100644
--- a/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs
+++ b/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs
@@ -1,9 +1,9 @@
 pub fn foo(num: i32) -> i32 {
     let foo: i32::from_be(num);
     //~^ ERROR expected type, found local variable `num`
+    //~| ERROR type arguments are not allowed for this type
     //~| ERROR parenthesized type parameters may only be used with a `Fn` trait
     //~| ERROR ambiguous associated type
-    //~| WARNING this was previously accepted by the compiler but is being phased out
     foo
 }
 
diff --git a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
index a7c784fe827..5353b3a75b2 100644
--- a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
+++ b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
@@ -6,15 +6,20 @@ LL |     let foo: i32::from_be(num);
    |            |
    |            help: use `=` if you meant to assign
 
-error: parenthesized type parameters may only be used with a `Fn` trait
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/let-binding-init-expr-as-ty.rs:2:19
    |
 LL |     let foo: i32::from_be(num);
    |                   ^^^^^^^^^^^^
+   |                   |
+   |                   only `Fn` traits may use parentheses
+   |                   help: use angle brackets instead: `from_be<num>`
+
+error[E0109]: type arguments are not allowed for this type
+  --> $DIR/let-binding-init-expr-as-ty.rs:2:27
    |
-   = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+LL |     let foo: i32::from_be(num);
+   |                           ^^^ type argument not allowed
 
 error[E0223]: ambiguous associated type
   --> $DIR/let-binding-init-expr-as-ty.rs:2:14
@@ -22,7 +27,7 @@ error[E0223]: ambiguous associated type
 LL |     let foo: i32::from_be(num);
    |              ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<i32 as Trait>::from_be`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0223, E0573.
-For more information about an error, try `rustc --explain E0223`.
+Some errors have detailed explanations: E0109, E0214, E0223, E0573.
+For more information about an error, try `rustc --explain E0109`.
diff --git a/src/test/ui/suggestions/missing-trait-item.fixed b/src/test/ui/suggestions/missing-trait-item.fixed
new file mode 100644
index 00000000000..42f579a665e
--- /dev/null
+++ b/src/test/ui/suggestions/missing-trait-item.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+
+trait T {
+    unsafe fn foo(a: &usize, b: &usize) -> usize;
+    fn bar(&self, a: &usize, b: &usize) -> usize;
+}
+
+mod foo {
+    use super::T;
+    impl T for () {    fn bar(&self, _: &usize, _: &usize) -> usize { unimplemented!() }
+        unsafe fn foo(_: &usize, _: &usize) -> usize { unimplemented!() }
+    } //~ ERROR not all trait items
+
+    impl T for usize { //~ ERROR not all trait items
+        fn bar(&self, _: &usize, _: &usize) -> usize { unimplemented!() }
+        unsafe fn foo(_: &usize, _: &usize) -> usize { unimplemented!() }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-trait-item.rs b/src/test/ui/suggestions/missing-trait-item.rs
new file mode 100644
index 00000000000..b4fca25ba2f
--- /dev/null
+++ b/src/test/ui/suggestions/missing-trait-item.rs
@@ -0,0 +1,16 @@
+// run-rustfix
+
+trait T {
+    unsafe fn foo(a: &usize, b: &usize) -> usize;
+    fn bar(&self, a: &usize, b: &usize) -> usize;
+}
+
+mod foo {
+    use super::T;
+    impl T for () {} //~ ERROR not all trait items
+
+    impl T for usize { //~ ERROR not all trait items
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-trait-item.stderr b/src/test/ui/suggestions/missing-trait-item.stderr
new file mode 100644
index 00000000000..4a9d7b472c9
--- /dev/null
+++ b/src/test/ui/suggestions/missing-trait-item.stderr
@@ -0,0 +1,25 @@
+error[E0046]: not all trait items implemented, missing: `foo`, `bar`
+  --> $DIR/missing-trait-item.rs:10:5
+   |
+LL |     unsafe fn foo(a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `foo` from trait
+LL |     fn bar(&self, a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `bar` from trait
+...
+LL |     impl T for () {}
+   |     ^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
+
+error[E0046]: not all trait items implemented, missing: `foo`, `bar`
+  --> $DIR/missing-trait-item.rs:12:5
+   |
+LL |     unsafe fn foo(a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `foo` from trait
+LL |     fn bar(&self, a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `bar` from trait
+...
+LL |     impl T for usize {
+   |     ^^^^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs
new file mode 100644
index 00000000000..220fd1eebda
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.rs
@@ -0,0 +1,5 @@
+fn main() -> Result<(), ()> {
+    vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?;
+    //~^ ERROR expected `::`, found `(`
+    Ok(())
+}
diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
new file mode 100644
index 00000000000..db793c84cf8
--- /dev/null
+++ b/src/test/ui/suggestions/type-ascription-instead-of-path-2.stderr
@@ -0,0 +1,13 @@
+error: expected `::`, found `(`
+  --> $DIR/type-ascription-instead-of-path-2.rs:2:55
+   |
+LL |     vec![Ok(2)].into_iter().collect:<Result<Vec<_>,_>>()?;
+   |                                    -                  ^ expected `::`
+   |                                    |
+   |                                    help: maybe write a path separator here: `::`
+   |
+   = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`
+   = note: for more information, see https://github.com/rust-lang/rust/issues/23416
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/test-attrs/test-on-macro.rs b/src/test/ui/test-attrs/test-on-macro.rs
index a238db6d716..0667364d13c 100644
--- a/src/test/ui/test-attrs/test-on-macro.rs
+++ b/src/test/ui/test-attrs/test-on-macro.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags:--test
 
 #![deny(warnings)]
@@ -8,6 +8,6 @@ macro_rules! foo {
 }
 
 #[test]
-foo!();
+foo!(); //~ WARNING `#[test]` attribute should not be used on macros
 
 fn main(){}
diff --git a/src/test/ui/test-attrs/test-warns-dead-code.stderr b/src/test/ui/test-attrs/test-warns-dead-code.stderr
index 62e99225dd9..cb118cdb410 100644
--- a/src/test/ui/test-attrs/test-warns-dead-code.stderr
+++ b/src/test/ui/test-attrs/test-warns-dead-code.stderr
@@ -1,8 +1,8 @@
 error: function is never used: `dead`
-  --> $DIR/test-warns-dead-code.rs:5:1
+  --> $DIR/test-warns-dead-code.rs:5:4
    |
 LL | fn dead() {}
-   | ^^^^^^^^^
+   |    ^^^^
    |
 note: lint level defined here
   --> $DIR/test-warns-dead-code.rs:3:9
diff --git a/src/test/ui/thread-local-not-in-prelude.rs b/src/test/ui/thread-local-not-in-prelude.rs
index 03974982625..e5ed09c600b 100644
--- a/src/test/ui/thread-local-not-in-prelude.rs
+++ b/src/test/ui/thread-local-not-in-prelude.rs
@@ -1,5 +1,4 @@
 // run-pass
-
 #![no_std]
 
 extern crate std;
diff --git a/src/test/ui/traits/trait-suggest-where-clause.rs b/src/test/ui/traits/trait-suggest-where-clause.rs
index 5ed14a6a866..5d3464d20f3 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.rs
+++ b/src/test/ui/traits/trait-suggest-where-clause.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::mem;
 
 struct Misc<T:?Sized>(T);
diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr
index f1004ea9dc6..2bb7defdac7 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.stderr
+++ b/src/test/ui/traits/trait-suggest-where-clause.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:9:20
+  --> $DIR/trait-suggest-where-clause.rs:8:20
    |
 LL | fn check<T: Iterator, U: ?Sized>() {
    |                       -- help: consider further restricting this bound: `U: std::marker::Sized +`
@@ -16,7 +16,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:12:5
+  --> $DIR/trait-suggest-where-clause.rs:11:5
    |
 LL | fn check<T: Iterator, U: ?Sized>() {
    |                       -- help: consider further restricting this bound: `U: std::marker::Sized +`
@@ -34,7 +34,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: required because it appears within the type `Misc<U>`
 
 error[E0277]: the trait bound `u64: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:17:5
+  --> $DIR/trait-suggest-where-clause.rs:16:5
    |
 LL |     <u64 as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `u64`
@@ -42,7 +42,7 @@ LL |     <u64 as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `u64: std::convert::From<<T as std::iter::Iterator>::Item>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:20:5
+  --> $DIR/trait-suggest-where-clause.rs:19:5
    |
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<<T as std::iter::Iterator>::Item>` is not implemented for `u64`
@@ -50,7 +50,7 @@ LL |     <u64 as From<<T as Iterator>::Item>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `Misc<_>: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:25:5
+  --> $DIR/trait-suggest-where-clause.rs:24:5
    |
 LL |     <Misc<_> as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `Misc<_>`
@@ -58,7 +58,7 @@ LL |     <Misc<_> as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:30:20
+  --> $DIR/trait-suggest-where-clause.rs:29:20
    |
 LL |     mem::size_of::<[T]>();
    |                    ^^^ doesn't have a size known at compile-time
@@ -72,7 +72,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `[&U]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:33:5
+  --> $DIR/trait-suggest-where-clause.rs:32:5
    |
 LL |     mem::size_of::<[&U]>();
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/traits/traits-issue-23003-overflow.rs b/src/test/ui/traits/traits-issue-23003-overflow.rs
index 5538e0303ed..c5f471f23c2 100644
--- a/src/test/ui/traits/traits-issue-23003-overflow.rs
+++ b/src/test/ui/traits/traits-issue-23003-overflow.rs
@@ -2,7 +2,7 @@
 // types are required. This test now just compiles fine, since the
 // relevant rules that triggered the overflow were removed.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 use std::marker::PhantomData;
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
index bdbd64140f0..3416503b851 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
@@ -1,26 +1,26 @@
-// run-pass
+// check-pass
 // Check tautalogically false `Copy` bounds
 #![feature(trivial_bounds)]
-#![allow(unused)]
 
-fn copy_string(t: String) -> String where String: Copy {
+fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds
     is_copy(&t);
     let x = t;
     drop(t);
     t
 }
 
-fn copy_out_string(t: &String) -> String where String: Copy {
+fn copy_out_string(t: &String) -> String where String: Copy { //~ WARNING trivial_bounds
     *t
 }
 
-fn copy_string_with_param<T>(x: String) where String: Copy {
+fn copy_string_with_param<T>(x: String) where String: Copy { //~ WARNING trivial_bounds
     let y = x;
     let z = x;
 }
 
 // Check that no reborrowing occurs
 fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
+    //~^ WARNING trivial_bounds
     is_copy(t);
     let x = *t;
     drop(x);
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
index af0bad80690..17389a87313 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
@@ -1,5 +1,5 @@
 warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:6:51
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:5:51
    |
 LL | fn copy_string(t: String) -> String where String: Copy {
    |                                                   ^^^^
@@ -7,19 +7,19 @@ LL | fn copy_string(t: String) -> String where String: Copy {
    = note: `#[warn(trivial_bounds)]` on by default
 
 warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:13:56
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:12:56
    |
 LL | fn copy_out_string(t: &String) -> String where String: Copy {
    |                                                        ^^^^
 
 warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:17:55
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:16:55
    |
 LL | fn copy_string_with_param<T>(x: String) where String: Copy {
    |                                                       ^^^^
 
 warning: Trait bound for<'b> &'b mut i32: std::marker::Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:23:76
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:22:76
    |
 LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
    |                                                                            ^^^^
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs
index fa2daeb11e9..b13956673d2 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs
@@ -18,21 +18,21 @@ impl A for B {
 
 fn underspecified_bound() -> u8
 where
-    B: A
+    B: A //~ WARNING trivial_bounds
 {
     B::get_x()
 }
 
 fn inconsistent_bound() -> i32
 where
-    B: A<X = i32>
+    B: A<X = i32> //~ WARNING trivial_bounds
 {
     B::get_x()
 }
 
 fn redundant_bound() -> u8
 where
-    B: A<X = u8>
+    B: A<X = u8> //~ WARNING trivial_bounds
 {
     B::get_x()
 }
@@ -40,6 +40,8 @@ where
 fn inconsistent_dup_bound() -> i32
 where
     B: A<X = i32> + A
+    //~^ WARNING trivial_bounds
+    //~| WARNING trivial_bounds
 {
     B::get_x()
 }
@@ -47,6 +49,8 @@ where
 fn redundant_dup_bound() -> u8
 where
     B: A<X = u8> + A
+    //~^ WARNING trivial_bounds
+    //~| WARNING trivial_bounds
 {
     B::get_x()
 }
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr
index f2aa482f6de..dc685cbf6b3 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr
@@ -31,13 +31,13 @@ LL |     B: A<X = i32> + A
    |                     ^
 
 warning: Trait bound B: A does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-projection.rs:49:8
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:51:8
    |
 LL |     B: A<X = u8> + A
    |        ^^^^^^^^^
 
 warning: Trait bound B: A does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-projection.rs:49:20
+  --> $DIR/trivial-bounds-inconsistent-projection.rs:51:20
    |
 LL |     B: A<X = u8> + A
    |                    ^
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs
index d411807673c..bfa083655c4 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.rs
@@ -12,12 +12,15 @@ struct T<X: ?Sized> {
 }
 
 struct S(str, str) where str: Sized;
+//~^ WARNING Sized does not depend on any type or lifetime
 
 fn unsized_local() where for<'a> T<dyn A + 'a>: Sized {
+    //~^ WARNING Sized does not depend on any type or lifetime
     let x: T<dyn A> = *(Box::new(T { x: 1 }) as Box<T<dyn A>>);
 }
 
 fn return_str() -> str where str: Sized {
+    //~^ WARNING Sized does not depend on any type or lifetime
     *"Sized".to_string().into_boxed_str()
 }
 
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr
index a80ebc173f0..d4fa698c737 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr
@@ -7,13 +7,13 @@ LL | struct S(str, str) where str: Sized;
    = note: `#[warn(trivial_bounds)]` on by default
 
 warning: Trait bound for<'a> T<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-sized.rs:16:49
+  --> $DIR/trivial-bounds-inconsistent-sized.rs:17:49
    |
 LL | fn unsized_local() where for<'a> T<dyn A + 'a>: Sized {
    |                                                 ^^^^^
 
 warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-sized.rs:20:35
+  --> $DIR/trivial-bounds-inconsistent-sized.rs:22:35
    |
 LL | fn return_str() -> str where str: Sized {
    |                                   ^^^^^
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs
index cab2423d25d..9efa22b1071 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.rs
@@ -5,6 +5,8 @@
 use std::fmt::Debug;
 
 pub fn foo() where Vec<str>: Debug, str: Copy {
+    //~^ WARNING Debug does not depend on any type or lifetime
+    //~| WARNING Copy does not depend on any type or lifetime
     let x = vec![*"1"];
     println!("{:?}", x);
 }
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs
index f6538b14d17..7148f5d6da0 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.rs
@@ -11,17 +11,19 @@ pub trait Foo {
 
 fn generic_function<X: Foo>(x: X) {}
 
-enum E where i32: Foo { V }
+enum E where i32: Foo { V } //~ WARNING trivial_bounds
 
-struct S where i32: Foo;
+struct S where i32: Foo; //~ WARNING trivial_bounds
 
-trait T where i32: Foo {}
+trait T where i32: Foo {} //~ WARNING trivial_bounds
 
-union U where i32: Foo { f: i32 }
+union U where i32: Foo { f: i32 } //~ WARNING trivial_bounds
 
 type Y where i32: Foo = ();
+//~^ WARNING type_alias_bounds
+//~| WARNING trivial_bounds
 
-impl Foo for () where i32: Foo {
+impl Foo for () where i32: Foo { //~ WARNING trivial_bounds
     fn test(&self) {
         3i32.test();
         Foo::test(&4i32);
@@ -29,14 +31,14 @@ impl Foo for () where i32: Foo {
     }
 }
 
-fn f() where i32: Foo {
+fn f() where i32: Foo { //~ WARNING trivial_bounds
     let s = S;
     3i32.test();
     Foo::test(&4i32);
     generic_function(5i32);
 }
 
-fn g() where &'static str: Foo {
+fn g() where &'static str: Foo { //~ WARNING trivial_bounds
     "Foo".test();
     Foo::test(&"Foo");
     generic_function("Foo");
@@ -50,21 +52,22 @@ struct Dst<X: ?Sized> {
     x: X,
 }
 
-struct TwoStrs(str, str) where str: Sized;
+struct TwoStrs(str, str) where str: Sized; //~ WARNING trivial_bounds
 
-fn unsized_local() where for<'a> Dst<dyn A + 'a>: Sized {
+fn unsized_local() where for<'a> Dst<dyn A + 'a>: Sized { //~ WARNING trivial_bounds
     let x: Dst<dyn A> = *(Box::new(Dst { x: 1 }) as Box<Dst<dyn A>>);
 }
 
-fn return_str() -> str where str: Sized {
+fn return_str() -> str where str: Sized { //~ WARNING trivial_bounds
     *"Sized".to_string().into_boxed_str()
 }
 
 fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
+    //~^ WARNING trivial_bounds
     -s
 }
 
-fn use_for() where i32: Iterator {
+fn use_for() where i32: Iterator { //~ WARNING trivial_bounds
     for _ in 2i32 {}
 }
 
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
index cb8bad6d9e7..156d38e3df5 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr
@@ -43,49 +43,49 @@ LL | type Y where i32: Foo = ();
    |                   ^^^
 
 warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:24:28
+  --> $DIR/trivial-bounds-inconsistent.rs:26:28
    |
 LL | impl Foo for () where i32: Foo {
    |                            ^^^
 
 warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:32:19
+  --> $DIR/trivial-bounds-inconsistent.rs:34:19
    |
 LL | fn f() where i32: Foo {
    |                   ^^^
 
 warning: Trait bound &'static str: Foo does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:39:28
+  --> $DIR/trivial-bounds-inconsistent.rs:41:28
    |
 LL | fn g() where &'static str: Foo {
    |                            ^^^
 
 warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:53:37
+  --> $DIR/trivial-bounds-inconsistent.rs:55:37
    |
 LL | struct TwoStrs(str, str) where str: Sized;
    |                                     ^^^^^
 
 warning: Trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:55:51
+  --> $DIR/trivial-bounds-inconsistent.rs:57:51
    |
 LL | fn unsized_local() where for<'a> Dst<dyn A + 'a>: Sized {
    |                                                   ^^^^^
 
 warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:59:35
+  --> $DIR/trivial-bounds-inconsistent.rs:61:35
    |
 LL | fn return_str() -> str where str: Sized {
    |                                   ^^^^^
 
 warning: Trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:63:46
+  --> $DIR/trivial-bounds-inconsistent.rs:65:46
    |
 LL | fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: Trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent.rs:67:25
+  --> $DIR/trivial-bounds-inconsistent.rs:70:25
    |
 LL | fn use_for() where i32: Iterator {
    |                         ^^^^^^^^
diff --git a/src/test/ui/try-block/try-block-unreachable-code-lint.rs b/src/test/ui/try-block/try-block-unreachable-code-lint.rs
index 5a9f662d229..e1d82ea360d 100644
--- a/src/test/ui/try-block/try-block-unreachable-code-lint.rs
+++ b/src/test/ui/try-block/try-block-unreachable-code-lint.rs
@@ -43,14 +43,14 @@ fn test_try_block_after_divergent_stmt() {
                 err()?;
             }
         }
-        // ~^^^^^ WARNING unreachable expression
+        //~^^^^^ WARNING unreachable expression
     };
 }
 
 fn test_wrapped_divergent_expr() {
     let _: Result<u32, ()> = {
         Err(return)
-        // ~^ WARNING unreachable call
+        //~^ WARNING unreachable call
     };
 }
 
@@ -61,7 +61,7 @@ fn test_expr_after_divergent_stmt_in_try_block() {
         }
 
         42
-        // ~^ WARNING unreachable expression
+        //~^ WARNING unreachable expression
     };
     println!("res: {:?}", res);
 }
diff --git a/src/test/ui/tuple/tuple-struct-fields/test.stderr b/src/test/ui/tuple/tuple-struct-fields/test.stderr
index 295f0b146dd..94f39f3b9f1 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test.stderr
@@ -2,7 +2,7 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test.rs:4:26
    |
 LL |     struct S2(pub((foo)) ());
-   |                          ^ expected one of `)` or `,` here
+   |                          ^ expected one of `)` or `,`
 
 error[E0412]: cannot find type `foo` in this scope
   --> $DIR/test.rs:4:20
diff --git a/src/test/ui/tuple/tuple-struct-fields/test2.stderr b/src/test/ui/tuple/tuple-struct-fields/test2.stderr
index 78176c67ed2..9a64ed97ae1 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test2.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test2.stderr
@@ -2,7 +2,7 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test2.rs:5:26
    |
 LL |         struct S3(pub $t ());
-   |                          ^ expected one of `)` or `,` here
+   |                          ^ expected one of `)` or `,`
 ...
 LL |     define_struct! { (foo) }
    |     ------------------------ in this macro invocation
diff --git a/src/test/ui/tuple/tuple-struct-fields/test3.stderr b/src/test/ui/tuple/tuple-struct-fields/test3.stderr
index e105aad09e6..89ae784882d 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test3.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test3.stderr
@@ -2,7 +2,7 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test3.rs:5:27
    |
 LL |         struct S3(pub($t) ());
-   |                           ^ expected one of `)` or `,` here
+   |                           ^ expected one of `)` or `,`
 ...
 LL |     define_struct! { foo }
    |     ---------------------- in this macro invocation
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index a0a617fdbbc..9e44e208f0e 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -1,8 +1,11 @@
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:13:25
    |
+LL | impl<T> Enum<T> {
+   |      - this type parameter
+LL |     fn ts_variant() {
 LL |         Self::TSVariant(());
-   |                         ^^ expected type parameter, found ()
+   |                         ^^ expected type parameter `T`, found ()
    |
    = note: expected type `T`
               found type `()`
@@ -24,8 +27,11 @@ LL |         Self::<()>::TSVariant(());
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:17:31
    |
+LL | impl<T> Enum<T> {
+   |      - this type parameter
+...
 LL |         Self::<()>::TSVariant(());
-   |                               ^^ expected type parameter, found ()
+   |                               ^^ expected type parameter `T`, found ()
    |
    = note: expected type `T`
               found type `()`
@@ -47,8 +53,11 @@ LL |         Self::<()>::TSVariant::<()>(());
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:26:29
    |
+LL | impl<T> Enum<T> {
+   |      - this type parameter
+...
 LL |         Self::SVariant { v: () };
-   |                             ^^ expected type parameter, found ()
+   |                             ^^ expected type parameter `T`, found ()
    |
    = note: expected type `T`
               found type `()`
@@ -64,8 +73,11 @@ LL |         Self::SVariant::<()> { v: () };
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:28:35
    |
+LL | impl<T> Enum<T> {
+   |      - this type parameter
+...
 LL |         Self::SVariant::<()> { v: () };
-   |                                   ^^ expected type parameter, found ()
+   |                                   ^^ expected type parameter `T`, found ()
    |
    = note: expected type `T`
               found type `()`
@@ -81,8 +93,11 @@ LL |         Self::<()>::SVariant { v: () };
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:31:35
    |
+LL | impl<T> Enum<T> {
+   |      - this type parameter
+...
 LL |         Self::<()>::SVariant { v: () };
-   |                                   ^^ expected type parameter, found ()
+   |                                   ^^ expected type parameter `T`, found ()
    |
    = note: expected type `T`
               found type `()`
@@ -104,8 +119,11 @@ LL |         Self::<()>::SVariant::<()> { v: () };
 error[E0308]: mismatched types
   --> $DIR/enum-variant-generic-args.rs:34:41
    |
+LL | impl<T> Enum<T> {
+   |      - this type parameter
+...
 LL |         Self::<()>::SVariant::<()> { v: () };
-   |                                         ^^ expected type parameter, found ()
+   |                                         ^^ expected type parameter `T`, found ()
    |
    = note: expected type `T`
               found type `()`
diff --git a/src/test/ui/type-alias-enum-variants/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs
index 058b58e174c..5e105b20a89 100644
--- a/src/test/ui/type-alias-enum-variants/issue-57866.rs
+++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 enum Outer<T> {
     A(T)
diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
index bff04daed0d..9c9eaab8da3 100644
--- a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
+++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
@@ -1,7 +1,7 @@
 // In this regression test we check that a path pattern referring to a unit variant
 // through a type alias is successful in inferring the generic argument.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 enum Opt<T> {
     N,
diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs
index c21d9f3d97c..c0d39c59014 100644
--- a/src/test/ui/type/ascription/issue-34255-1.rs
+++ b/src/test/ui/type/ascription/issue-34255-1.rs
@@ -8,7 +8,6 @@ impl Reactor {
         //~^ ERROR cannot find value `input_cells` in this scope
         //~| ERROR parenthesized type parameters may only be used with a `Fn` trait
         //~| ERROR wrong number of type arguments: expected 1, found 0
-        //~| WARNING this was previously accepted by the compiler but is being phased out
     }
 }
 
diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr
index 0d0acfde886..7895cf77fc0 100644
--- a/src/test/ui/type/ascription/issue-34255-1.stderr
+++ b/src/test/ui/type/ascription/issue-34255-1.stderr
@@ -4,15 +4,11 @@ error[E0425]: cannot find value `input_cells` in this scope
 LL |         input_cells: Vec::new()
    |         ^^^^^^^^^^^ a field by this name exists in `Self`
 
-error: parenthesized type parameters may only be used with a `Fn` trait
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/issue-34255-1.rs:7:27
    |
 LL |         input_cells: Vec::new()
-   |                           ^^^^^
-   |
-   = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
+   |                           ^^^^^ only `Fn` traits may use parentheses
 
 error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/issue-34255-1.rs:7:22
@@ -22,5 +18,5 @@ LL |         input_cells: Vec::new()
 
 error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0107, E0425.
+Some errors have detailed explanations: E0107, E0214, E0425.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr
index 97942904a0f..47e3c78459d 100644
--- a/src/test/ui/type/ascription/issue-54516.stderr
+++ b/src/test/ui/type/ascription/issue-54516.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `,`, or `::`, found `(`
   --> $DIR/issue-54516.rs:4:58
    |
 LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-   |                            -                             ^ expected one of `!`, `,`, or `::` here
+   |                            -                             ^ expected one of `!`, `,`, or `::`
    |                            |
    |                            help: maybe write a path separator here: `::`
    |
diff --git a/src/test/ui/type/ascription/issue-60933.stderr b/src/test/ui/type/ascription/issue-60933.stderr
index c2fc7bbcfc8..c47042bbe59 100644
--- a/src/test/ui/type/ascription/issue-60933.stderr
+++ b/src/test/ui/type/ascription/issue-60933.stderr
@@ -2,7 +2,7 @@ error: expected one of `!`, `::`, or `;`, found `(`
   --> $DIR/issue-60933.rs:2:43
    |
 LL |     let u: usize = std::mem:size_of::<u32>();
-   |                            -              ^ expected one of `!`, `::`, or `;` here
+   |                            -              ^ expected one of `!`, `::`, or `;`
    |                            |
    |                            help: maybe write a path separator here: `::`
    |
diff --git a/src/test/ui/type/type-error-break-tail.rs b/src/test/ui/type/type-error-break-tail.rs
new file mode 100644
index 00000000000..d4e3e93d06b
--- /dev/null
+++ b/src/test/ui/type/type-error-break-tail.rs
@@ -0,0 +1,8 @@
+fn loop_ending() -> i32 {
+    loop {
+        if false { break; } //~ ERROR mismatched types
+        return 42;
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type/type-error-break-tail.stderr b/src/test/ui/type/type-error-break-tail.stderr
new file mode 100644
index 00000000000..e5297d9a596
--- /dev/null
+++ b/src/test/ui/type/type-error-break-tail.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/type-error-break-tail.rs:3:20
+   |
+LL | fn loop_ending() -> i32 {
+   |                     --- expected `i32` because of return type
+LL |     loop {
+LL |         if false { break; }
+   |                    ^^^^^
+   |                    |
+   |                    expected i32, found ()
+   |                    help: give it a value of the expected type: `break 42`
+   |
+   = note: expected type `i32`
+              found type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type/type-parameter-names.rs b/src/test/ui/type/type-parameter-names.rs
index b6b3795d09b..82576646345 100644
--- a/src/test/ui/type/type-parameter-names.rs
+++ b/src/test/ui/type/type-parameter-names.rs
@@ -6,7 +6,7 @@ fn foo<Foo, Bar>(x: Foo) -> Bar {
 //~^ ERROR mismatched types
 //~| expected type `Bar`
 //~| found type `Foo`
-//~| expected type parameter, found a different type parameter
+//~| expected type parameter `Bar`, found type parameter `Foo`
 }
 
 fn main() {}
diff --git a/src/test/ui/type/type-parameter-names.stderr b/src/test/ui/type/type-parameter-names.stderr
index 3397eec9e05..78d6989a336 100644
--- a/src/test/ui/type/type-parameter-names.stderr
+++ b/src/test/ui/type/type-parameter-names.stderr
@@ -2,9 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/type-parameter-names.rs:5:5
    |
 LL | fn foo<Foo, Bar>(x: Foo) -> Bar {
-   |                             --- expected `Bar` because of return type
+   |        ---  ---             --- expected `Bar` because of return type
+   |        |    |
+   |        |    expected type parameter
+   |        found type parameter
 LL |     x
-   |     ^ expected type parameter, found a different type parameter
+   |     ^ expected type parameter `Bar`, found type parameter `Foo`
    |
    = note: expected type `Bar`
               found type `Foo`
diff --git a/src/test/ui/type/type-params-in-different-spaces-1.rs b/src/test/ui/type/type-params-in-different-spaces-1.rs
index 71fb7f380ae..d2dce7006b7 100644
--- a/src/test/ui/type/type-params-in-different-spaces-1.rs
+++ b/src/test/ui/type/type-params-in-different-spaces-1.rs
@@ -5,7 +5,7 @@ trait BrokenAdd: Copy + Add<Output=Self> {
         *self + rhs //~  ERROR mismatched types
                     //~| expected type `Self`
                     //~| found type `T`
-                    //~| expected type parameter, found a different type parameter
+                    //~| expected type parameter `Self`, found type parameter `T`
     }
 }
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr
index a10bf4e0b77..d2c6b7304ff 100644
--- a/src/test/ui/type/type-params-in-different-spaces-1.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr
@@ -1,8 +1,16 @@
 error[E0308]: mismatched types
   --> $DIR/type-params-in-different-spaces-1.rs:5:17
    |
-LL |         *self + rhs
-   |                 ^^^ expected type parameter, found a different type parameter
+LL | / trait BrokenAdd: Copy + Add<Output=Self> {
+LL | |     fn broken_add<T>(&self, rhs: T) -> Self {
+   | |                   - found type parameter
+LL | |         *self + rhs
+   | |                 ^^^ expected type parameter `Self`, found type parameter `T`
+LL | |
+...  |
+LL | |     }
+LL | | }
+   | |_- expected type parameter
    |
    = note: expected type `Self`
               found type `T`
diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr
index 9f0fa5a0ea1..ec5d6372792 100644
--- a/src/test/ui/type/type-params-in-different-spaces-3.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr
@@ -1,10 +1,16 @@
 error[E0308]: mismatched types
   --> $DIR/type-params-in-different-spaces-3.rs:3:9
    |
-LL |     fn test<X>(u: X) -> Self {
-   |                         ---- expected `Self` because of return type
-LL |         u
-   |         ^ expected type parameter, found a different type parameter
+LL | / trait Tr : Sized {
+LL | |     fn test<X>(u: X) -> Self {
+   | |             -           ---- expected `Self` because of return type
+   | |             |
+   | |             found type parameter
+LL | |         u
+   | |         ^ expected type parameter `Self`, found type parameter `X`
+LL | |     }
+LL | | }
+   | |_- expected type parameter
    |
    = note: expected type `Self`
               found type `X`
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index cd15f81a615..926f12911c5 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -1,5 +1,4 @@
-// ignore-musl
-// ignore-x86
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // error-pattern: reached the type-length limit while instantiating
 
 // Test that the type length limit can be changed.
diff --git a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
index 710b7c9bbee..23ea0ad61a7 100644
--- a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
+++ b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#55810: types for a binding in a match arm can be
 // inferred from arms that come later in the match.
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index a49344e45ce..7af6075262c 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -30,11 +30,11 @@ LL |     let _ = match x {};
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0004]: non-exhaustive patterns: `&[_]` not covered
+error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
   --> $DIR/uninhabited-matches-feature-gated.rs:21:19
    |
 LL |     let _ = match x {
-   |                   ^ pattern `&[_]` not covered
+   |                   ^ pattern `&[_, ..]` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/dead-code-ret.rs b/src/test/ui/unreachable-code-ret.rs
index fad35794fae..fad35794fae 100644
--- a/src/test/ui/dead-code-ret.rs
+++ b/src/test/ui/unreachable-code-ret.rs
diff --git a/src/test/ui/dead-code-ret.stderr b/src/test/ui/unreachable-code-ret.stderr
index 83841131599..c22342ce721 100644
--- a/src/test/ui/dead-code-ret.stderr
+++ b/src/test/ui/unreachable-code-ret.stderr
@@ -1,5 +1,5 @@
 error: unreachable statement
-  --> $DIR/dead-code-ret.rs:7:5
+  --> $DIR/unreachable-code-ret.rs:7:5
    |
 LL |     return;
    |     ------ any code following this expression is unreachable
@@ -7,7 +7,7 @@ LL |     println!("Paul is dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
-  --> $DIR/dead-code-ret.rs:3:9
+  --> $DIR/unreachable-code-ret.rs:3:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/unsafe/unsafe-block-without-braces.stderr b/src/test/ui/unsafe/unsafe-block-without-braces.stderr
index 34a90352e92..637fdeead36 100644
--- a/src/test/ui/unsafe/unsafe-block-without-braces.stderr
+++ b/src/test/ui/unsafe/unsafe-block-without-braces.stderr
@@ -2,7 +2,7 @@ error: expected one of `extern`, `fn`, or `{`, found `std`
   --> $DIR/unsafe-block-without-braces.rs:3:9
    |
 LL |     unsafe //{
-   |           - expected one of `extern`, `fn`, or `{` here
+   |           - expected one of `extern`, `fn`, or `{`
 LL |         std::mem::transmute::<f32, u32>(1.0);
    |         ^^^ unexpected token
 
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index c364479d8db..0bbbabd2998 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -7,3 +7,4 @@ edition = "2018"
 [dependencies]
 toml = "0.5"
 serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index fca57eec79f..d92924085e7 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -11,10 +11,11 @@ use serde::Serialize;
 
 use std::collections::BTreeMap;
 use std::env;
-use std::fs;
+use std::fs::{self, File};
 use std::io::{self, Read, Write};
 use std::path::{PathBuf, Path};
 use std::process::{Command, Stdio};
+use std::collections::HashMap;
 
 static HOSTS: &[&str] = &[
     "aarch64-unknown-linux-gnu",
@@ -366,6 +367,7 @@ impl Builder {
         self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
         self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
 
+        self.check_toolstate();
         self.digest_and_sign();
         let manifest = self.build_manifest();
         self.write_channel_files(&self.rust_release, &manifest);
@@ -375,6 +377,25 @@ impl Builder {
         }
     }
 
+    /// If a tool does not pass its tests, don't ship it.
+    /// Right now, we do this only for Miri.
+    fn check_toolstate(&mut self) {
+        let toolstates: Option<HashMap<String, String>> =
+            File::open(self.input.join("toolstates-linux.json")).ok()
+                .and_then(|f| serde_json::from_reader(&f).ok());
+        let toolstates = toolstates.unwrap_or_else(|| {
+            println!("WARNING: `toolstates-linux.json` missing/malformed; \
+                assuming all tools failed");
+            HashMap::default() // Use empty map if anything went wrong.
+        });
+        // Mark some tools as missing based on toolstate.
+        if toolstates.get("miri").map(|s| &*s as &str) != Some("test-pass") {
+            println!("Miri tests are not passing, removing component");
+            self.miri_version = None;
+            self.miri_git_commit_hash = None;
+        }
+    }
+
     /// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
     fn digest_and_sign(&mut self) {
         for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject c8e3cfbdd997839c771ca32c7ac860fe95149a0
+Subproject 86b8643586aa39f36fb7a02e98c8d64d31415e7
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index a9acc9733c1..28b6d2c1d01 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3148,11 +3148,20 @@ impl<'test> TestCx<'test> {
                explicit, self.config.compare_mode, expected_errors, proc_res.status,
                self.props.error_patterns);
         if !explicit && self.config.compare_mode.is_none() {
-            if !self.should_run() && !self.props.error_patterns.is_empty() {
+            let check_patterns =
+                !self.should_run() &&
+                !self.props.error_patterns.is_empty();
+
+            let check_annotations =
+                !check_patterns ||
+                !expected_errors.is_empty();
+
+            if check_patterns {
                 // "// error-pattern" comments
                 self.check_error_patterns(&proc_res.stderr, &proc_res);
             }
-            if !expected_errors.is_empty() {
+
+            if check_annotations {
                 // "//~ERROR comments"
                 self.check_expected_errors(expected_errors, &proc_res);
             }
diff --git a/src/tools/miri b/src/tools/miri
-Subproject d4e4fe71e6a9568f5d081d99f1c621c5a4ddd7d
+Subproject 8355437d5d0e747b7e7239cd0a2af8a3825bd91
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 93029099686..5abe481368d 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -160,6 +160,8 @@ pub fn check(path: &Path, bad: &mut bool) {
         let can_contain = contents.contains("// ignore-tidy-") ||
             contents.contains("# ignore-tidy-");
         let mut skip_cr = contains_ignore_directive(can_contain, &contents, "cr");
+        let mut skip_undocumented_unsafe =
+            contains_ignore_directive(can_contain, &contents, "undocumented-unsafe");
         let mut skip_tab = contains_ignore_directive(can_contain, &contents, "tab");
         let mut skip_line_length = contains_ignore_directive(can_contain, &contents, "linelength");
         let mut skip_file_length = contains_ignore_directive(can_contain, &contents, "filelength");
@@ -171,6 +173,7 @@ pub fn check(path: &Path, bad: &mut bool) {
         let mut leading_new_lines = false;
         let mut trailing_new_lines = 0;
         let mut lines = 0;
+        let mut last_safety_comment = false;
         for (i, line) in contents.split('\n').enumerate() {
             let mut err = |msg: &str| {
                 tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
@@ -200,6 +203,20 @@ pub fn check(path: &Path, bad: &mut bool) {
                     err("XXX is deprecated; use FIXME")
                 }
             }
+            let is_test = || file.components().any(|c| c.as_os_str() == "tests");
+            // for now we just check libcore
+            if line.contains("unsafe {") && !line.trim().starts_with("//") && !last_safety_comment {
+                if file.components().any(|c| c.as_os_str() == "libcore") && !is_test() {
+                    suppressible_tidy_err!(err, skip_undocumented_unsafe, "undocumented unsafe");
+                }
+            }
+            if line.contains("// SAFETY: ") || line.contains("// Safety: ") {
+                last_safety_comment = true;
+            } else if line.trim().starts_with("//") || line.trim().is_empty() {
+                // keep previous value
+            } else {
+                last_safety_comment = false;
+            }
             if (line.starts_with("// Copyright") ||
                 line.starts_with("# Copyright") ||
                 line.starts_with("Copyright"))