about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArtyom Pavlov <newpavlov@gmail.com>2019-08-24 22:50:20 +0000
committerGitHub <noreply@github.com>2019-08-24 22:50:20 +0000
commit37721461d47d3840adc6d931b848a9db8e66ceaa (patch)
tree4424a43dce056c6000de36eacc524cceccd822c9
parent926f36400f1667edec92959d8b640dea5084674c (diff)
parenteeba189cfb2cfc5c5898513352d4ca8f1df06e05 (diff)
downloadrust-37721461d47d3840adc6d931b848a9db8e66ceaa.tar.gz
rust-37721461d47d3840adc6d931b848a9db8e66ceaa.zip
Merge branch 'master' into wasi
-rw-r--r--.gitattributes2
-rw-r--r--.mailmap3
-rw-r--r--Cargo.lock127
-rw-r--r--Cargo.toml1
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/builder.rs45
-rw-r--r--src/bootstrap/builder/tests.rs153
-rw-r--r--src/bootstrap/check.rs55
-rw-r--r--src/bootstrap/compile.rs139
-rw-r--r--src/bootstrap/dist.rs21
-rw-r--r--src/bootstrap/doc.rs131
-rw-r--r--src/bootstrap/lib.rs7
-rw-r--r--src/bootstrap/test.rs39
-rw-r--r--src/bootstrap/tool.rs39
-rw-r--r--src/build_helper/lib.rs2
-rw-r--r--src/ci/docker/dist-various-1/Dockerfile6
-rwxr-xr-xsrc/ci/docker/dist-various-1/install-mipsel-musl.sh2
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-guide0
-rw-r--r--src/doc/rustc/src/command-line-arguments.md7
-rw-r--r--src/doc/rustc/src/lints/listing/allowed-by-default.md2
-rw-r--r--src/liballoc/collections/vec_deque.rs4
-rw-r--r--src/libcore/cmp.rs8
-rw-r--r--src/libcore/iter/adapters/chain.rs22
-rw-r--r--src/libcore/iter/adapters/mod.rs4
-rw-r--r--src/libcore/macros.rs8
-rw-r--r--src/libcore/num/f32.rs2
-rw-r--r--src/libcore/num/f64.rs2
-rw-r--r--src/libcore/slice/mod.rs19
-rw-r--r--src/libcore/tests/iter.rs48
-rw-r--r--src/libcore/tests/slice.rs19
-rw-r--r--src/libproc_macro/Cargo.toml3
-rw-r--r--src/librustc/error_codes.rs2
-rw-r--r--src/librustc/hir/map/mod.rs15
-rw-r--r--src/librustc/ich/impls_syntax.rs1
-rw-r--r--src/librustc/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc/ty/error.rs22
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs20
-rw-r--r--src/librustc/ty/relate.rs24
-rw-r--r--src/librustc/ty/sty.rs24
-rw-r--r--src/librustc_driver/Cargo.toml1
-rw-r--r--src/librustc_driver/args.rs53
-rw-r--r--src/librustc_driver/lib.rs37
-rw-r--r--src/librustc_metadata/cstore.rs8
-rw-r--r--src/librustc_metadata/decoder.rs35
-rw-r--r--src/librustc_metadata/encoder.rs391
-rw-r--r--src/librustc_metadata/index.rs10
-rw-r--r--src/librustc_metadata/schema.rs153
-rw-r--r--src/librustc_passes/error_codes.rs2
-rw-r--r--src/librustc_passes/loops.rs37
-rw-r--r--src/librustc_plugin/deprecated/lib.rs2
-rw-r--r--src/librustc_privacy/lib.rs20
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/lib.rs12
-rw-r--r--src/librustc_resolve/macros.rs34
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/error_codes.rs7
-rw-r--r--src/librustdoc/html/render.rs18
-rw-r--r--src/librustdoc/html/static/main.js12
-rw-r--r--src/librustdoc/html/static/rustdoc.css15
-rw-r--r--src/librustdoc/html/static/storage.js16
-rw-r--r--src/libstd/f32.rs33
-rw-r--r--src/libstd/f64.rs33
-rw-r--r--src/libstd/ffi/c_str.rs32
-rw-r--r--src/libstd/ffi/os_str.rs4
-rw-r--r--src/libstd/io/mod.rs66
-rw-r--r--src/libstd/keyword_docs.rs2
-rw-r--r--src/libstd/primitive_docs.rs2
-rw-r--r--src/libstd/sys/unix/process/process_common.rs54
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs38
-rw-r--r--src/libstd/sys/wasi/mod.rs21
-rw-r--r--src/libsyntax/diagnostics/metadata.rs93
-rw-r--r--src/libsyntax/diagnostics/plugin.rs34
-rw-r--r--src/libsyntax/ext/base.rs60
-rw-r--r--src/libsyntax/ext/expand.rs22
-rw-r--r--src/libsyntax/ext/proc_macro_server.rs11
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs20
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs44
-rw-r--r--src/libsyntax/feature_gate.rs2510
-rw-r--r--src/libsyntax/feature_gate/accepted.rs236
-rw-r--r--src/libsyntax/feature_gate/active.rs522
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs562
-rw-r--r--src/libsyntax/feature_gate/check.rs951
-rw-r--r--src/libsyntax/feature_gate/mod.rs31
-rw-r--r--src/libsyntax/feature_gate/removed.rs82
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/attr.rs5
-rw-r--r--src/libsyntax/parse/mod.rs32
-rw-r--r--src/libsyntax/parse/parser/expr.rs8
-rw-r--r--src/libsyntax/parse/parser/item.rs1
-rw-r--r--src/libsyntax/parse/parser/pat.rs2
-rw-r--r--src/libsyntax/tokenstream.rs9
-rw-r--r--src/libsyntax_ext/asm.rs2
-rw-r--r--src/libsyntax_ext/assert.rs2
-rw-r--r--src/libsyntax_ext/cfg.rs2
-rw-r--r--src/libsyntax_ext/concat.rs2
-rw-r--r--src/libsyntax_ext/concat_idents.rs2
-rw-r--r--src/libsyntax_ext/deriving/clone.rs2
-rw-r--r--src/libsyntax_ext/deriving/cmp/eq.rs2
-rw-r--r--src/libsyntax_ext/deriving/debug.rs2
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs2
-rw-r--r--src/libsyntax_ext/deriving/mod.rs5
-rw-r--r--src/libsyntax_ext/env.rs2
-rw-r--r--src/libsyntax_ext/format.rs11
-rw-r--r--src/libsyntax_ext/global_allocator.rs3
-rw-r--r--src/libsyntax_ext/global_asm.rs2
-rw-r--r--src/libsyntax_ext/test.rs6
-rw-r--r--src/libsyntax_pos/hygiene.rs80
-rw-r--r--src/libsyntax_pos/lib.rs12
-rw-r--r--src/libterm/Cargo.toml6
-rw-r--r--src/libtest/Cargo.toml16
-rw-r--r--src/libtest/lib.rs13
-rw-r--r--src/test/codegen/integer-cmp.rs28
-rw-r--r--src/test/codegen/issue-45222.rs3
-rw-r--r--src/test/incremental/hashes/call_expressions.rs18
-rw-r--r--src/test/incremental/hashes/closure_expressions.rs12
-rw-r--r--src/test/incremental/hashes/consts.rs12
-rw-r--r--src/test/incremental/hashes/if_expressions.rs16
-rw-r--r--src/test/incremental/hashes/indexing_expressions.rs14
-rw-r--r--src/test/incremental/hashes/inline_asm.rs12
-rw-r--r--src/test/incremental/hashes/loop_expressions.rs16
-rw-r--r--src/test/incremental/hashes/panic_exprs.rs18
-rw-r--r--src/test/incremental/hashes/statics.rs20
-rw-r--r--src/test/incremental/hashes/struct_constructors.rs18
-rw-r--r--src/test/incremental/hashes/trait_defs.rs121
-rw-r--r--src/test/incremental/hashes/while_let_loops.rs18
-rw-r--r--src/test/incremental/hashes/while_loops.rs18
-rw-r--r--src/test/rustdoc/async-fn.rs2
-rw-r--r--src/test/rustdoc/async-move-doctest.rs6
-rw-r--r--src/test/rustdoc/edition-flag.rs3
-rw-r--r--src/test/ui/array-break-length.rs4
-rw-r--r--src/test/ui/array-break-length.stderr8
-rw-r--r--src/test/ui/async-await/argument-patterns.rs1
-rw-r--r--src/test/ui/async-await/async-await.rs2
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.rs6
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr36
-rw-r--r--src/test/ui/async-await/async-closure-matches-expr.rs2
-rw-r--r--src/test/ui/async-await/async-closure.rs2
-rw-r--r--src/test/ui/async-await/async-error-span.rs3
-rw-r--r--src/test/ui/async-await/async-error-span.stderr4
-rw-r--r--src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs2
-rw-r--r--src/test/ui/async-await/async-fn-nonsend.rs2
-rw-r--r--src/test/ui/async-await/async-fn-nonsend.stderr32
-rw-r--r--src/test/ui/async-await/async-fn-path-elision.rs3
-rw-r--r--src/test/ui/async-await/async-fn-path-elision.stderr2
-rw-r--r--src/test/ui/async-await/async-fn-send-uses-nonsend.rs2
-rw-r--r--src/test/ui/async-await/async-fn-size-moved-locals.rs2
-rw-r--r--src/test/ui/async-await/async-fn-size.rs2
-rw-r--r--src/test/ui/async-await/async-matches-expr.rs2
-rw-r--r--src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs2
-rw-r--r--src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr8
-rw-r--r--src/test/ui/async-await/async-with-closure.rs2
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs1
-rw-r--r--src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr22
-rw-r--r--src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs1
-rw-r--r--src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr14
-rw-r--r--src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs2
-rw-r--r--src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr70
-rw-r--r--src/test/ui/async-await/await-unsize.rs2
-rw-r--r--src/test/ui/async-await/bound-normalization.rs2
-rw-r--r--src/test/ui/async-await/conditional-and-guaranteed-initialization.rs2
-rw-r--r--src/test/ui/async-await/dont-print-desugared-async.rs1
-rw-r--r--src/test/ui/async-await/dont-print-desugared-async.stderr2
-rw-r--r--src/test/ui/async-await/dont-suggest-missing-await.rs2
-rw-r--r--src/test/ui/async-await/dont-suggest-missing-await.stderr2
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs1
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs1
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs2
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs3
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr8
-rw-r--r--src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs3
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.rs2
-rw-r--r--src/test/ui/async-await/edition-deny-async-fns-2015.stderr20
-rw-r--r--src/test/ui/async-await/generics-and-bounds.rs2
-rw-r--r--src/test/ui/async-await/issue-60709.rs3
-rw-r--r--src/test/ui/async-await/issue-61452.rs1
-rw-r--r--src/test/ui/async-await/issue-61452.stderr4
-rw-r--r--src/test/ui/async-await/issue-61793.rs3
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.rs1
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.stderr2
-rw-r--r--src/test/ui/async-await/issue-62658.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-51719.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-51719.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-51751.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-51751.stderr2
-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.rs3
-rw-r--r--src/test/ui/async-await/issues/issue-54974.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-55324.rs3
-rw-r--r--src/test/ui/async-await/issues/issue-55809.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-58885.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-59001.rs3
-rw-r--r--src/test/ui/async-await/issues/issue-59972.rs6
-rw-r--r--src/test/ui/async-await/issues/issue-60518.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-60655-latebound-regions.rs1
-rw-r--r--src/test/ui/async-await/issues/issue-60674.rs1
-rw-r--r--src/test/ui/async-await/issues/issue-61187.rs4
-rw-r--r--src/test/ui/async-await/issues/issue-61187.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-61986.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr12
-rw-r--r--src/test/ui/async-await/issues/issue-62009-2.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-62517-1.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-62517-2.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.nll.stderr4
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.nll.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.stderr10
-rw-r--r--src/test/ui/async-await/issues/issue-63388-3.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-4.rs2
-rw-r--r--src/test/ui/async-await/issues/non-async-enclosing-span.rs1
-rw-r--r--src/test/ui/async-await/issues/non-async-enclosing-span.stderr2
-rw-r--r--src/test/ui/async-await/move-part-await-return-rest-struct.rs2
-rw-r--r--src/test/ui/async-await/move-part-await-return-rest-tuple.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/elided.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/hrtb.rs3
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/named.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/partial-relation.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-ref.rs2
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr6
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/variance.rs3
-rw-r--r--src/test/ui/async-await/nested-in-impl.rs2
-rw-r--r--src/test/ui/async-await/no-args-non-move-async-closure.rs2
-rw-r--r--src/test/ui/async-await/no-async-const.rs2
-rw-r--r--src/test/ui/async-await/no-async-const.stderr2
-rw-r--r--src/test/ui/async-await/no-const-async.rs2
-rw-r--r--src/test/ui/async-await/no-const-async.stderr4
-rw-r--r--src/test/ui/async-await/no-move-across-await-struct.rs2
-rw-r--r--src/test/ui/async-await/no-move-across-await-struct.stderr2
-rw-r--r--src/test/ui/async-await/no-move-across-await-tuple.rs2
-rw-r--r--src/test/ui/async-await/no-move-across-await-tuple.stderr2
-rw-r--r--src/test/ui/async-await/no-non-guaranteed-initialization.rs2
-rw-r--r--src/test/ui/async-await/no-non-guaranteed-initialization.stderr2
-rw-r--r--src/test/ui/async-await/partial-initialization-across-await.rs2
-rw-r--r--src/test/ui/async-await/partial-initialization-across-await.stderr6
-rw-r--r--src/test/ui/async-await/recursive-async-impl-trait-type.rs2
-rw-r--r--src/test/ui/async-await/recursive-async-impl-trait-type.stderr2
-rw-r--r--src/test/ui/async-await/suggest-missing-await-closure.fixed2
-rw-r--r--src/test/ui/async-await/suggest-missing-await-closure.rs2
-rw-r--r--src/test/ui/async-await/suggest-missing-await.fixed2
-rw-r--r--src/test/ui/async-await/suggest-missing-await.rs2
-rw-r--r--src/test/ui/async-await/suggest-missing-await.stderr2
-rw-r--r--src/test/ui/async-await/unresolved_type_param.rs2
-rw-r--r--src/test/ui/break-outside-loop.rs6
-rw-r--r--src/test/ui/break-outside-loop.stderr21
-rw-r--r--src/test/ui/closures/closure-array-break-length.rs6
-rw-r--r--src/test/ui/closures/closure-array-break-length.stderr12
-rw-r--r--src/test/ui/commandline-argfile-badutf8.args2
-rw-r--r--src/test/ui/commandline-argfile-badutf8.rs13
-rw-r--r--src/test/ui/commandline-argfile-badutf8.stderr2
-rw-r--r--src/test/ui/commandline-argfile-missing.rs16
-rw-r--r--src/test/ui/commandline-argfile-missing.stderr2
-rw-r--r--src/test/ui/commandline-argfile.args2
-rw-r--r--src/test/ui/commandline-argfile.rs13
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-crate-2.rs2
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr2
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs3
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr2
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs3
-rw-r--r--src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr2
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs16
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr (renamed from src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr)10
-rw-r--r--src/test/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs (renamed from src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs)23
-rw-r--r--src/test/ui/drop/dynamic-drop-async.rs3
-rw-r--r--src/test/ui/error-codes/E0267.stderr4
-rw-r--r--src/test/ui/error-codes/E0268.stderr4
-rw-r--r--src/test/ui/feature-gate-optimize_attribute.rs10
-rw-r--r--src/test/ui/feature-gate-optimize_attribute.stderr10
-rw-r--r--src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-allow_fail.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-allow_fail.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs9
-rw-r--r--src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr31
-rw-r--r--src/test/ui/feature-gates/feature-gate-async-await.rs18
-rw-r--r--src/test/ui/feature-gates/feature-gate-async-await.stderr45
-rw-r--r--src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-no_core.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-no_core.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-attrs.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-unwind-attributes.rs2
-rw-r--r--src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr2
-rw-r--r--src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs2
-rw-r--r--src/test/ui/generator/issue-62506-two_awaits.rs1
-rw-r--r--src/test/ui/hygiene/eager-from-opaque-2.rs22
-rw-r--r--src/test/ui/hygiene/eager-from-opaque.rs20
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.rs1
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.stderr8
-rw-r--r--src/test/ui/impl-trait/bound-normalization-pass.rs1
-rw-r--r--src/test/ui/impl-trait/bound-normalization-pass.stderr2
-rw-r--r--src/test/ui/impl-trait/issue-55872-2.rs3
-rw-r--r--src/test/ui/impl-trait/issue-55872-2.stderr4
-rw-r--r--src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs1
-rw-r--r--src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr4
-rw-r--r--src/test/ui/inference/cannot-infer-async.rs1
-rw-r--r--src/test/ui/inference/cannot-infer-async.stderr2
-rw-r--r--src/test/ui/issues/issue-28105.rs4
-rw-r--r--src/test/ui/issues/issue-28105.stderr8
-rw-r--r--src/test/ui/issues/issue-31776.rs6
-rw-r--r--src/test/ui/issues/issue-43162.stderr8
-rw-r--r--src/test/ui/issues/issue-50415.rs6
-rw-r--r--src/test/ui/issues/issue-50576.stderr8
-rw-r--r--src/test/ui/issues/issue-50581.stderr4
-rw-r--r--src/test/ui/issues/issue-5067.rs4
-rw-r--r--src/test/ui/lint/lint-unused-mut-variables.rs2
-rw-r--r--src/test/ui/lint/lint-unused-variables.rs2
-rw-r--r--src/test/ui/macros/derive-in-eager-expansion-hang.stderr3
-rw-r--r--src/test/ui/macros/macro-in-fn.rs8
-rw-r--r--src/test/ui/macros/restricted-shadowing-modern.rs2
-rw-r--r--src/test/ui/macros/restricted-shadowing-modern.stderr18
-rw-r--r--src/test/ui/malformed/malformed-regressions.stderr6
-rw-r--r--src/test/ui/non-integer-atomic.rs (renamed from src/test/ui/non-interger-atomic.rs)0
-rw-r--r--src/test/ui/non-integer-atomic.stderr (renamed from src/test/ui/non-interger-atomic.stderr)32
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr2
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr10
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr2
-rw-r--r--src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs4
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs2
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs2
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr2
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs2
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr8
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr10
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs2
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr6
-rw-r--r--src/test/ui/self/elision/alias-async.rs2
-rw-r--r--src/test/ui/self/elision/assoc-async.rs2
-rw-r--r--src/test/ui/self/elision/lt-alias-async.rs2
-rw-r--r--src/test/ui/self/elision/lt-assoc-async.rs2
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.nll.stderr24
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.rs2
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.stderr12
-rw-r--r--src/test/ui/self/elision/lt-self-async.rs2
-rw-r--r--src/test/ui/self/elision/lt-struct-async.rs2
-rw-r--r--src/test/ui/self/elision/multiple-ref-self-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-alias-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-assoc-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-mut-alias-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.nll.stderr24
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.stderr12
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.nll.stderr20
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.stderr10
-rw-r--r--src/test/ui/self/elision/ref-self-async.nll.stderr28
-rw-r--r--src/test/ui/self/elision/ref-self-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-self-async.stderr14
-rw-r--r--src/test/ui/self/elision/ref-struct-async.nll.stderr20
-rw-r--r--src/test/ui/self/elision/ref-struct-async.rs2
-rw-r--r--src/test/ui/self/elision/ref-struct-async.stderr10
-rw-r--r--src/test/ui/self/elision/self-async.rs2
-rw-r--r--src/test/ui/self/elision/struct-async.rs2
-rw-r--r--src/test/ui/self/self_lifetime-async.rs2
-rw-r--r--src/test/ui/specialization/issue-63716-parse-async.rs14
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs2
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs4
-rw-r--r--src/test/ui/suggestions/dont-suggest-ref/simple.rs8
-rw-r--r--src/test/ui/suggestions/opaque-type-error.rs24
-rw-r--r--src/test/ui/suggestions/opaque-type-error.stderr20
-rw-r--r--src/test/ui/traits/traits-conditional-model-fn.rs1
-rw-r--r--src/tools/build-manifest/Cargo.toml2
m---------src/tools/cargo0
m---------src/tools/clippy16
-rw-r--r--src/tools/error_index_generator/Cargo.toml4
-rw-r--r--src/tools/error_index_generator/build.rs64
-rw-r--r--src/tools/error_index_generator/main.rs49
m---------src/tools/miri14
-rwxr-xr-xsrc/tools/publish_toolstate.py2
-rw-r--r--src/tools/rustc-std-workspace-std/Cargo.toml15
-rw-r--r--src/tools/rustc-std-workspace-std/README.md3
-rw-r--r--src/tools/rustc-std-workspace-std/lib.rs1
m---------src/tools/rustfmt27
-rw-r--r--src/tools/tidy/src/deps.rs3
-rw-r--r--src/tools/tidy/src/features.rs9
388 files changed, 4546 insertions, 4945 deletions
diff --git a/.gitattributes b/.gitattributes
index f0b1c67bd0f..a7de7ce8559 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8,7 +8,7 @@
 src/etc/installer/gfx/* binary
 *.woff binary
 src/vendor/** -text
-Cargo.lock -merge linguist-generated=false
+Cargo.lock linguist-generated=false
 
 # Older git versions try to fix line endings on images, this prevents it.
 *.png binary
diff --git a/.mailmap b/.mailmap
index c5ecfb54fca..72c76006f7c 100644
--- a/.mailmap
+++ b/.mailmap
@@ -117,6 +117,9 @@ Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com>
 Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com>
 Jay True <glacjay@gmail.com>
 Jeremy Letang <letang.jeremy@gmail.com>
+Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com>
+Jeremy Stucki <dev@jeremystucki.ch> <jeremy@myelin.ch>
+Jeremy Stucki <dev@jeremystucki.ch>
 Jethro Beekman <github@jbeekman.nl>
 Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
 Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>
diff --git a/Cargo.lock b/Cargo.lock
index 9e7dd54e135..8ae21c86637 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -185,7 +185,7 @@ dependencies = [
  "serde",
  "serde_json",
  "time",
- "toml 0.4.10",
+ "toml",
 ]
 
 [[package]]
@@ -202,7 +202,7 @@ name = "build-manifest"
 version = "0.1.0"
 dependencies = [
  "serde",
- "toml 0.4.10",
+ "toml",
 ]
 
 [[package]]
@@ -265,7 +265,7 @@ dependencies = [
 
 [[package]]
 name = "cargo"
-version = "0.39.0"
+version = "0.40.0"
 dependencies = [
  "atty",
  "bytesize",
@@ -287,7 +287,7 @@ dependencies = [
  "git2-curl",
  "glob",
  "hex",
- "home",
+ "home 0.4.2",
  "ignore",
  "im-rc",
  "jobserver",
@@ -309,16 +309,16 @@ dependencies = [
  "same-file",
  "semver",
  "serde",
- "serde_ignored",
+ "serde_ignored 0.1.0",
  "serde_json",
  "shell-escape",
  "strip-ansi-escapes",
  "tar",
  "tempfile",
  "termcolor",
- "toml 0.5.1",
+ "toml",
  "unicode-width",
- "url 2.0.0",
+ "url 2.1.0",
  "walkdir",
  "winapi 0.3.6",
 ]
@@ -442,9 +442,9 @@ dependencies = [
  "semver",
  "serde",
  "smallvec",
- "toml 0.5.1",
+ "toml",
  "unicode-normalization",
- "url 1.7.2",
+ "url 2.1.0",
 ]
 
 [[package]]
@@ -574,7 +574,7 @@ checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
 
 [[package]]
 name = "crates-io"
-version = "0.27.0"
+version = "0.28.0"
 dependencies = [
  "curl",
  "failure",
@@ -583,7 +583,7 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "url 2.0.0",
+ "url 2.1.0",
 ]
 
 [[package]]
@@ -946,6 +946,7 @@ name = "error_index_generator"
 version = "0.0.0"
 dependencies = [
  "rustdoc",
+ "walkdir",
 ]
 
 [[package]]
@@ -1138,10 +1139,12 @@ dependencies = [
 
 [[package]]
 name = "getopts"
-version = "0.2.19"
+version = "0.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450"
+checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
 dependencies = [
+ "rustc-std-workspace-core",
+ "rustc-std-workspace-std",
  "unicode-width",
 ]
 
@@ -1167,7 +1170,7 @@ dependencies = [
  "log",
  "openssl-probe",
  "openssl-sys",
- "url 2.0.0",
+ "url 2.1.0",
 ]
 
 [[package]]
@@ -1179,7 +1182,7 @@ dependencies = [
  "curl",
  "git2",
  "log",
- "url 2.0.0",
+ "url 2.1.0",
 ]
 
 [[package]]
@@ -1278,6 +1281,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "home"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "013e4e6e9134211bb4d6bf53dd8cfb75d9e2715cc33614b9c0827718c6fbe0b8"
+dependencies = [
+ "scopeguard 1.0.0",
+ "winapi 0.3.6",
+]
+
+[[package]]
 name = "html5ever"
 version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1569,9 +1582,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.60"
+version = "0.2.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
+checksum = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -1775,7 +1788,7 @@ dependencies = [
  "serde_json",
  "shlex",
  "tempfile",
- "toml 0.5.1",
+ "toml",
  "toml-query",
 ]
 
@@ -2364,6 +2377,9 @@ dependencies = [
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
+dependencies = [
+ "std",
+]
 
 [[package]]
 name = "profiler_builtins"
@@ -2720,7 +2736,7 @@ dependencies = [
  "failure",
  "futures",
  "heck",
- "home",
+ "home 0.3.3",
  "itertools 0.8.0",
  "jsonrpc-core",
  "lazy_static 1.3.0",
@@ -2744,13 +2760,13 @@ dependencies = [
  "rustfmt-nightly",
  "serde",
  "serde_derive",
- "serde_ignored",
+ "serde_ignored 0.0.4",
  "serde_json",
  "tempfile",
  "tokio",
  "tokio-process",
  "tokio-timer",
- "toml 0.5.1",
+ "toml",
  "url 1.7.2",
  "walkdir",
 ]
@@ -3053,6 +3069,13 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc-std-workspace-std"
+version = "1.0.0"
+dependencies = [
+ "std",
+]
+
+[[package]]
 name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
@@ -3189,6 +3212,7 @@ dependencies = [
  "rustc_interface",
  "rustc_metadata",
  "rustc_mir",
+ "rustc_plugin",
  "rustc_plugin_impl",
  "rustc_save_analysis",
  "rustc_target",
@@ -3373,6 +3397,13 @@ dependencies = [
 ]
 
 [[package]]
+name = "rustc_plugin"
+version = "0.0.0"
+dependencies = [
+ "rustc_plugin_impl",
+]
+
+[[package]]
 name = "rustc_plugin_impl"
 version = "0.0.0"
 dependencies = [
@@ -3546,7 +3577,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.4"
+version = "1.4.5"
 dependencies = [
  "annotate-snippets",
  "atty",
@@ -3572,7 +3603,7 @@ dependencies = [
  "serde_json",
  "structopt",
  "term 0.6.0",
- "toml 0.5.1",
+ "toml",
  "unicode-segmentation",
  "unicode-width",
  "unicode_categories",
@@ -3666,9 +3697,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
 [[package]]
 name = "serde"
-version = "1.0.92"
+version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be"
+checksum = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
 dependencies = [
  "serde_derive",
 ]
@@ -3694,6 +3725,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "serde_ignored"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c24bbb8f4b81834f618cd3e28698235c2fba06ddf7f4fbe30519dd081364e59"
+dependencies = [
+ "serde",
+]
+
+[[package]]
 name = "serde_json"
 version = "1.0.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4040,6 +4080,10 @@ dependencies = [
 [[package]]
 name = "term"
 version = "0.0.0"
+dependencies = [
+ "core",
+ "std",
+]
 
 [[package]]
 name = "term"
@@ -4086,8 +4130,13 @@ dependencies = [
 name = "test"
 version = "0.0.0"
 dependencies = [
+ "core",
  "getopts",
+ "libc",
+ "panic_abort",
+ "panic_unwind",
  "proc_macro",
+ "std",
  "term 0.0.0",
 ]
 
@@ -4357,18 +4406,9 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.1"
+version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"
+checksum = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
 dependencies = [
  "serde",
 ]
@@ -4384,7 +4424,7 @@ dependencies = [
  "is-match",
  "lazy_static 1.3.0",
  "regex",
- "toml 0.5.1",
+ "toml",
  "toml-query_derive",
 ]
 
@@ -4464,9 +4504,14 @@ checksum = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
+checksum = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
+dependencies = [
+ "compiler_builtins",
+ "rustc-std-workspace-core",
+ "rustc-std-workspace-std",
+]
 
 [[package]]
 name = "unicode-xid"
@@ -4512,9 +4557,9 @@ dependencies = [
 
 [[package]]
 name = "url"
-version = "2.0.0"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6"
+checksum = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
 dependencies = [
  "idna 0.2.0",
  "matches",
diff --git a/Cargo.toml b/Cargo.toml
index ccd7e8b7654..a242f090fbc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -68,6 +68,7 @@ rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
 # here
 rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' }
 rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' }
+rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' }
 
 [patch."https://github.com/rust-lang/rust-clippy"]
 clippy_lints = { path = "src/tools/clippy/clippy_lints" }
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 589ee9276a5..c27c318f5ad 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -44,7 +44,7 @@ cc = "1.0.35"
 libc = "0.2"
 serde = { version = "1.0.8", features = ["derive"] }
 serde_json = "1.0.2"
-toml = "0.4"
+toml = "0.5"
 lazy_static = "1.3.0"
 time = "0.1"
 petgraph = "0.4.13"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index f0054c36c0c..4f5de1ecd2b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -337,7 +337,6 @@ impl<'a> Builder<'a> {
         match kind {
             Kind::Build => describe!(
                 compile::Std,
-                compile::Test,
                 compile::Rustc,
                 compile::CodegenBackend,
                 compile::StartupObjects,
@@ -363,7 +362,6 @@ impl<'a> Builder<'a> {
             ),
             Kind::Check | Kind::Clippy | Kind::Fix => describe!(
                 check::Std,
-                check::Test,
                 check::Rustc,
                 check::CodegenBackend,
                 check::Rustdoc
@@ -425,8 +423,6 @@ impl<'a> Builder<'a> {
                 doc::TheBook,
                 doc::Standalone,
                 doc::Std,
-                doc::Test,
-                doc::WhitelistedRustc,
                 doc::Rustc,
                 doc::Rustdoc,
                 doc::ErrorIndex,
@@ -618,13 +614,7 @@ impl<'a> Builder<'a> {
             }
 
             fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
-                let compiler = self.compiler;
-                let config = &builder.build.config;
-                let lib = if compiler.stage >= 1 && config.libdir_relative().is_some() {
-                    builder.build.config.libdir_relative().unwrap()
-                } else {
-                    Path::new("lib")
-                };
+                let lib = builder.sysroot_libdir_relative(self.compiler);
                 let sysroot = builder
                     .sysroot(self.compiler)
                     .join(lib)
@@ -678,6 +668,18 @@ impl<'a> Builder<'a> {
         }
     }
 
+    /// Returns the compiler's relative libdir where the standard library and other artifacts are
+    /// found for a compiler's sysroot.
+    ///
+    /// For example this returns `lib` on Unix and Windows.
+    pub fn sysroot_libdir_relative(&self, compiler: Compiler) -> &Path {
+        match self.config.libdir_relative() {
+            Some(relative_libdir) if compiler.stage >= 1
+                => relative_libdir,
+            _ => Path::new("lib")
+        }
+    }
+
     /// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic
     /// library lookup path.
     pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut Command) {
@@ -795,7 +797,7 @@ impl<'a> Builder<'a> {
         }
 
         match mode {
-            Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {},
+            Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {},
             Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
                 // Build proc macros both for the host and the target
                 if target != compiler.host && cmd != "check" {
@@ -846,7 +848,6 @@ impl<'a> Builder<'a> {
         // things still build right, please do!
         match mode {
             Mode::Std => metadata.push_str("std"),
-            Mode::Test => metadata.push_str("test"),
             _ => {},
         }
         cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
@@ -859,18 +860,17 @@ impl<'a> Builder<'a> {
             stage = compiler.stage;
         }
 
-        let mut extra_args = env::var(&format!("RUSTFLAGS_STAGE_{}", stage)).unwrap_or_default();
+        let mut extra_args = String::new();
         if stage != 0 {
-            let s = env::var("RUSTFLAGS_STAGE_NOT_0").unwrap_or_default();
-            if !extra_args.is_empty() {
-                extra_args.push_str(" ");
-            }
+            let s = env::var("RUSTFLAGS_NOT_BOOTSTRAP").unwrap_or_default();
+            extra_args.push_str(&s);
+        } else {
+            let s = env::var("RUSTFLAGS_BOOTSTRAP").unwrap_or_default();
             extra_args.push_str(&s);
         }
 
         if cmd == "clippy" {
-            extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \
-                --json-rendered=termcolor");
+            extra_args.push_str("-Zforce-unstable-if-unmarked");
         }
 
         if !extra_args.is_empty() {
@@ -943,9 +943,9 @@ impl<'a> Builder<'a> {
 
         let debuginfo_level = match mode {
             Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
-            Mode::Std | Mode::Test => self.config.rust_debuginfo_level_std,
+            Mode::Std => self.config.rust_debuginfo_level_std,
             Mode::ToolBootstrap | Mode::ToolStd |
-            Mode::ToolTest | Mode::ToolRustc => self.config.rust_debuginfo_level_tools,
+            Mode::ToolRustc => self.config.rust_debuginfo_level_tools,
         };
         cargo.env("RUSTC_DEBUGINFO_LEVEL", debuginfo_level.to_string());
 
@@ -1145,7 +1145,6 @@ impl<'a> Builder<'a> {
 
         match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) {
             (Mode::Std, Some(n), _) |
-            (Mode::Test, Some(n), _) |
             (_, _, Some(n)) => {
                 cargo.env("RUSTC_CODEGEN_UNITS", n.to_string());
             }
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index d1542b1fca6..2bb90fdb04e 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -366,27 +366,6 @@ fn dist_with_same_targets_and_hosts() {
         ]
     );
     assert_eq!(
-        first(builder.cache.all::<compile::Test>()),
-        &[
-            compile::Test {
-                compiler: Compiler { host: a, stage: 0 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: b,
-            },
-        ]
-    );
-    assert_eq!(
         first(builder.cache.all::<compile::Assemble>()),
         &[
             compile::Assemble {
@@ -415,7 +394,47 @@ fn build_default() {
     let b = INTERNER.intern_str("B");
     let c = INTERNER.intern_str("C");
 
-    assert!(!builder.cache.all::<compile::Std>().is_empty());
+    assert_eq!(
+        first(builder.cache.all::<compile::Std>()),
+        &[
+            compile::Std {
+                compiler: Compiler { host: a, stage: 0 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 1 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 2 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: b, stage: 2 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 1 },
+                target: b,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 2 },
+                target: b,
+            },
+            compile::Std {
+                compiler: Compiler { host: b, stage: 2 },
+                target: b,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 2 },
+                target: c,
+            },
+            compile::Std {
+                compiler: Compiler { host: b, stage: 2 },
+                target: c,
+            },
+        ]
+    );
     assert!(!builder.cache.all::<compile::Assemble>().is_empty());
     assert_eq!(
         first(builder.cache.all::<compile::Rustc>()),
@@ -450,63 +469,61 @@ fn build_default() {
             },
         ]
     );
+}
+
+#[test]
+fn build_with_target_flag() {
+    let mut config = configure(&["B"], &["C"]);
+    config.skip_only_host_steps = true;
+    let build = Build::new(config);
+    let mut builder = Builder::new(&build);
+    builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
+
+    let a = INTERNER.intern_str("A");
+    let b = INTERNER.intern_str("B");
+    let c = INTERNER.intern_str("C");
 
     assert_eq!(
-        first(builder.cache.all::<compile::Test>()),
+        first(builder.cache.all::<compile::Std>()),
         &[
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 0 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 1 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 2 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: b, stage: 2 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 1 },
                 target: b,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 2 },
                 target: b,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: b, stage: 2 },
                 target: b,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 2 },
                 target: c,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: b, stage: 2 },
                 target: c,
             },
         ]
     );
-}
-
-#[test]
-fn build_with_target_flag() {
-    let mut config = configure(&["B"], &["C"]);
-    config.skip_only_host_steps = true;
-    let build = Build::new(config);
-    let mut builder = Builder::new(&build);
-    builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
-
-    let a = INTERNER.intern_str("A");
-    let b = INTERNER.intern_str("B");
-    let c = INTERNER.intern_str("C");
-
-    assert!(!builder.cache.all::<compile::Std>().is_empty());
     assert_eq!(
         first(builder.cache.all::<compile::Assemble>()),
         &[
@@ -541,48 +558,6 @@ fn build_with_target_flag() {
             },
         ]
     );
-
-    assert_eq!(
-        first(builder.cache.all::<compile::Test>()),
-        &[
-            compile::Test {
-                compiler: Compiler { host: a, stage: 0 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: b, stage: 2 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: b,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: b,
-            },
-            compile::Test {
-                compiler: Compiler { host: b, stage: 2 },
-                target: b,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: c,
-            },
-            compile::Test {
-                compiler: Compiler { host: b, stage: 2 },
-                target: c,
-            },
-        ]
-    );
 }
 
 #[test]
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 6e6fea6b831..e9a9b7881a0 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -1,6 +1,6 @@
 //! Implementation of compiling the compiler and standard library, in "check"-based modes.
 
-use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
+use crate::compile::{run_cargo, std_cargo, rustc_cargo, rustc_cargo_env,
                      add_to_sysroot};
 use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
 use crate::tool::{prepare_tool_cargo, SourceType};
@@ -92,7 +92,7 @@ impl Step for Rustc {
         let compiler = builder.compiler(0, builder.config.build);
         let target = self.target;
 
-        builder.ensure(Test { target });
+        builder.ensure(Std { target });
 
         let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
             cargo_subcommand(builder.kind));
@@ -160,47 +160,6 @@ impl Step for CodegenBackend {
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Test {
-    pub target: Interned<String>,
-}
-
-impl Step for Test {
-    type Output = ();
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("test")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Test {
-            target: run.target,
-        });
-    }
-
-    fn run(self, builder: &Builder<'_>) {
-        let compiler = builder.compiler(0, builder.config.build);
-        let target = self.target;
-
-        builder.ensure(Std { target });
-
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
-        test_cargo(builder, &compiler, target, &mut cargo);
-
-        builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
-        run_cargo(builder,
-                  &mut cargo,
-                  args(builder.kind),
-                  &libtest_stamp(builder, compiler, target),
-                  true);
-
-        let libdir = builder.sysroot_libdir(compiler, target);
-        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
-        add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
-    }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Rustdoc {
     pub target: Interned<String>,
 }
@@ -258,16 +217,6 @@ pub fn libstd_stamp(
     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
 }
 
-/// Cargo's output path for libtest in a given stage, compiled by a particular
-/// compiler for the specified target.
-pub fn libtest_stamp(
-    builder: &Builder<'_>,
-    compiler: Compiler,
-    target: Interned<String>,
-) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp")
-}
-
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 96987d08159..7dad146b48d 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -216,7 +216,7 @@ pub fn std_cargo(builder: &Builder<'_>,
 
         cargo.arg("--features").arg(features)
             .arg("--manifest-path")
-            .arg(builder.src.join("src/libstd/Cargo.toml"));
+            .arg(builder.src.join("src/libtest/Cargo.toml"));
 
         if target.contains("musl") {
             if let Some(p) = builder.musl_root(target) {
@@ -359,129 +359,6 @@ impl Step for StartupObjects {
 }
 
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Test {
-    pub target: Interned<String>,
-    pub compiler: Compiler,
-}
-
-impl Step for Test {
-    type Output = ();
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("test")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Test {
-            compiler: run.builder.compiler(run.builder.top_stage, run.host),
-            target: run.target,
-        });
-    }
-
-    /// Builds libtest.
-    ///
-    /// This will build libtest and supporting libraries for a particular stage of
-    /// the build using the `compiler` targeting the `target` architecture. The
-    /// artifacts created will also be linked into the sysroot directory.
-    fn run(self, builder: &Builder<'_>) {
-        let target = self.target;
-        let compiler = self.compiler;
-
-        builder.ensure(Std { compiler, target });
-
-        if builder.config.keep_stage.contains(&compiler.stage) {
-            builder.info("Warning: Using a potentially old libtest. This may not behave well.");
-            builder.ensure(TestLink {
-                compiler,
-                target_compiler: compiler,
-                target,
-            });
-            return;
-        }
-
-        let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
-        if compiler_to_use != compiler {
-            builder.ensure(Test {
-                compiler: compiler_to_use,
-                target,
-            });
-            builder.info(
-                &format!("Uplifting stage1 test ({} -> {})", builder.config.build, target));
-            builder.ensure(TestLink {
-                compiler: compiler_to_use,
-                target_compiler: compiler,
-                target,
-            });
-            return;
-        }
-
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, "build");
-        test_cargo(builder, &compiler, target, &mut cargo);
-
-        builder.info(&format!("Building stage{} test artifacts ({} -> {})", compiler.stage,
-                &compiler.host, target));
-        run_cargo(builder,
-                  &mut cargo,
-                  vec![],
-                  &libtest_stamp(builder, compiler, target),
-                  false);
-
-        builder.ensure(TestLink {
-            compiler: builder.compiler(compiler.stage, builder.config.build),
-            target_compiler: compiler,
-            target,
-        });
-    }
-}
-
-/// Same as `std_cargo`, but for libtest
-pub fn test_cargo(builder: &Builder<'_>,
-                  _compiler: &Compiler,
-                  _target: Interned<String>,
-                  cargo: &mut Command) {
-    if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
-        cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
-    }
-    cargo.arg("--manifest-path")
-        .arg(builder.src.join("src/libtest/Cargo.toml"));
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct TestLink {
-    pub compiler: Compiler,
-    pub target_compiler: Compiler,
-    pub target: Interned<String>,
-}
-
-impl Step for TestLink {
-    type Output = ();
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.never()
-    }
-
-    /// Same as `std_link`, only for libtest
-    fn run(self, builder: &Builder<'_>) {
-        let compiler = self.compiler;
-        let target_compiler = self.target_compiler;
-        let target = self.target;
-        builder.info(&format!("Copying stage{} test from stage{} ({} -> {} / {})",
-                target_compiler.stage,
-                compiler.stage,
-                &compiler.host,
-                target_compiler.host,
-                target));
-        add_to_sysroot(
-            builder,
-            &builder.sysroot_libdir(target_compiler, target),
-            &builder.sysroot_libdir(target_compiler, compiler.host),
-            &libtest_stamp(builder, compiler, target)
-        );
-    }
-}
-
-#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Rustc {
     pub target: Interned<String>,
     pub compiler: Compiler,
@@ -512,7 +389,7 @@ impl Step for Rustc {
         let compiler = self.compiler;
         let target = self.target;
 
-        builder.ensure(Test { compiler, target });
+        builder.ensure(Std { compiler, target });
 
         if builder.config.keep_stage.contains(&compiler.stage) {
             builder.info("Warning: Using a potentially old librustc. This may not behave well.");
@@ -541,7 +418,7 @@ impl Step for Rustc {
         }
 
         // Ensure that build scripts and proc macros have a std / libproc_macro to link against.
-        builder.ensure(Test {
+        builder.ensure(Std {
             compiler: builder.compiler(self.compiler.stage, builder.config.build),
             target: builder.config.build,
         });
@@ -872,16 +749,6 @@ pub fn libstd_stamp(
     builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
 }
 
-/// Cargo's output path for libtest in a given stage, compiled by a particular
-/// compiler for the specified target.
-pub fn libtest_stamp(
-    builder: &Builder<'_>,
-    compiler: Compiler,
-    target: Interned<String>,
-) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Test, target).join(".libtest.stamp")
-}
-
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index bd012a887c2..0f4ac63651c 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -469,7 +469,6 @@ impl Step for Rustc {
         fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) {
             let host = compiler.host;
             let src = builder.sysroot(compiler);
-            let libdir = builder.rustc_libdir(compiler);
 
             // Copy rustc/rustdoc binaries
             t!(fs::create_dir_all(image.join("bin")));
@@ -481,11 +480,14 @@ impl Step for Rustc {
 
             // Copy runtime DLLs needed by the compiler
             if libdir_relative.to_str() != Some("bin") {
+                let libdir = builder.rustc_libdir(compiler);
                 for entry in builder.read_dir(&libdir) {
                     let name = entry.file_name();
                     if let Some(s) = name.to_str() {
                         if is_dylib(s) {
-                            builder.install(&entry.path(), &image.join(&libdir_relative), 0o644);
+                            // Don't use custom libdir here because ^lib/ will be resolved again
+                            // with installer
+                            builder.install(&entry.path(), &image.join("lib"), 0o644);
                         }
                     }
                 }
@@ -493,8 +495,11 @@ impl Step for Rustc {
 
             // Copy over the codegen backends
             let backends_src = builder.sysroot_codegen_backends(compiler);
-            let backends_rel = backends_src.strip_prefix(&src).unwrap();
-            let backends_dst = image.join(&backends_rel);
+            let backends_rel = backends_src.strip_prefix(&src).unwrap()
+                .strip_prefix(builder.sysroot_libdir_relative(compiler)).unwrap();
+            // Don't use custom libdir here because ^lib/ will be resolved again with installer
+            let backends_dst = image.join("lib").join(&backends_rel);
+
             t!(fs::create_dir_all(&backends_dst));
             builder.cp_r(&backends_src, &backends_dst);
 
@@ -673,12 +678,7 @@ impl Step for Std {
         if builder.hosts.iter().any(|t| t == target) {
             builder.ensure(compile::Rustc { compiler, target });
         } else {
-            if builder.no_std(target) == Some(true) {
-                // the `test` doesn't compile for no-std targets
-                builder.ensure(compile::Std { compiler, target });
-            } else {
-                builder.ensure(compile::Test { compiler, target });
-            }
+            builder.ensure(compile::Std { compiler, target });
         }
 
         let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
@@ -907,6 +907,7 @@ impl Step for Src {
             "src/libproc_macro",
             "src/tools/rustc-std-workspace-core",
             "src/tools/rustc-std-workspace-alloc",
+            "src/tools/rustc-std-workspace-std",
             "src/librustc",
             "src/libsyntax",
         ];
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 36229720e42..6805474aa04 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -478,139 +478,13 @@ impl Step for Std {
             builder.run(&mut cargo);
             builder.cp_r(&my_out, &out);
         };
-        for krate in &["alloc", "core", "std"] {
+        for krate in &["alloc", "core", "std", "proc_macro", "test"] {
             run_cargo_rustdoc_for(krate);
         }
     }
 }
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct Test {
-    stage: u32,
-    target: Interned<String>,
-}
-
-impl Step for Test {
-    type Output = ();
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        let builder = run.builder;
-        run.krate("test").default_condition(builder.config.docs)
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Test {
-            stage: run.builder.top_stage,
-            target: run.target,
-        });
-    }
-
-    /// Compile all libtest documentation.
-    ///
-    /// This will generate all documentation for libtest and its dependencies. This
-    /// is largely just a wrapper around `cargo doc`.
-    fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let target = self.target;
-        builder.info(&format!("Documenting stage{} test ({})", stage, target));
-        let out = builder.doc_out(target);
-        t!(fs::create_dir_all(&out));
-        let compiler = builder.compiler_for(stage, builder.config.build, target);
-
-        // Build libstd docs so that we generate relative links
-        builder.ensure(Std { stage, target });
-
-        builder.ensure(compile::Test { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Test)
-                           .join(target).join("doc");
-
-        // See docs in std above for why we symlink
-        let my_out = builder.crate_doc_out(target);
-        t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
-
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, "doc");
-        compile::test_cargo(builder, &compiler, target, &mut cargo);
-
-        cargo.arg("--no-deps")
-             .arg("-p").arg("test")
-             .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
-             .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
-
-        builder.run(&mut cargo);
-        builder.cp_r(&my_out, &out);
-    }
-}
-
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct WhitelistedRustc {
-    stage: u32,
-    target: Interned<String>,
-}
-
-impl Step for WhitelistedRustc {
-    type Output = ();
-    const DEFAULT: bool = true;
-    const ONLY_HOSTS: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        let builder = run.builder;
-        run.krate("rustc-main").default_condition(builder.config.docs)
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(WhitelistedRustc {
-            stage: run.builder.top_stage,
-            target: run.target,
-        });
-    }
-
-    /// Generates whitelisted compiler crate documentation.
-    ///
-    /// This will generate all documentation for crates that are whitelisted
-    /// to be included in the standard documentation. This documentation is
-    /// included in the standard Rust documentation, so we should always
-    /// document it and symlink to merge with the rest of the std and test
-    /// documentation. We don't build other compiler documentation
-    /// here as we want to be able to keep it separate from the standard
-    /// documentation. This is largely just a wrapper around `cargo doc`.
-    fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let target = self.target;
-        builder.info(&format!("Documenting stage{} whitelisted compiler ({})", stage, target));
-        let out = builder.doc_out(target);
-        t!(fs::create_dir_all(&out));
-        let compiler = builder.compiler_for(stage, builder.config.build, target);
-
-        // Build libstd docs so that we generate relative links
-        builder.ensure(Std { stage, target });
-
-        builder.ensure(compile::Rustc { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Rustc)
-                           .join(target).join("doc");
-
-        // See docs in std above for why we symlink
-        let my_out = builder.crate_doc_out(target);
-        t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
-
-        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
-        compile::rustc_cargo(builder, &mut cargo);
-
-        // We don't want to build docs for internal compiler dependencies in this
-        // step (there is another step for that). Therefore, we whitelist the crates
-        // for which docs must be built.
-        for krate in &["proc_macro"] {
-            cargo.arg("-p").arg(krate)
-                 .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
-                 .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
-        }
-
-        builder.run(&mut cargo);
-        builder.cp_r(&my_out, &out);
-    }
-}
-
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Rustc {
     stage: u32,
     target: Interned<String>,
@@ -825,8 +699,7 @@ impl Step for ErrorIndex {
         index.arg(crate::channel::CFG_RELEASE_NUM);
 
         // FIXME: shouldn't have to pass this env var
-        index.env("CFG_BUILD", &builder.config.build)
-             .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
+        index.env("CFG_BUILD", &builder.config.build);
 
         builder.run(&mut index);
     }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index b72aa78f3de..c0e0ad1a857 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -297,9 +297,6 @@ pub enum Mode {
     /// Build the standard library, placing output in the "stageN-std" directory.
     Std,
 
-    /// Build libtest, placing output in the "stageN-test" directory.
-    Test,
-
     /// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
     Rustc,
 
@@ -315,7 +312,6 @@ pub enum Mode {
     /// Compile a tool which uses all libraries we compile (up to rustc).
     /// Doesn't use the stage0 compiler libraries like "other", and includes
     /// tools like rustdoc, cargo, rls, etc.
-    ToolTest,
     ToolStd,
     ToolRustc,
 }
@@ -536,11 +532,10 @@ impl Build {
     fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
         let suffix = match mode {
             Mode::Std => "-std",
-            Mode::Test => "-test",
             Mode::Rustc => "-rustc",
             Mode::Codegen => "-codegen",
             Mode::ToolBootstrap => "-bootstrap-tools",
-            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
+            Mode::ToolStd | Mode::ToolRustc => "-tools",
         };
         self.out.join(&*compiler.host)
                 .join(format!("stage{}{}", compiler.stage, suffix))
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index c2c134bfd1d..2bb053cc2b0 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1040,21 +1040,10 @@ impl Step for Compiletest {
             builder.ensure(compile::Rustc { compiler, target });
         }
 
-        if builder.no_std(target) == Some(true) {
-            // the `test` doesn't compile for no-std targets
-            builder.ensure(compile::Std { compiler, target });
-        } else {
-            builder.ensure(compile::Test { compiler, target });
-        }
-
-        if builder.no_std(target) == Some(true) {
-            // for no_std run-make (e.g., thumb*),
-            // we need a host compiler which is called by cargo.
-            builder.ensure(compile::Std { compiler, target: compiler.host });
-        }
+        builder.ensure(compile::Std { compiler, target });
+        // ensure that `libproc_macro` is available on the host.
+        builder.ensure(compile::Std { compiler, target: compiler.host });
 
-        // HACK(eddyb) ensure that `libproc_macro` is available on the host.
-        builder.ensure(compile::Test { compiler, target: compiler.host });
         // Also provide `rust_test_helpers` for the host.
         builder.ensure(native::TestHelpers { target: compiler.host });
 
@@ -1399,7 +1388,7 @@ impl Step for DocTest {
     fn run(self, builder: &Builder<'_>) {
         let compiler = self.compiler;
 
-        builder.ensure(compile::Test {
+        builder.ensure(compile::Std {
             compiler,
             target: compiler.host,
         });
@@ -1535,8 +1524,7 @@ impl Step for ErrorIndex {
         );
         tool.arg("markdown")
             .arg(&output)
-            .env("CFG_BUILD", &builder.config.build)
-            .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
+            .env("CFG_BUILD", &builder.config.build);
 
         builder.info(&format!("Testing error-index stage{}", compiler.stage));
         let _time = util::timeit(&builder);
@@ -1710,8 +1698,7 @@ impl Step for Crate {
 
     fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run = run.krate("test");
-        for krate in run.builder.in_tree_crates("std") {
+        for krate in run.builder.in_tree_crates("test") {
             if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) {
                 run = run.path(krate.local_path(&builder).to_str().unwrap());
             }
@@ -1735,14 +1722,9 @@ impl Step for Crate {
             });
         };
 
-        for krate in builder.in_tree_crates("std") {
-            if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Std, krate);
-            }
-        }
         for krate in builder.in_tree_crates("test") {
             if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Test, krate);
+                make(Mode::Std, krate);
             }
         }
     }
@@ -1762,7 +1744,7 @@ impl Step for Crate {
         let test_kind = self.test_kind;
         let krate = self.krate;
 
-        builder.ensure(compile::Test { compiler, target });
+        builder.ensure(compile::Std { compiler, target });
         builder.ensure(RemoteCopyLibs { compiler, target });
 
         // If we're not doing a full bootstrap but we're testing a stage2
@@ -1776,9 +1758,6 @@ impl Step for Crate {
             Mode::Std => {
                 compile::std_cargo(builder, &compiler, target, &mut cargo);
             }
-            Mode::Test => {
-                compile::test_cargo(builder, &compiler, target, &mut cargo);
-            }
             Mode::Rustc => {
                 builder.ensure(compile::Rustc { compiler, target });
                 compile::rustc_cargo(builder, &mut cargo);
@@ -1980,7 +1959,7 @@ impl Step for RemoteCopyLibs {
             return;
         }
 
-        builder.ensure(compile::Test { compiler, target });
+        builder.ensure(compile::Std { compiler, target });
 
         builder.info(&format!("REMOTE copy libs to emulator ({})", target));
         t!(fs::create_dir_all(builder.out.join("tmp")));
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index df7eb7c455d..54fe26f18e7 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -577,12 +577,6 @@ impl Step for Cargo {
     }
 
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        // Cargo depends on procedural macros, so make sure the host
-        // libstd/libproc_macro is available.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
         builder.ensure(ToolBuild {
             compiler: self.compiler,
             target: self.target,
@@ -650,31 +644,10 @@ macro_rules! tool_extended {
 
 tool_extended!((self, builder),
     Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", {};
-    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {
-        // Clippy depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
-    };
-    Clippy, clippy, "src/tools/clippy", "clippy-driver", {
-        // Clippy depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
-    };
+    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {};
+    Clippy, clippy, "src/tools/clippy", "clippy-driver", {};
     Miri, miri, "src/tools/miri", "miri", {};
-    CargoMiri, miri, "src/tools/miri", "cargo-miri", {
-        // Miri depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
-    };
+    CargoMiri, miri, "src/tools/miri", "cargo-miri", {};
     Rls, rls, "src/tools/rls", "rls", {
         let clippy = builder.ensure(Clippy {
             compiler: self.compiler,
@@ -684,12 +657,6 @@ tool_extended!((self, builder),
         if clippy.is_some() {
             self.extra_features.push("clippy".to_owned());
         }
-        // RLS depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
     };
     Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", {};
 );
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index a1aa18922b5..131d2034675 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -262,7 +262,7 @@ pub fn native_lib_boilerplate(
     if !up_to_date(Path::new("build.rs"), &timestamp) || !up_to_date(src_dir, &timestamp) {
         Ok(NativeLibBoilerplate {
             src_dir: src_dir.to_path_buf(),
-            out_dir: out_dir,
+            out_dir,
         })
     } else {
         Err(())
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index ae2ea8ef95a..10579119462 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -104,9 +104,7 @@ ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi
 ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf
 ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl
 ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu
-# FIXME: temporarily disable the redox builder,
-# see: https://github.com/rust-lang/rust/issues/63160
-# ENV TARGETS=$TARGETS,x86_64-unknown-redox
+ENV TARGETS=$TARGETS,x86_64-unknown-redox
 ENV TARGETS=$TARGETS,thumbv6m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7em-none-eabi
@@ -132,7 +130,7 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
     AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
     CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++
-    
+
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-armv5te=/musl-armv5te \
       --musl-root-arm=/musl-arm \
diff --git a/src/ci/docker/dist-various-1/install-mipsel-musl.sh b/src/ci/docker/dist-various-1/install-mipsel-musl.sh
index 9ae41218ee4..de8c359d167 100755
--- a/src/ci/docker/dist-various-1/install-mipsel-musl.sh
+++ b/src/ci/docker/dist-various-1/install-mipsel-musl.sh
@@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl
 # Note that this originally came from:
 # https://downloads.openwrt.org/snapshots/trunk/malta/generic/
 # OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2
-URL="https://rust-lang-ci2.s3.amazonaws.com/libc"
+URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc"
 FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2"
 curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2
 
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject c5da1e11915d3f28266168baaf55822f7e3fe99
+Subproject 432ca26686c11d396eed6a59499f93ce1bf2433
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject 8a7d05615e5bc0a7fb961b4919c44f5221ee54d
+Subproject 38b9a76bc8b59ac862663807fc51c9b757337fd
diff --git a/src/doc/reference b/src/doc/reference
-Subproject b4b3536839042a6743fc76f0d9ad2a812020aea
+Subproject d191a0cdd3b92648e0f1e53b13140a14677cc65
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject f2c15ba5ee89ae9469a2cf60494977749901d76
+Subproject 580839d90aacd537f0293697096fa8355bc4e67
diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
-Subproject 6f4ba673ff9d4613e98415bc095347a6a0031e9
+Subproject 6e25a3d0d3573eb42b2e2339f1219e969d1b3de
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index d774e465118..5eea9c86879 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -304,3 +304,10 @@ to customize the output:
 
 Note that it is invalid to combine the `--json` argument with the `--color`
 argument, and it is required to combine `--json` with `--error-format=json`.
+
+## `@path`: load command-line flags from a path
+
+If you specify `@path` on the command-line, then it will open `path` and read
+command line options from it. These options are one per line; a blank line indicates
+an empty option. The file can use Unix or Windows style line endings, and must be
+encoded as UTF-8.
diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md
index a6e4e166d7b..d3dfc3197e2 100644
--- a/src/doc/rustc/src/lints/listing/allowed-by-default.md
+++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md
@@ -208,7 +208,7 @@ error: missing documentation for a function
 
 To fix the lint, add documentation to all items.
 
-## single-use-lifetime
+## single-use-lifetimes
 
 This lint detects lifetimes that are only used once. Some example code that
 triggers this lint:
diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 7315963cc8b..a4a0fbb194d 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1810,7 +1810,7 @@ impl<T> VecDeque<T> {
         other
     }
 
-    /// Moves all the elements of `other` into `Self`, leaving `other` empty.
+    /// Moves all the elements of `other` into `self`, leaving `other` empty.
     ///
     /// # Panics
     ///
@@ -1847,7 +1847,7 @@ impl<T> VecDeque<T> {
     ///
     /// let mut buf = VecDeque::new();
     /// buf.extend(1..5);
-    /// buf.retain(|&x| x%2 == 0);
+    /// buf.retain(|&x| x % 2 == 0);
     /// assert_eq!(buf, [2, 4]);
     /// ```
     ///
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index cb9feb074dd..167a9dd1c36 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -1012,9 +1012,11 @@ mod impls {
             impl Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &$t) -> Ordering {
-                    if *self == *other { Equal }
-                    else if *self < *other { Less }
-                    else { Greater }
+                    // The order here is important to generate more optimal assembly.
+                    // See <https://github.com/rust-lang/rust/issues/63758> for more info.
+                    if *self < *other { Less }
+                    else if *self > *other { Greater }
+                    else { Equal }
                 }
             }
         )*)
diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs
index 0b9f7f6b609..c9612596b1b 100644
--- a/src/libcore/iter/adapters/chain.rs
+++ b/src/libcore/iter/adapters/chain.rs
@@ -173,17 +173,23 @@ impl<A, B> Iterator for Chain<A, B> where
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let (a_lower, a_upper) = self.a.size_hint();
-        let (b_lower, b_upper) = self.b.size_hint();
+        match self.state {
+            ChainState::Both => {
+                let (a_lower, a_upper) = self.a.size_hint();
+                let (b_lower, b_upper) = self.b.size_hint();
 
-        let lower = a_lower.saturating_add(b_lower);
+                let lower = a_lower.saturating_add(b_lower);
 
-        let upper = match (a_upper, b_upper) {
-            (Some(x), Some(y)) => x.checked_add(y),
-            _ => None
-        };
+                let upper = match (a_upper, b_upper) {
+                    (Some(x), Some(y)) => x.checked_add(y),
+                    _ => None
+                };
 
-        (lower, upper)
+                (lower, upper)
+            }
+            ChainState::Front => self.a.size_hint(),
+            ChainState::Back => self.b.size_hint(),
+        }
     }
 }
 
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index a63434abd6c..f50781890ab 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -1309,7 +1309,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
         match self.peeked.take() {
-            Some(None) => return Try::from_ok(init),
+            Some(None) => Try::from_ok(init),
             Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
                 Ok(acc) => f(acc, v),
                 Err(e) => {
@@ -1326,7 +1326,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
         match self.peeked {
-            Some(None) => return init,
+            Some(None) => init,
             Some(Some(v)) => {
                 let acc = self.iter.rfold(init, &mut fold);
                 fold(acc, v)
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 6c88a766a2f..ffaca029a8a 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -734,7 +734,6 @@ pub(crate) mod builtin {
     #[allow_internal_unstable(fmt_internals)]
     #[rustc_builtin_macro]
     #[macro_export]
-    #[rustc_macro_transparency = "opaque"]
     macro_rules! format_args {
         ($fmt:expr) => ({ /* compiler built-in */ });
         ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
@@ -747,7 +746,6 @@ pub(crate) mod builtin {
     #[allow_internal_unstable(fmt_internals)]
     #[rustc_builtin_macro]
     #[macro_export]
-    #[rustc_macro_transparency = "opaque"]
     macro_rules! format_args_nl {
         ($fmt:expr) => ({ /* compiler built-in */ });
         ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
@@ -1235,7 +1233,6 @@ pub(crate) mod builtin {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro test($item:item) { /* compiler built-in */ }
 
     /// Attribute macro applied to a function to turn it into a benchmark test.
@@ -1243,7 +1240,6 @@ pub(crate) mod builtin {
                reason = "`bench` is a part of custom test frameworks which are unstable")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro bench($item:item) { /* compiler built-in */ }
 
     /// An implementation detail of the `#[test]` and `#[bench]` macros.
@@ -1251,26 +1247,22 @@ pub(crate) mod builtin {
                reason = "custom test frameworks are an unstable feature")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro test_case($item:item) { /* compiler built-in */ }
 
     /// Attribute macro applied to a static to register it as a global allocator.
     #[stable(feature = "global_allocator", since = "1.28.0")]
     #[allow_internal_unstable(rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro global_allocator($item:item) { /* compiler built-in */ }
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
     pub macro RustcDecodable($item:item) { /* compiler built-in */ }
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro RustcEncodable($item:item) { /* compiler built-in */ }
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 8ff78166a9f..22e7573eca6 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -315,7 +315,7 @@ impl f32 {
     /// use std::f32;
     ///
     /// let x = 2.0_f32;
-    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    /// let abs_difference = (x.recip() - (1.0 / x)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index d45c04f45af..bbe1d040780 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -327,7 +327,7 @@ impl f64 {
     ///
     /// ```
     /// let x = 2.0_f64;
-    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    /// let abs_difference = (x.recip() - (1.0 / x)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index ce5af13d4ca..931768564ca 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -3026,8 +3026,7 @@ macro_rules! len {
         if size == 0 {
             // This _cannot_ use `unchecked_sub` because we depend on wrapping
             // to represent the length of long ZST slice iterators.
-            let diff = ($self.end as usize).wrapping_sub(start as usize);
-            diff
+            ($self.end as usize).wrapping_sub(start as usize)
         } else {
             // We know that `start <= end`, so can do better than `offset_from`,
             // which needs to deal in signed.  By setting appropriate flags here
@@ -4637,6 +4636,22 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
             Some(tail)
         }
     }
+
+    #[inline]
+    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
+        let len = self.len();
+        if n >= len {
+            self.v = &mut [];
+            None
+        } else {
+            let start = (len - 1 - n) * self.chunk_size;
+            let end = start + self.chunk_size;
+            let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
+            let (head, nth_back) = temp.split_at_mut(start);
+            self.v = head;
+            Some(nth_back)
+        }
+    }
 }
 
 #[stable(feature = "chunks_exact", since = "1.31.0")]
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index a1a27e1d538..3a4f76852a0 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -153,6 +153,54 @@ fn test_iterator_chain_find() {
 }
 
 #[test]
+fn test_iterator_chain_size_hint() {
+    struct Iter {
+        is_empty: bool,
+    }
+
+    impl Iterator for Iter {
+        type Item = ();
+
+        // alternates between `None` and `Some(())`
+        fn next(&mut self) -> Option<Self::Item> {
+            if self.is_empty {
+                self.is_empty = false;
+                None
+            } else {
+                self.is_empty = true;
+                Some(())
+            }
+        }
+
+        fn size_hint(&self) -> (usize, Option<usize>) {
+            if self.is_empty {
+                (0, Some(0))
+            } else {
+                (1, Some(1))
+            }
+        }
+    }
+
+    impl DoubleEndedIterator for Iter {
+        fn next_back(&mut self) -> Option<Self::Item> {
+            self.next()
+        }
+    }
+
+    // this chains an iterator of length 0 with an iterator of length 1,
+    // so after calling `.next()` once, the iterator is empty and the
+    // state is `ChainState::Back`. `.size_hint()` should now disregard
+    // the size hint of the left iterator
+    let mut iter = Iter { is_empty: true }.chain(once(()));
+    assert_eq!(iter.next(), Some(()));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+
+    let mut iter = once(()).chain(Iter { is_empty: true });
+    assert_eq!(iter.next_back(), Some(()));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+}
+
+#[test]
 fn test_zip_nth() {
     let xs = [0, 1, 2, 4, 5];
     let ys = [10, 11, 12];
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 4790152512a..6609bc3135a 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -375,6 +375,25 @@ fn test_chunks_exact_mut_nth() {
 }
 
 #[test]
+fn test_chunks_exact_mut_nth_back() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks_exact_mut(2);
+    assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
+    assert_eq!(c.next().unwrap(), &[0, 1]);
+    assert_eq!(c.next(), None);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks_exact_mut(3);
+    assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
+    assert_eq!(c2.next(), None);
+    assert_eq!(c2.next_back(), None);
+
+    let v3: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c3 = v3.chunks_exact_mut(10);
+    assert_eq!(c3.nth_back(0), None);
+}
+
+#[test]
 fn test_chunks_exact_mut_last() {
     let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
     let c = v.chunks_exact_mut(2);
diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml
index b3d0ee94f0e..187bdac8001 100644
--- a/src/libproc_macro/Cargo.toml
+++ b/src/libproc_macro/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2018"
 
 [lib]
 path = "lib.rs"
+
+[dependencies]
+std = { path = "../libstd" }
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index b3eee7c3464..a200a058f4f 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -2088,7 +2088,6 @@ generator can be constructed.
 Erroneous code example:
 
 ```edition2018,compile-fail,E0698
-#![feature(async_await)]
 async fn bar<T>() -> () {}
 
 async fn foo() {
@@ -2101,7 +2100,6 @@ To fix this you must bind `T` to a concrete type such as `String`
 so that a generator can then be constructed:
 
 ```edition2018
-#![feature(async_await)]
 async fn bar<T>() -> () {}
 
 async fn foo() {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 7292428ec37..f80e527dfd9 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -514,8 +514,7 @@ impl<'hir> Map<'hir> {
         &self.forest.krate.attrs
     }
 
-    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId)
-    {
+    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
         let hir_id = self.as_local_hir_id(module).unwrap();
         self.read(hir_id);
         match self.find_entry(hir_id).unwrap().node {
@@ -525,7 +524,7 @@ impl<'hir> Map<'hir> {
                 ..
             }) => (m, span, hir_id),
             Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
-            _ => panic!("not a module")
+            node => panic!("not a module: {:?}", node),
         }
     }
 
@@ -679,6 +678,16 @@ impl<'hir> Map<'hir> {
         }
     }
 
+    /// Wether `hir_id` corresponds to a `mod` or a crate.
+    pub fn is_hir_id_module(&self, hir_id: HirId) -> bool {
+        match self.lookup(hir_id) {
+            Some(Entry { node: Node::Item(Item { node: ItemKind::Mod(_), .. }), .. }) |
+            Some(Entry { node: Node::Crate, .. }) => true,
+            _ => false,
+        }
+    }
+
+
     /// If there is some error when walking the parents (e.g., a node does not
     /// have a parent in the map or a node can't be found), then we return the
     /// last good `HirId` we found. Note that reaching the crate root (`id == 0`),
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 7003f71c8ba..05e2c7854b4 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -402,7 +402,6 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
     parent -> _,
     call_site,
     def_site,
-    default_transparency,
     allow_internal_unstable,
     allow_internal_unsafe,
     local_inner_macros,
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 84687b8cab5..9be73cf3c6d 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1650,7 +1650,7 @@ impl<'tcx> ObligationCause<'tcx> {
                 hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
                 _ => "match arms have compatible types",
             },
-            IfExpression { .. } => "if and else have compatible types",
+            IfExpression { .. } => "if and else have incompatible types",
             IfExpressionWithNoElse => "if missing an else returns ()",
             MainFunctionType => "`main` function has the correct type",
             StartFunctionType => "`start` function has the correct type",
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index d6d17a67e01..c70006b68d6 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -247,13 +247,15 @@ impl<'tcx> ty::TyS<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    pub fn note_and_explain_type_err(self,
-                                     db: &mut DiagnosticBuilder<'_>,
-                                     err: &TypeError<'tcx>,
-                                     sp: Span) {
+    pub fn note_and_explain_type_err(
+        self,
+        db: &mut DiagnosticBuilder<'_>,
+        err: &TypeError<'tcx>,
+        sp: Span,
+    ) {
         use self::TypeError::*;
 
-        match err.clone() {
+        match err {
             Sorts(values) => {
                 let expected_str = values.expected.sort_string(self);
                 let found_str = values.found.sort_string(self);
@@ -261,6 +263,16 @@ impl<'tcx> TyCtxt<'tcx> {
                     db.note("no two closures, even if identical, have the same type");
                     db.help("consider boxing your closure and/or using it as a trait object");
                 }
+                if expected_str == found_str && expected_str == "opaque type" { // Issue #63167
+                    db.note("distinct uses of `impl Trait` result in different opaque types");
+                    let e_str = values.expected.to_string();
+                    let f_str = values.found.to_string();
+                    if &e_str == &f_str && &e_str == "impl std::future::Future" {
+                        // FIXME: use non-string based check.
+                        db.help("if both `Future`s have the same `Output` type, consider \
+                                 `.await`ing on both of them");
+                    }
+                }
                 if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
                        (&values.found.sty, &values.expected.sty) // Issue #53280
                 {
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 8bf01970eb5..c21639d0dca 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -23,7 +23,7 @@ use std::mem;
 use syntax::ast::NodeId;
 use syntax::source_map::{SourceMap, StableSourceFileId};
 use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
-use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData};
+use syntax_pos::hygiene::{ExpnId, SyntaxContext};
 
 const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
 
@@ -593,8 +593,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
         // don't seem to be used after HIR lowering, so everything should be fine
         // as long as incremental compilation does not kick in before that.
         let location = || Span::with_root_ctxt(lo, hi);
-        let recover_from_expn_data = |this: &Self, expn_data, pos| {
-            let span = location().fresh_expansion(expn_data);
+        let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| {
+            let span = location().fresh_expansion_with_transparency(expn_data, transparency);
             this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
             span
         };
@@ -603,9 +603,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
                 location()
             }
             TAG_EXPN_DATA_INLINE => {
-                let expn_data = Decodable::decode(self)?;
+                let (expn_data, transparency) = Decodable::decode(self)?;
                 recover_from_expn_data(
-                    self, expn_data, AbsoluteBytePos::new(self.opaque.position())
+                    self, expn_data, transparency, AbsoluteBytePos::new(self.opaque.position())
                 )
             }
             TAG_EXPN_DATA_SHORTHAND => {
@@ -614,9 +614,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
                 if let Some(ctxt) = cached_ctxt {
                     Span::new(lo, hi, ctxt)
                 } else {
-                    let expn_data =
-                        self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?;
-                    recover_from_expn_data(self, expn_data, pos)
+                    let (expn_data, transparency) =
+                        self.with_position(pos.to_usize(), |this| Decodable::decode(this))?;
+                    recover_from_expn_data(self, expn_data, transparency, pos)
                 }
             }
             _ => {
@@ -819,7 +819,7 @@ where
         if span_data.ctxt == SyntaxContext::root() {
             TAG_NO_EXPN_DATA.encode(self)
         } else {
-            let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data();
+            let (expn_id, transparency, expn_data) = span_data.ctxt.outer_mark_with_data();
             if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
                 TAG_EXPN_DATA_SHORTHAND.encode(self)?;
                 pos.encode(self)
@@ -827,7 +827,7 @@ where
                 TAG_EXPN_DATA_INLINE.encode(self)?;
                 let pos = AbsoluteBytePos::new(self.position());
                 self.expn_data_shorthands.insert(expn_id, pos);
-                expn_data.encode(self)
+                (expn_data, transparency).encode(self)
             }
         }
     }
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 945e3e158ea..565447dd7e1 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
 use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
+use crate::mir::interpret::{ConstValue, Scalar};
 use std::rc::Rc;
 use std::iter;
 use rustc_target::spec::abi;
@@ -551,26 +551,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
     let tcx = relation.tcx();
 
     let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
-        if let ConstValue::Unevaluated(def_id, substs) = x.val {
-            // FIXME(eddyb) get the right param_env.
-            let param_env = ty::ParamEnv::empty();
-            if !substs.has_local_value() {
-                let instance = ty::Instance::resolve(
-                    tcx.global_tcx(),
-                    param_env,
-                    def_id,
-                    substs,
-                );
-                if let Some(instance) = instance {
-                    let cid = GlobalId {
-                        instance,
-                        promoted: None,
-                    };
-                    if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
-                        return ct.val;
-                    }
-                }
-            }
+        if !x.val.has_local_value() {
+            return x.eval(tcx, relation.param_env()).val;
         }
         x.val
     };
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 2b173068b38..da66fdf5b1b 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -2299,23 +2299,33 @@ impl<'tcx> Const<'tcx> {
         assert_eq!(self.ty, ty);
         // if `ty` does not depend on generic parameters, use an empty param_env
         let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
+        self.eval(tcx, param_env).val.try_to_bits(size)
+    }
+
+    #[inline]
+    pub fn eval(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        param_env: ParamEnv<'tcx>,
+    ) -> &Const<'tcx> {
+        // FIXME(const_generics): this doesn't work right now,
+        // because it tries to relate an `Infer` to a `Param`.
         match self.val {
-            // FIXME(const_generics): this doesn't work right now,
-            // because it tries to relate an `Infer` to a `Param`.
             ConstValue::Unevaluated(did, substs) => {
                 // if `substs` has no unresolved components, use and empty param_env
                 let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts();
                 // try to resolve e.g. associated constants to their definition on an impl
-                let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
+                let instance = match ty::Instance::resolve(tcx, param_env, did, substs) {
+                    Some(instance) => instance,
+                    None => return self,
+                };
                 let gid = GlobalId {
                     instance,
                     promoted: None,
                 };
-                let evaluated = tcx.const_eval(param_env.and(gid)).ok()?;
-                evaluated.val.try_to_bits(size)
+                tcx.const_eval(param_env.and(gid)).unwrap_or(self)
             },
-            // otherwise just extract a `ConstValue`'s bits if possible
-            _ => self.val.try_to_bits(size),
+            _ => self,
         }
     }
 
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index f7a423092ac..b030517e28e 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -20,6 +20,7 @@ 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_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" }
diff --git a/src/librustc_driver/args.rs b/src/librustc_driver/args.rs
new file mode 100644
index 00000000000..0906d358bad
--- /dev/null
+++ b/src/librustc_driver/args.rs
@@ -0,0 +1,53 @@
+use std::error;
+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
+            }
+            Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
+                return Err(Error::Utf8Error(Some(path.to_string())));
+            }
+            Err(err) => return Err(Error::IOError(path.to_string(), err)),
+        };
+        Ok(file.lines().map(ToString::to_string).collect())
+    } else {
+        Ok(vec![arg])
+    }
+}
+
+#[derive(Debug)]
+pub enum Error {
+    Utf8Error(Option<String>),
+    IOError(String, io::Error),
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
+            Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path),
+            Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err),
+        }
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &'static str {
+        "argument error"
+    }
+}
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index b19ea513b75..e7712ae115f 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -68,6 +68,7 @@ use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
 
 pub mod pretty;
+mod args;
 
 /// Exit status code used for successful compilation and help output.
 pub const EXIT_SUCCESS: i32 = 0;
@@ -141,14 +142,22 @@ impl Callbacks for TimePassesCallbacks {
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
 pub fn run_compiler(
-    args: &[String],
+    at_args: &[String],
     callbacks: &mut (dyn Callbacks + Send),
     file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
     emitter: Option<Box<dyn Write + Send>>
 ) -> interface::Result<()> {
+    let mut args = Vec::new();
+    for arg in at_args {
+        match args::arg_expand(arg.clone()) {
+            Ok(arg) => args.extend(arg),
+            Err(err) => early_error(ErrorOutputType::default(),
+                &format!("Failed to load argument file: {}", err)),
+        }
+    }
     let diagnostic_output = emitter.map(|emitter| DiagnosticOutput::Raw(emitter))
                                    .unwrap_or(DiagnosticOutput::Default);
-    let matches = match handle_options(args) {
+    let matches = match handle_options(&args) {
         Some(matches) => matches,
         None => return Ok(()),
     };
@@ -779,13 +788,19 @@ fn usage(verbose: bool, include_unstable_options: bool) {
     } else {
         "\n    --help -v           Print the full set of options rustc accepts"
     };
-    println!("{}\nAdditional help:
+    let at_path = if verbose && nightly_options::is_nightly_build() {
+        "    @path               Read newline separated options from `path`\n"
+    } else {
+        ""
+    };
+    println!("{options}{at_path}\nAdditional help:
     -C help             Print codegen options
     -W help             \
-              Print 'lint' options and default settings{}{}\n",
-             options.usage(message),
-             nightly_help,
-             verbose_help);
+              Print 'lint' options and default settings{nightly}{verbose}\n",
+             options = options.usage(message),
+             at_path = at_path,
+             nightly = nightly_help,
+             verbose = verbose_help);
 }
 
 fn print_wall_help() {
@@ -1010,6 +1025,12 @@ 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));
@@ -1190,7 +1211,7 @@ pub fn main() {
     let result = report_ices_to_stderr_if_any(|| {
         let args = env::args_os().enumerate()
             .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
-                early_error(ErrorOutputType::default(),
+                    early_error(ErrorOutputType::default(),
                             &format!("Argument {} is not valid Unicode: {:?}", i, arg))
             }))
             .collect::<Vec<_>>();
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 792922a1837..efc77699313 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -68,9 +68,9 @@ pub struct CrateMetadata {
     pub alloc_decoding_state: AllocDecodingState,
 
     // NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
-    // lifetime is only used behind `Lazy` / `LazySeq`, and therefore
-    // acts like an universal (`for<'tcx>`), that is paired up with
-    // whichever `TyCtxt` is being used to decode those values.
+    // 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.
     pub root: schema::CrateRoot<'static>,
 
     /// For each definition in this crate, we encode a key. When the
@@ -80,7 +80,7 @@ pub struct CrateMetadata {
     /// compilation support.
     pub def_path_table: Lrc<DefPathTable>,
 
-    pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>,
+    pub trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
 
     pub dep_kind: Lock<DepKind>,
     pub source: CrateSource,
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index d29592a5d68..da96728d2de 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -134,14 +134,14 @@ impl<'a, 'tcx, T: Decodable> Lazy<T> {
     }
 }
 
-impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> LazySeq<T> {
+impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> {
     pub fn decode<M: Metadata<'a, 'tcx>>(
         self,
         meta: M,
     ) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
         let mut dcx = meta.decoder(self.position);
         dcx.lazy_state = LazyState::NodeStart(self.position);
-        (0..self.len).map(move |_| T::decode(&mut dcx).unwrap())
+        (0..self.meta).map(move |_| T::decode(&mut dcx).unwrap())
     }
 }
 
@@ -154,10 +154,14 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
         self.cdata.expect("missing CrateMetadata in DecodeContext")
     }
 
-    fn read_lazy_distance(&mut self, min_size: usize) -> Result<usize, <Self as Decoder>::Error> {
+    fn read_lazy_with_meta<T: ?Sized + LazyMeta>(
+        &mut self,
+        meta: T::Meta,
+    ) -> Result<Lazy<T>, <Self as Decoder>::Error> {
+        let min_size = T::min_size(meta);
         let distance = self.read_usize()?;
         let position = match self.lazy_state {
-            LazyState::NoNode => bug!("read_lazy_distance: outside of a metadata node"),
+            LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
             LazyState::NodeStart(start) => {
                 assert!(distance + min_size <= start);
                 start - distance - min_size
@@ -165,7 +169,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
             LazyState::Previous(last_min_end) => last_min_end + distance,
         };
         self.lazy_state = LazyState::Previous(position + min_size);
-        Ok(position)
+        Ok(Lazy::from_position_and_meta(position, meta))
     }
 }
 
@@ -230,19 +234,18 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
 
 impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> {
-        Ok(Lazy::with_position(self.read_lazy_distance(Lazy::<T>::min_size())?))
+        self.read_lazy_with_meta(())
     }
 }
 
-impl<'a, 'tcx, T> SpecializedDecoder<LazySeq<T>> for DecodeContext<'a, 'tcx> {
-    fn specialized_decode(&mut self) -> Result<LazySeq<T>, Self::Error> {
+impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> {
         let len = self.read_usize()?;
-        let position = if len == 0 {
-            0
+        if len == 0 {
+            Ok(Lazy::empty())
         } else {
-            self.read_lazy_distance(LazySeq::<T>::min_size(len))?
-        };
-        Ok(LazySeq::with_position_and_length(position, len))
+            self.read_lazy_with_meta(len)
+        }
     }
 }
 
@@ -378,7 +381,7 @@ impl<'tcx> MetadataBlob {
     }
 
     pub fn get_rustc_version(&self) -> String {
-        Lazy::with_position(METADATA_HEADER.len() + 4).decode(self)
+        Lazy::<String>::from_position(METADATA_HEADER.len() + 4).decode(self)
     }
 
     pub fn get_root(&self) -> CrateRoot<'tcx> {
@@ -387,7 +390,7 @@ impl<'tcx> MetadataBlob {
         let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) |
                    ((slice[offset + 2] as u32) << 8) |
                    ((slice[offset + 3] as u32) << 0)) as usize;
-        Lazy::with_position(pos).decode(self)
+        Lazy::<CrateRoot<'tcx>>::from_position(pos).decode(self)
     }
 
     pub fn list_crate_metadata(&self,
@@ -1140,7 +1143,7 @@ impl<'a, 'tcx> CrateMetadata {
             EntryKind::Fn(data) |
             EntryKind::ForeignFn(data) => data.decode(self).arg_names,
             EntryKind::Method(data) => data.decode(self).fn_data.arg_names,
-            _ => LazySeq::empty(),
+            _ => Lazy::empty(),
         };
         arg_names.decode(self).collect()
     }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 6058ae99cf4..df3320c64a9 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -98,17 +98,17 @@ impl<'tcx> Encoder for EncodeContext<'tcx> {
 
 impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
     fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
-        self.emit_lazy_distance(lazy.position, Lazy::<T>::min_size())
+        self.emit_lazy_distance(*lazy)
     }
 }
 
-impl<'tcx, T> SpecializedEncoder<LazySeq<T>> for EncodeContext<'tcx> {
-    fn specialized_encode(&mut self, seq: &LazySeq<T>) -> Result<(), Self::Error> {
-        self.emit_usize(seq.len)?;
-        if seq.len == 0 {
+impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
+    fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
+        self.emit_usize(lazy.meta)?;
+        if lazy.meta == 0 {
             return Ok(());
         }
-        self.emit_lazy_distance(seq.position, LazySeq::<T>::min_size(seq.len))
+        self.emit_lazy_distance(*lazy)
     }
 }
 
@@ -239,21 +239,38 @@ impl<'tcx> TyEncoder for EncodeContext<'tcx> {
     }
 }
 
-impl<'tcx> EncodeContext<'tcx> {
-    fn emit_node<F: FnOnce(&mut Self, usize) -> R, R>(&mut self, f: F) -> R {
-        assert_eq!(self.lazy_state, LazyState::NoNode);
-        let pos = self.position();
-        self.lazy_state = LazyState::NodeStart(pos);
-        let r = f(self, pos);
-        self.lazy_state = LazyState::NoNode;
-        r
+/// Helper trait to allow overloading `EncodeContext::lazy` for iterators.
+trait EncodeContentsForLazy<T: ?Sized + LazyMeta> {
+    fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> T::Meta;
+}
+
+impl<T: Encodable> EncodeContentsForLazy<T> for &T {
+    fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) {
+        self.encode(ecx).unwrap()
+    }
+}
+
+impl<T: Encodable> EncodeContentsForLazy<T> for T {
+    fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) {
+        self.encode(ecx).unwrap()
+    }
+}
+
+impl<I, T> EncodeContentsForLazy<[T]> for I
+    where I: IntoIterator,
+          I::Item: EncodeContentsForLazy<T>,
+{
+    fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> usize {
+        self.into_iter().map(|value| value.encode_contents_for_lazy(ecx)).count()
     }
+}
 
-    fn emit_lazy_distance(&mut self,
-                          position: usize,
-                          min_size: usize)
-                          -> Result<(), <Self as Encoder>::Error> {
-        let min_end = position + min_size;
+impl<'tcx> EncodeContext<'tcx> {
+    fn emit_lazy_distance<T: ?Sized + LazyMeta>(
+        &mut self,
+        lazy: Lazy<T>,
+    ) -> Result<(), <Self as Encoder>::Error> {
+        let min_end = lazy.position + T::min_size(lazy.meta);
         let distance = match self.lazy_state {
             LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"),
             LazyState::NodeStart(start) => {
@@ -262,48 +279,31 @@ impl<'tcx> EncodeContext<'tcx> {
             }
             LazyState::Previous(last_min_end) => {
                 assert!(
-                    last_min_end <= position,
+                    last_min_end <= lazy.position,
                     "make sure that the calls to `lazy*` \
                     are in the same order as the metadata fields",
                 );
-                position - last_min_end
+                lazy.position - last_min_end
             }
         };
         self.lazy_state = LazyState::Previous(min_end);
         self.emit_usize(distance)
     }
 
-    pub fn lazy<T: Encodable>(&mut self, value: &T) -> Lazy<T> {
-        self.emit_node(|ecx, pos| {
-            value.encode(ecx).unwrap();
-
-            assert!(pos + Lazy::<T>::min_size() <= ecx.position());
-            Lazy::with_position(pos)
-        })
-    }
-
-    pub fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T>
-        where I: IntoIterator<Item = T>,
-              T: Encodable
-    {
-        self.emit_node(|ecx, pos| {
-            let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count();
+    fn lazy<T: ?Sized + LazyMeta>(
+        &mut self,
+        value: impl EncodeContentsForLazy<T>,
+    ) -> Lazy<T> {
+        let pos = self.position();
 
-            assert!(pos + LazySeq::<T>::min_size(len) <= ecx.position());
-            LazySeq::with_position_and_length(pos, len)
-        })
-    }
+        assert_eq!(self.lazy_state, LazyState::NoNode);
+        self.lazy_state = LazyState::NodeStart(pos);
+        let meta = value.encode_contents_for_lazy(self);
+        self.lazy_state = LazyState::NoNode;
 
-    pub fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T>
-        where I: IntoIterator<Item = &'b T>,
-              T: 'b + Encodable
-    {
-        self.emit_node(|ecx, pos| {
-            let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count();
+        assert!(pos + <T>::min_size(meta) <= self.position());
 
-            assert!(pos + LazySeq::<T>::min_size(len) <= ecx.position());
-            LazySeq::with_position_and_length(pos, len)
-        })
+        Lazy::from_position_and_meta(pos, meta)
     }
 
     /// Emit the data for a `DefId` to the metadata. The function to
@@ -320,7 +320,7 @@ impl<'tcx> EncodeContext<'tcx> {
         assert!(id.is_local());
 
         let entry = op(self, data);
-        let entry = self.lazy(&entry);
+        let entry = self.lazy(entry);
         self.entries_index.record(id, entry);
     }
 
@@ -341,7 +341,7 @@ impl<'tcx> EncodeContext<'tcx> {
         self.lazy(definitions.def_path_table())
     }
 
-    fn encode_source_map(&mut self) -> LazySeq<syntax_pos::SourceFile> {
+    fn encode_source_map(&mut self) -> Lazy<[syntax_pos::SourceFile]> {
         let source_map = self.tcx.sess.source_map();
         let all_source_files = source_map.files();
 
@@ -380,7 +380,7 @@ impl<'tcx> EncodeContext<'tcx> {
             })
             .collect::<Vec<_>>();
 
-        self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
+        self.lazy(adapted.iter().map(|rc| &**rc))
     }
 
     fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
@@ -463,7 +463,7 @@ impl<'tcx> EncodeContext<'tcx> {
                 }
                 n = new_n;
             }
-            self.lazy_seq(interpret_alloc_index)
+            self.lazy(interpret_alloc_index)
         };
 
 
@@ -482,8 +482,7 @@ impl<'tcx> EncodeContext<'tcx> {
         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 {
+        let root = self.lazy(CrateRoot {
             name: tcx.crate_name(LOCAL_CRATE),
             extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
             triple: tcx.sess.opts.target_triple.clone(),
@@ -562,17 +561,17 @@ impl<'tcx> EncodeContext<'tcx> {
 }
 
 impl EncodeContext<'tcx> {
-    fn encode_variances_of(&mut self, def_id: DefId) -> LazySeq<ty::Variance> {
+    fn encode_variances_of(&mut self, def_id: DefId) -> Lazy<[ty::Variance]> {
         debug!("EncodeContext::encode_variances_of({:?})", def_id);
         let tcx = self.tcx;
-        self.lazy_seq_ref(&tcx.variances_of(def_id)[..])
+        self.lazy(&tcx.variances_of(def_id)[..])
     }
 
     fn encode_item_type(&mut self, def_id: DefId) -> Lazy<Ty<'tcx>> {
         let tcx = self.tcx;
         let ty = tcx.type_of(def_id);
         debug!("EncodeContext::encode_item_type({:?}) => {:?}", def_id, ty);
-        self.lazy(&ty)
+        self.lazy(ty)
     }
 
     fn encode_enum_variant_info(
@@ -601,11 +600,11 @@ impl EncodeContext<'tcx> {
         let enum_vis = &tcx.hir().expect_item(enum_id).vis;
 
         Entry {
-            kind: EntryKind::Variant(self.lazy(&data)),
-            visibility: self.lazy(&ty::Visibility::from_hir(enum_vis, enum_id, tcx)),
-            span: self.lazy(&tcx.def_span(def_id)),
+            kind: EntryKind::Variant(self.lazy(data)),
+            visibility: self.lazy(ty::Visibility::from_hir(enum_vis, enum_id, tcx)),
+            span: self.lazy(tcx.def_span(def_id)),
             attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
-            children: self.lazy_seq(variant.fields.iter().map(|f| {
+            children: self.lazy(variant.fields.iter().map(|f| {
                 assert!(f.did.is_local());
                 f.did.index
             })),
@@ -613,11 +612,11 @@ impl EncodeContext<'tcx> {
             deprecation: self.encode_deprecation(def_id),
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
             variances: if variant.ctor_kind == CtorKind::Fn {
                 self.encode_variances_of(def_id)
             } else {
-                LazySeq::empty()
+                Lazy::empty()
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
@@ -642,7 +641,7 @@ impl EncodeContext<'tcx> {
             discr: variant.discr,
             ctor: Some(def_id.index),
             ctor_sig: if variant.ctor_kind == CtorKind::Fn {
-                Some(self.lazy(&tcx.fn_sig(def_id)))
+                Some(self.lazy(tcx.fn_sig(def_id)))
             } else {
                 None
             }
@@ -658,20 +657,20 @@ impl EncodeContext<'tcx> {
         }
 
         Entry {
-            kind: EntryKind::Variant(self.lazy(&data)),
-            visibility: self.lazy(&ctor_vis),
-            span: self.lazy(&tcx.def_span(def_id)),
-            attributes: LazySeq::empty(),
-            children: LazySeq::empty(),
+            kind: EntryKind::Variant(self.lazy(data)),
+            visibility: self.lazy(ctor_vis),
+            span: self.lazy(tcx.def_span(def_id)),
+            attributes: Lazy::empty(),
+            children: Lazy::empty(),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
             variances: if variant.ctor_kind == CtorKind::Fn {
                 self.encode_variances_of(def_id)
             } else {
-                LazySeq::empty()
+                Lazy::empty()
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
@@ -691,25 +690,25 @@ impl EncodeContext<'tcx> {
 
         let data = ModData {
             reexports: match tcx.module_exports(def_id) {
-                Some(exports) => self.lazy_seq_ref(exports),
-                _ => LazySeq::empty(),
+                Some(exports) => self.lazy(exports),
+                _ => Lazy::empty(),
             },
         };
 
         Entry {
-            kind: EntryKind::Mod(self.lazy(&data)),
-            visibility: self.lazy(&ty::Visibility::from_hir(vis, id, tcx)),
-            span: self.lazy(&tcx.def_span(def_id)),
+            kind: EntryKind::Mod(self.lazy(data)),
+            visibility: self.lazy(ty::Visibility::from_hir(vis, id, tcx)),
+            span: self.lazy(tcx.def_span(def_id)),
             attributes: self.encode_attributes(attrs),
-            children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
+            children: self.lazy(md.item_ids.iter().map(|item_id| {
                 tcx.hir().local_def_id(item_id.id).index
             })),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
             ty: None,
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
+            variances: Lazy::empty(),
             generics: None,
             predicates: None,
             predicates_defined_on: None,
@@ -734,16 +733,16 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind: EntryKind::Field,
-            visibility: self.lazy(&field.vis),
-            span: self.lazy(&tcx.def_span(def_id)),
+            visibility: self.lazy(field.vis),
+            span: self.lazy(tcx.def_span(def_id)),
             attributes: self.encode_attributes(&variant_data.fields()[field_index].attrs),
-            children: LazySeq::empty(),
+            children: Lazy::empty(),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
+            variances: Lazy::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
             predicates_defined_on: None,
@@ -763,7 +762,7 @@ impl EncodeContext<'tcx> {
             discr: variant.discr,
             ctor: Some(def_id.index),
             ctor_sig: if variant.ctor_kind == CtorKind::Fn {
-                Some(self.lazy(&tcx.fn_sig(def_id)))
+                Some(self.lazy(tcx.fn_sig(def_id)))
             } else {
                 None
             }
@@ -789,20 +788,20 @@ impl EncodeContext<'tcx> {
         let repr_options = get_repr_options(tcx, adt_def_id);
 
         Entry {
-            kind: EntryKind::Struct(self.lazy(&data), repr_options),
-            visibility: self.lazy(&ctor_vis),
-            span: self.lazy(&tcx.def_span(def_id)),
-            attributes: LazySeq::empty(),
-            children: LazySeq::empty(),
+            kind: EntryKind::Struct(self.lazy(data), repr_options),
+            visibility: self.lazy(ctor_vis),
+            span: self.lazy(tcx.def_span(def_id)),
+            attributes: Lazy::empty(),
+            children: Lazy::empty(),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
             variances: if variant.ctor_kind == CtorKind::Fn {
                 self.encode_variances_of(def_id)
             } else {
-                LazySeq::empty()
+                Lazy::empty()
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
@@ -821,13 +820,13 @@ impl EncodeContext<'tcx> {
     fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
         debug!("EncodeContext::encode_predicates({:?})", def_id);
         let tcx = self.tcx;
-        self.lazy(&tcx.predicates_of(def_id))
+        self.lazy(&*tcx.predicates_of(def_id))
     }
 
     fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
         debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
         let tcx = self.tcx;
-        self.lazy(&tcx.predicates_defined_on(def_id))
+        self.lazy(&*tcx.predicates_defined_on(def_id))
     }
 
     fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
@@ -858,7 +857,7 @@ impl EncodeContext<'tcx> {
 
                 let rendered =
                     hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item));
-                let rendered_const = self.lazy(&RenderedConst(rendered));
+                let rendered_const = self.lazy(RenderedConst(rendered));
 
                 EntryKind::AssocConst(container, const_qualif, rendered_const)
             }
@@ -875,12 +874,12 @@ impl EncodeContext<'tcx> {
                     FnData {
                         constness: hir::Constness::NotConst,
                         arg_names,
-                        sig: self.lazy(&tcx.fn_sig(def_id)),
+                        sig: self.lazy(tcx.fn_sig(def_id)),
                     }
                 } else {
                     bug!()
                 };
-                EntryKind::Method(self.lazy(&MethodData {
+                EntryKind::Method(self.lazy(MethodData {
                     fn_data,
                     container,
                     has_self: trait_item.method_has_self_argument,
@@ -892,10 +891,10 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind,
-            visibility: self.lazy(&trait_item.vis),
-            span: self.lazy(&ast_item.span),
+            visibility: self.lazy(trait_item.vis),
+            span: self.lazy(ast_item.span),
             attributes: self.encode_attributes(&ast_item.attrs),
-            children: LazySeq::empty(),
+            children: Lazy::empty(),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
@@ -913,11 +912,11 @@ impl EncodeContext<'tcx> {
                 }
                 ty::AssocKind::OpaqueTy => unreachable!(),
             },
-            inherent_impls: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
             variances: if trait_item.kind == ty::AssocKind::Method {
                 self.encode_variances_of(def_id)
             } else {
-                LazySeq::empty()
+                Lazy::empty()
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
@@ -971,12 +970,12 @@ impl EncodeContext<'tcx> {
                     FnData {
                         constness: sig.header.constness,
                         arg_names: self.encode_fn_arg_names_for_body(body),
-                        sig: self.lazy(&tcx.fn_sig(def_id)),
+                        sig: self.lazy(tcx.fn_sig(def_id)),
                     }
                 } else {
                     bug!()
                 };
-                EntryKind::Method(self.lazy(&MethodData {
+                EntryKind::Method(self.lazy(MethodData {
                     fn_data,
                     container,
                     has_self: impl_item.method_has_self_argument,
@@ -1004,19 +1003,19 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind,
-            visibility: self.lazy(&impl_item.vis),
-            span: self.lazy(&ast_item.span),
+            visibility: self.lazy(impl_item.vis),
+            span: self.lazy(ast_item.span),
             attributes: self.encode_attributes(&ast_item.attrs),
-            children: LazySeq::empty(),
+            children: Lazy::empty(),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
             variances: if impl_item.kind == ty::AssocKind::Method {
                 self.encode_variances_of(def_id)
             } else {
-                LazySeq::empty()
+                Lazy::empty()
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
@@ -1027,10 +1026,10 @@ impl EncodeContext<'tcx> {
     }
 
     fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
-                                    -> LazySeq<ast::Name> {
+                                    -> Lazy<[ast::Name]> {
         self.tcx.dep_graph.with_ignore(|| {
             let body = self.tcx.hir().body(body_id);
-            self.lazy_seq(body.arguments.iter().map(|arg| {
+            self.lazy(body.arguments.iter().map(|arg| {
                 match arg.pat.node {
                     PatKind::Binding(_, _, ident, _) => ident.name,
                     _ => kw::Invalid,
@@ -1039,28 +1038,28 @@ impl EncodeContext<'tcx> {
         })
     }
 
-    fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> LazySeq<ast::Name> {
-        self.lazy_seq(param_names.iter().map(|ident| ident.name))
+    fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> Lazy<[ast::Name]> {
+        self.lazy(param_names.iter().map(|ident| ident.name))
     }
 
     fn encode_optimized_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Body<'tcx>>> {
         debug!("EntryBuilder::encode_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
             let mir = self.tcx.optimized_mir(def_id);
-            Some(self.lazy(&mir))
+            Some(self.lazy(mir))
         } else {
             None
         }
     }
 
     // Encodes the inherent implementations of a structure, enumeration, or trait.
-    fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> {
+    fn encode_inherent_implementations(&mut self, def_id: DefId) -> Lazy<[DefIndex]> {
         debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
         let implementations = self.tcx.inherent_impls(def_id);
         if implementations.is_empty() {
-            LazySeq::empty()
+            Lazy::empty()
         } else {
-            self.lazy_seq(implementations.iter().map(|&def_id| {
+            self.lazy(implementations.iter().map(|&def_id| {
                 assert!(def_id.is_local());
                 def_id.index
             }))
@@ -1074,7 +1073,7 @@ impl EncodeContext<'tcx> {
 
     fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> {
         debug!("EncodeContext::encode_deprecation({:?})", def_id);
-        self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
+        self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(depr))
     }
 
     fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy<RenderedConst> {
@@ -1103,10 +1102,10 @@ impl EncodeContext<'tcx> {
                 let data = FnData {
                     constness: header.constness,
                     arg_names: self.encode_fn_arg_names_for_body(body),
-                    sig: self.lazy(&tcx.fn_sig(def_id)),
+                    sig: self.lazy(tcx.fn_sig(def_id)),
                 };
 
-                EntryKind::Fn(self.lazy(&data))
+                EntryKind::Fn(self.lazy(data))
             }
             hir::ItemKind::Mod(ref m) => {
                 return self.encode_info_for_mod((item.hir_id, m, &item.attrs, &item.vis));
@@ -1127,7 +1126,7 @@ impl EncodeContext<'tcx> {
 
                 let repr_options = get_repr_options(tcx, def_id);
 
-                EntryKind::Struct(self.lazy(&VariantData {
+                EntryKind::Struct(self.lazy(VariantData {
                     ctor_kind: variant.ctor_kind,
                     discr: variant.discr,
                     ctor,
@@ -1138,7 +1137,7 @@ impl EncodeContext<'tcx> {
                 let variant = tcx.adt_def(def_id).non_enum_variant();
                 let repr_options = get_repr_options(tcx, def_id);
 
-                EntryKind::Union(self.lazy(&VariantData {
+                EntryKind::Union(self.lazy(VariantData {
                     ctor_kind: variant.ctor_kind,
                     discr: variant.discr,
                     ctor: None,
@@ -1175,10 +1174,10 @@ impl EncodeContext<'tcx> {
                     defaultness,
                     parent_impl: parent,
                     coerce_unsized_info,
-                    trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)),
+                    trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)),
                 };
 
-                EntryKind::Impl(self.lazy(&data))
+                EntryKind::Impl(self.lazy(data))
             }
             hir::ItemKind::Trait(..) => {
                 let trait_def = tcx.trait_def(def_id);
@@ -1187,17 +1186,17 @@ impl EncodeContext<'tcx> {
                     paren_sugar: trait_def.paren_sugar,
                     has_auto_impl: tcx.trait_is_auto(def_id),
                     is_marker: trait_def.is_marker,
-                    super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
+                    super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)),
                 };
 
-                EntryKind::Trait(self.lazy(&data))
+                EntryKind::Trait(self.lazy(data))
             }
             hir::ItemKind::TraitAlias(..) => {
                 let data = TraitAliasData {
-                    super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
+                    super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)),
                 };
 
-                EntryKind::TraitAlias(self.lazy(&data))
+                EntryKind::TraitAlias(self.lazy(data))
             }
             hir::ItemKind::ExternCrate(_) |
             hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
@@ -1205,19 +1204,19 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind,
-            visibility: self.lazy(&ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)),
-            span: self.lazy(&item.span),
+            visibility: self.lazy(ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)),
+            span: self.lazy(item.span),
             attributes: self.encode_attributes(&item.attrs),
             children: match item.node {
                 hir::ItemKind::ForeignMod(ref fm) => {
-                    self.lazy_seq(fm.items
+                    self.lazy(fm.items
                         .iter()
                         .map(|foreign_item| tcx.hir().local_def_id(
                             foreign_item.hir_id).index))
                 }
                 hir::ItemKind::Enum(..) => {
                     let def = self.tcx.adt_def(def_id);
-                    self.lazy_seq(def.variants.iter().map(|v| {
+                    self.lazy(def.variants.iter().map(|v| {
                         assert!(v.def_id.is_local());
                         v.def_id.index
                     }))
@@ -1225,19 +1224,19 @@ impl EncodeContext<'tcx> {
                 hir::ItemKind::Struct(..) |
                 hir::ItemKind::Union(..) => {
                     let def = self.tcx.adt_def(def_id);
-                    self.lazy_seq(def.non_enum_variant().fields.iter().map(|f| {
+                    self.lazy(def.non_enum_variant().fields.iter().map(|f| {
                         assert!(f.did.is_local());
                         f.did.index
                     }))
                 }
                 hir::ItemKind::Impl(..) |
                 hir::ItemKind::Trait(..) => {
-                    self.lazy_seq(tcx.associated_item_def_ids(def_id).iter().map(|&def_id| {
+                    self.lazy(tcx.associated_item_def_ids(def_id).iter().map(|&def_id| {
                         assert!(def_id.is_local());
                         def_id.index
                     }))
                 }
-                _ => LazySeq::empty(),
+                _ => Lazy::empty(),
             },
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
@@ -1260,7 +1259,7 @@ impl EncodeContext<'tcx> {
                 hir::ItemKind::Struct(..) |
                 hir::ItemKind::Union(..) |
                 hir::ItemKind::Fn(..) => self.encode_variances_of(def_id),
-                _ => LazySeq::empty(),
+                _ => Lazy::empty(),
             },
             generics: match item.node {
                 hir::ItemKind::Static(..) |
@@ -1333,20 +1332,20 @@ impl EncodeContext<'tcx> {
         use syntax::print::pprust;
         let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
         Entry {
-            kind: EntryKind::MacroDef(self.lazy(&MacroDef {
+            kind: EntryKind::MacroDef(self.lazy(MacroDef {
                 body: pprust::tokens_to_string(macro_def.body.clone()),
                 legacy: macro_def.legacy,
             })),
-            visibility: self.lazy(&ty::Visibility::Public),
-            span: self.lazy(&macro_def.span),
+            visibility: self.lazy(ty::Visibility::Public),
+            span: self.lazy(macro_def.span),
             attributes: self.encode_attributes(&macro_def.attrs),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
-            children: LazySeq::empty(),
+            children: Lazy::empty(),
             ty: None,
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
+            variances: Lazy::empty(),
             generics: None,
             predicates: None,
             predicates_defined_on: None,
@@ -1363,15 +1362,15 @@ impl EncodeContext<'tcx> {
         let tcx = self.tcx;
         Entry {
             kind: entry_kind,
-            visibility: self.lazy(&ty::Visibility::Public),
-            span: self.lazy(&tcx.def_span(def_id)),
-            attributes: LazySeq::empty(),
-            children: LazySeq::empty(),
+            visibility: self.lazy(ty::Visibility::Public),
+            span: self.lazy(tcx.def_span(def_id)),
+            attributes: Lazy::empty(),
+            children: Lazy::empty(),
             stability: None,
             deprecation: None,
             ty: if encode_type { Some(self.encode_item_type(def_id)) } else { None },
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
+            variances: Lazy::empty(),
             generics: None,
             predicates: None,
             predicates_defined_on: None,
@@ -1408,13 +1407,13 @@ impl EncodeContext<'tcx> {
                 let data = GeneratorData {
                     layout: layout.clone(),
                 };
-                EntryKind::Generator(self.lazy(&data))
+                EntryKind::Generator(self.lazy(data))
             }
 
             ty::Closure(def_id, substs) => {
                 let sig = substs.closure_sig(def_id, self.tcx);
-                let data = ClosureData { sig: self.lazy(&sig) };
-                EntryKind::Closure(self.lazy(&data))
+                let data = ClosureData { sig: self.lazy(sig) };
+                EntryKind::Closure(self.lazy(data))
             }
 
             _ => bug!("closure that is neither generator nor closure")
@@ -1422,16 +1421,16 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind,
-            visibility: self.lazy(&ty::Visibility::Public),
-            span: self.lazy(&tcx.def_span(def_id)),
+            visibility: self.lazy(ty::Visibility::Public),
+            span: self.lazy(tcx.def_span(def_id)),
             attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
-            children: LazySeq::empty(),
+            children: Lazy::empty(),
             stability: None,
             deprecation: None,
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
+            variances: Lazy::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: None,
             predicates_defined_on: None,
@@ -1450,16 +1449,16 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind: EntryKind::Const(self.const_qualif(mir, body_id), const_data),
-            visibility: self.lazy(&ty::Visibility::Public),
-            span: self.lazy(&tcx.def_span(def_id)),
-            attributes: LazySeq::empty(),
-            children: LazySeq::empty(),
+            visibility: self.lazy(ty::Visibility::Public),
+            span: self.lazy(tcx.def_span(def_id)),
+            attributes: Lazy::empty(),
+            children: Lazy::empty(),
             stability: None,
             deprecation: None,
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
+            variances: Lazy::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
             predicates_defined_on: None,
@@ -1468,37 +1467,37 @@ impl EncodeContext<'tcx> {
         }
     }
 
-    fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> {
-        self.lazy_seq_ref(attrs)
+    fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> Lazy<[ast::Attribute]> {
+        self.lazy(attrs)
     }
 
-    fn encode_native_libraries(&mut self) -> LazySeq<NativeLibrary> {
+    fn encode_native_libraries(&mut self) -> Lazy<[NativeLibrary]> {
         let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
-        self.lazy_seq(used_libraries.iter().cloned())
+        self.lazy(used_libraries.iter().cloned())
     }
 
-    fn encode_foreign_modules(&mut self) -> LazySeq<ForeignModule> {
+    fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> {
         let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE);
-        self.lazy_seq(foreign_modules.iter().cloned())
+        self.lazy(foreign_modules.iter().cloned())
     }
 
-    fn encode_proc_macros(&mut self) -> Option<LazySeq<DefIndex>> {
+    fn encode_proc_macros(&mut self) -> Option<Lazy<[DefIndex]>> {
         let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
         if is_proc_macro {
-            let proc_macros: Vec<_> = self.tcx.hir().krate().items.values().filter_map(|item| {
+            let tcx = self.tcx;
+            Some(self.lazy(tcx.hir().krate().items.values().filter_map(|item| {
                 if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
                     Some(item.hir_id.owner)
                 } else {
                     None
                 }
-            }).collect();
-            Some(self.lazy_seq(proc_macros))
+            })))
         } else {
             None
         }
     }
 
-    fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
+    fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> {
         let crates = self.tcx.crates();
 
         let mut deps = crates
@@ -1529,20 +1528,20 @@ impl EncodeContext<'tcx> {
         // the assumption that they are numbered 1 to n.
         // FIXME (#2166): This is not nearly enough to support correct versioning
         // but is enough to get transitive crate dependencies working.
-        self.lazy_seq_ref(deps.iter().map(|&(_, ref dep)| dep))
+        self.lazy(deps.iter().map(|&(_, ref dep)| dep))
     }
 
-    fn encode_lib_features(&mut self) -> LazySeq<(ast::Name, Option<ast::Name>)> {
+    fn encode_lib_features(&mut self) -> Lazy<[(ast::Name, Option<ast::Name>)]> {
         let tcx = self.tcx;
         let lib_features = tcx.lib_features();
-        self.lazy_seq(lib_features.to_vec())
+        self.lazy(lib_features.to_vec())
     }
 
-    fn encode_lang_items(&mut self) -> LazySeq<(DefIndex, usize)> {
+    fn encode_lang_items(&mut self) -> Lazy<[(DefIndex, usize)]> {
         let tcx = self.tcx;
         let lang_items = tcx.lang_items();
         let lang_items = lang_items.items().iter();
-        self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
+        self.lazy(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
             if let Some(def_id) = opt_def_id {
                 if def_id.is_local() {
                     return Some((def_id.index, i));
@@ -1552,13 +1551,13 @@ impl EncodeContext<'tcx> {
         }))
     }
 
-    fn encode_lang_items_missing(&mut self) -> LazySeq<lang_items::LangItem> {
+    fn encode_lang_items_missing(&mut self) -> Lazy<[lang_items::LangItem]> {
         let tcx = self.tcx;
-        self.lazy_seq_ref(&tcx.lang_items().missing)
+        self.lazy(&tcx.lang_items().missing)
     }
 
     /// Encodes an index, mapping each trait to its (local) implementations.
-    fn encode_impls(&mut self) -> LazySeq<TraitImpls> {
+    fn encode_impls(&mut self) -> Lazy<[TraitImpls]> {
         debug!("EncodeContext::encode_impls()");
         let tcx = self.tcx;
         let mut visitor = ImplVisitor {
@@ -1584,12 +1583,12 @@ impl EncodeContext<'tcx> {
 
                 TraitImpls {
                     trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
-                    impls: self.lazy_seq_ref(&impls),
+                    impls: self.lazy(&impls),
                 }
             })
             .collect();
 
-        self.lazy_seq_ref(&all_impls)
+        self.lazy(&all_impls)
     }
 
     // Encodes all symbols exported from this crate into the metadata.
@@ -1600,12 +1599,12 @@ impl EncodeContext<'tcx> {
     // definition (as that's not defined in this crate).
     fn encode_exported_symbols(&mut self,
                                exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)])
-                               -> LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
+                               -> Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]> {
         // The metadata symbol name is special. It should not show up in
         // downstream crates.
         let metadata_symbol_name = SymbolName::new(&metadata_symbol_name(self.tcx));
 
-        self.lazy_seq(exported_symbols
+        self.lazy(exported_symbols
             .iter()
             .filter(|&&(ref exported_symbol, _)| {
                 match *exported_symbol {
@@ -1618,10 +1617,10 @@ impl EncodeContext<'tcx> {
             .cloned())
     }
 
-    fn encode_dylib_dependency_formats(&mut self) -> LazySeq<Option<LinkagePreference>> {
+    fn encode_dylib_dependency_formats(&mut self) -> Lazy<[Option<LinkagePreference>]> {
         match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) {
             Some(arr) => {
-                self.lazy_seq(arr.iter().map(|slot| {
+                self.lazy(arr.iter().map(|slot| {
                     match *slot {
                         Linkage::NotLinked |
                         Linkage::IncludedFromDylib => None,
@@ -1631,7 +1630,7 @@ impl EncodeContext<'tcx> {
                     }
                 }))
             }
-            None => LazySeq::empty(),
+            None => Lazy::empty(),
         }
     }
 
@@ -1647,9 +1646,9 @@ impl EncodeContext<'tcx> {
                 let data = FnData {
                     constness: hir::Constness::NotConst,
                     arg_names: self.encode_fn_arg_names(names),
-                    sig: self.lazy(&tcx.fn_sig(def_id)),
+                    sig: self.lazy(tcx.fn_sig(def_id)),
                 };
-                EntryKind::ForeignFn(self.lazy(&data))
+                EntryKind::ForeignFn(self.lazy(data))
             }
             hir::ForeignItemKind::Static(_, hir::MutMutable) => EntryKind::ForeignMutStatic,
             hir::ForeignItemKind::Static(_, hir::MutImmutable) => EntryKind::ForeignImmStatic,
@@ -1658,18 +1657,18 @@ impl EncodeContext<'tcx> {
 
         Entry {
             kind,
-            visibility: self.lazy(&ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)),
-            span: self.lazy(&nitem.span),
+            visibility: self.lazy(ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)),
+            span: self.lazy(nitem.span),
             attributes: self.encode_attributes(&nitem.attrs),
-            children: LazySeq::empty(),
+            children: Lazy::empty(),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
 
             ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
+            inherent_impls: Lazy::empty(),
             variances: match nitem.node {
                 hir::ForeignItemKind::Fn(..) => self.encode_variances_of(def_id),
-                _ => LazySeq::empty(),
+                _ => Lazy::empty(),
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs
index dd2f59922ef..6f248f22cf2 100644
--- a/src/librustc_metadata/index.rs
+++ b/src/librustc_metadata/index.rs
@@ -108,18 +108,18 @@ impl Index<'tcx> {
         position.write_to_bytes_at(positions, array_index)
     }
 
-    pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Self> {
+    pub fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> {
         let pos = buf.position();
 
         // First we write the length of the lower range ...
         buf.emit_raw_bytes(&(self.positions.len() as u32 / 4).to_le_bytes());
         // ... then the values.
         buf.emit_raw_bytes(&self.positions);
-        LazySeq::with_position_and_length(pos as usize, self.positions.len() / 4 + 1)
+        Lazy::from_position_and_meta(pos as usize, self.positions.len() / 4 + 1)
     }
 }
 
-impl LazySeq<Index<'tcx>> {
+impl Lazy<[Index<'tcx>]> {
     /// Given the metadata, extract out the offset of a particular
     /// DefIndex (if any).
     #[inline(never)]
@@ -127,7 +127,7 @@ impl LazySeq<Index<'tcx>> {
         let bytes = &bytes[self.position..];
         debug!("Index::lookup: index={:?} len={:?}",
                def_index,
-               self.len);
+               self.meta);
 
         let position = u32::read_from_bytes_at(bytes, 1 + def_index.index());
         if position == u32::MAX {
@@ -135,7 +135,7 @@ impl LazySeq<Index<'tcx>> {
             None
         } else {
             debug!("Index::lookup: position={:?}", position);
-            Some(Lazy::with_position(position as usize))
+            Some(Lazy::from_position(position as usize))
         }
     }
 }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 13c599cf997..f37877b437e 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -41,6 +41,33 @@ pub const METADATA_VERSION: u8 = 4;
 pub const METADATA_HEADER: &[u8; 12] =
     &[0, 0, 0, 0, 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).
+pub trait LazyMeta {
+    type Meta: Copy + 'static;
+
+    /// Returns the minimum encoded size.
+    // FIXME(eddyb) Give better estimates for certain types.
+    fn min_size(meta: Self::Meta) -> usize;
+}
+
+impl<T> LazyMeta for T {
+    type Meta = ();
+
+    fn min_size(_: ()) -> usize {
+        assert_ne!(std::mem::size_of::<T>(), 0);
+        1
+    }
+}
+
+impl<T> LazyMeta for [T] {
+    type Meta = usize;
+
+    fn min_size(len: usize) -> usize {
+        len * T::min_size(())
+    }
+}
+
 /// A value of type T referred to by its absolute position
 /// in the metadata, and which can be decoded lazily.
 ///
@@ -56,40 +83,8 @@ pub const METADATA_HEADER: &[u8; 12] =
 /// Distances start at 1, as 0-byte nodes are invalid.
 /// Also invalid are nodes being referred in a different
 /// order than they were encoded in.
-#[must_use]
-pub struct Lazy<T> {
-    pub position: usize,
-    _marker: PhantomData<T>,
-}
-
-impl<T> Lazy<T> {
-    pub fn with_position(position: usize) -> Lazy<T> {
-        Lazy {
-            position,
-            _marker: PhantomData,
-        }
-    }
-
-    /// Returns the minimum encoded size of a value of type `T`.
-    // FIXME(eddyb) Give better estimates for certain types.
-    pub fn min_size() -> usize {
-        1
-    }
-}
-
-impl<T> Copy for Lazy<T> {}
-impl<T> Clone for Lazy<T> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl<T> rustc_serialize::UseSpecializedEncodable for Lazy<T> {}
-impl<T> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
-
-/// A sequence of type T referred to by its absolute position
-/// in the metadata and length, and which can be decoded lazily.
-/// The sequence is a single node for the purposes of `Lazy`.
+///
+/// # Sequences (`Lazy<[T]>`)
 ///
 /// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
 /// position, not at the position, which means that the length
@@ -100,54 +95,62 @@ impl<T> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
 /// the minimal distance the length of the sequence, i.e.
 /// it's assumed there's no 0-byte element in the sequence.
 #[must_use]
-pub struct LazySeq<T> {
-    pub len: usize,
+// FIXME(#59875) the `Meta` parameter only exists to dodge
+// invariance wrt `T` (coming from the `meta: T::Meta` field).
+pub struct Lazy<T, Meta = <T as LazyMeta>::Meta>
+    where T: ?Sized + LazyMeta<Meta = Meta>,
+          Meta: 'static + Copy,
+{
     pub position: usize,
+    pub meta: Meta,
     _marker: PhantomData<T>,
 }
 
-impl<T> LazySeq<T> {
-    pub fn empty() -> LazySeq<T> {
-        LazySeq::with_position_and_length(0, 0)
-    }
-
-    pub fn with_position_and_length(position: usize, len: usize) -> LazySeq<T> {
-        LazySeq {
-            len,
+impl<T: ?Sized + LazyMeta> Lazy<T> {
+    pub fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy<T> {
+        Lazy {
             position,
+            meta,
             _marker: PhantomData,
         }
     }
+}
+
+impl<T> Lazy<T> {
+    pub fn from_position(position: usize) -> Lazy<T> {
+        Lazy::from_position_and_meta(position, ())
+    }
+}
 
-    /// Returns the minimum encoded size of `length` values of type `T`.
-    pub fn min_size(length: usize) -> usize {
-        length
+impl<T> Lazy<[T]> {
+    pub fn empty() -> Lazy<[T]> {
+        Lazy::from_position_and_meta(0, 0)
     }
 }
 
-impl<T> Copy for LazySeq<T> {}
-impl<T> Clone for LazySeq<T> {
+impl<T: ?Sized + LazyMeta> Copy for Lazy<T> {}
+impl<T: ?Sized + LazyMeta> Clone for Lazy<T> {
     fn clone(&self) -> Self {
         *self
     }
 }
 
-impl<T> rustc_serialize::UseSpecializedEncodable for LazySeq<T> {}
-impl<T> rustc_serialize::UseSpecializedDecodable for LazySeq<T> {}
+impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedEncodable for Lazy<T> {}
+impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedDecodable for Lazy<T> {}
 
-/// Encoding / decoding state for `Lazy` and `LazySeq`.
+/// Encoding / decoding state for `Lazy`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum LazyState {
     /// Outside of a metadata node.
     NoNode,
 
-    /// Inside a metadata node, and before any `Lazy` or `LazySeq`.
+    /// Inside a metadata node, and before any `Lazy`.
     /// The position is that of the node itself.
     NodeStart(usize),
 
-    /// Inside a metadata node, with a previous `Lazy` or `LazySeq`.
+    /// Inside a metadata node, with a previous `Lazy`.
     /// The position is a conservative estimate of where that
-    /// previous `Lazy` / `LazySeq` would end (see their comments).
+    /// previous `Lazy` would end (see their comments).
     Previous(usize),
 }
 
@@ -167,24 +170,24 @@ pub struct CrateRoot<'tcx> {
     pub proc_macro_decls_static: Option<DefIndex>,
     pub proc_macro_stability: Option<attr::Stability>,
 
-    pub crate_deps: LazySeq<CrateDep>,
-    pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
-    pub lib_features: LazySeq<(Symbol, Option<Symbol>)>,
-    pub lang_items: LazySeq<(DefIndex, usize)>,
-    pub lang_items_missing: LazySeq<lang_items::LangItem>,
-    pub native_libraries: LazySeq<NativeLibrary>,
-    pub foreign_modules: LazySeq<ForeignModule>,
-    pub source_map: LazySeq<syntax_pos::SourceFile>,
+    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 native_libraries: Lazy<[NativeLibrary]>,
+    pub foreign_modules: Lazy<[ForeignModule]>,
+    pub source_map: Lazy<[syntax_pos::SourceFile]>,
     pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
-    pub impls: LazySeq<TraitImpls>,
-    pub exported_symbols: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)>,
-    pub interpret_alloc_index: LazySeq<u32>,
+    pub impls: Lazy<[TraitImpls]>,
+    pub exported_symbols: Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]>,
+    pub interpret_alloc_index: Lazy<[u32]>,
 
-    pub entries_index: LazySeq<index::Index<'tcx>>,
+    pub entries_index: Lazy<[index::Index<'tcx>]>,
 
     /// The DefIndex's of any proc macros delcared by
     /// this crate
-    pub proc_macro_data: Option<LazySeq<DefIndex>>,
+    pub proc_macro_data: Option<Lazy<[DefIndex]>>,
 
     pub compiler_builtins: bool,
     pub needs_allocator: bool,
@@ -207,7 +210,7 @@ pub struct CrateDep {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct TraitImpls {
     pub trait_id: (u32, DefIndex),
-    pub impls: LazySeq<DefIndex>,
+    pub impls: Lazy<[DefIndex]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -215,14 +218,14 @@ pub struct Entry<'tcx> {
     pub kind: EntryKind<'tcx>,
     pub visibility: Lazy<ty::Visibility>,
     pub span: Lazy<Span>,
-    pub attributes: LazySeq<ast::Attribute>,
-    pub children: LazySeq<DefIndex>,
+    pub attributes: Lazy<[ast::Attribute]>,
+    pub children: Lazy<[DefIndex]>,
     pub stability: Option<Lazy<attr::Stability>>,
     pub deprecation: Option<Lazy<attr::Deprecation>>,
 
     pub ty: Option<Lazy<Ty<'tcx>>>,
-    pub inherent_impls: LazySeq<DefIndex>,
-    pub variances: LazySeq<ty::Variance>,
+    pub inherent_impls: Lazy<[DefIndex]>,
+    pub variances: Lazy<[ty::Variance]>,
     pub generics: Option<Lazy<ty::Generics>>,
     pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
     pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>,
@@ -278,7 +281,7 @@ pub struct RenderedConst(pub String);
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct ModData {
-    pub reexports: LazySeq<def::Export<hir::HirId>>,
+    pub reexports: Lazy<[def::Export<hir::HirId>]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -290,7 +293,7 @@ pub struct MacroDef {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct FnData<'tcx> {
     pub constness: hir::Constness,
-    pub arg_names: LazySeq<ast::Name>,
+    pub arg_names: Lazy<[ast::Name]>,
     pub sig: Lazy<ty::PolyFnSig<'tcx>>,
 }
 
diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs
index cd33943e77e..a30cd8a627f 100644
--- a/src/librustc_passes/error_codes.rs
+++ b/src/librustc_passes/error_codes.rs
@@ -131,7 +131,7 @@ be taken. Erroneous code example:
 
 ```compile_fail,E0268
 fn some_func() {
-    break; // error: `break` outside of loop
+    break; // error: `break` outside of a loop
 }
 ```
 
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 1547e607b9c..dbfbec32a6f 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -16,8 +16,8 @@ use errors::Applicability;
 enum Context {
     Normal,
     Loop(hir::LoopSource),
-    Closure,
-    AsyncClosure,
+    Closure(Span),
+    AsyncClosure(Span),
     LabeledBlock,
     AnonConst,
 }
@@ -58,11 +58,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
             hir::ExprKind::Loop(ref b, _, source) => {
                 self.with_context(Loop(source), |v| v.visit_block(&b));
             }
-            hir::ExprKind::Closure(_, ref function_decl, b, _, movability) => {
+            hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => {
                 let cx = if let Some(GeneratorMovability::Static) = movability {
-                    AsyncClosure
+                    AsyncClosure(span)
                 } else {
-                    Closure
+                    Closure(span)
                 };
                 self.visit_fn_decl(&function_decl);
                 self.with_context(cx, |v| v.visit_nested_body(b));
@@ -170,23 +170,22 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
     }
 
     fn require_break_cx(&self, name: &str, span: Span) {
-        match self.cx {
-            LabeledBlock | Loop(_) => {}
-            Closure => {
-                struct_span_err!(self.sess, span, E0267, "`{}` inside of a closure", name)
-                .span_label(span, "cannot break inside of a closure")
+        let err_inside_of = |article, ty, closure_span| {
+            struct_span_err!(self.sess, span, E0267, "`{}` inside of {} {}", name, article, ty)
+                .span_label(span, format!("cannot `{}` inside of {} {}", name, article, ty))
+                .span_label(closure_span, &format!("enclosing {}", ty))
                 .emit();
-            }
-            AsyncClosure => {
-                struct_span_err!(self.sess, span, E0267, "`{}` inside of an async block", name)
-                    .span_label(span, "cannot break inside of an async block")
-                    .emit();
-            }
+        };
+
+        match self.cx {
+            LabeledBlock | Loop(_) => {},
+            Closure(closure_span) => err_inside_of("a", "closure", closure_span),
+            AsyncClosure(closure_span) => err_inside_of("an", "`async` block", closure_span),
             Normal | AnonConst => {
-                struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name)
-                .span_label(span, "cannot break outside of a loop")
+                struct_span_err!(self.sess, span, E0268, "`{}` outside of a loop", name)
+                .span_label(span, format!("cannot `{}` outside of a loop", name))
                 .emit();
-            }
+            },
         }
     }
 
diff --git a/src/librustc_plugin/deprecated/lib.rs b/src/librustc_plugin/deprecated/lib.rs
index 5fb18066759..1d0afe84c25 100644
--- a/src/librustc_plugin/deprecated/lib.rs
+++ b/src/librustc_plugin/deprecated/lib.rs
@@ -1,6 +1,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(staged_api)]
-#![unstable(feature = "rustc_plugin", issue = "29597")]
+#![unstable(feature = "rustc_private", issue = "27812")]
 #![rustc_deprecated(since = "1.38.0", reason = "\
     import this through `rustc_driver::plugin` instead to make TLS work correctly. \
     See https://github.com/rust-lang/rust/issues/62717")]
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index bca77621e55..146058963b6 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -508,11 +508,7 @@ impl EmbargoVisitor<'tcx> {
         }
     }
 
-    fn update_macro_reachable_mod(
-        &mut self,
-        reachable_mod: hir::HirId,
-        defining_mod: DefId,
-    ) {
+    fn update_macro_reachable_mod(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) {
         let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
         let module = self.tcx.hir().get_module(module_def_id).0;
         for item_id in &module.item_ids {
@@ -524,19 +520,13 @@ impl EmbargoVisitor<'tcx> {
                 self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
             }
         }
-
         if let Some(exports) = self.tcx.module_exports(module_def_id) {
             for export in exports {
                 if export.vis.is_accessible_from(defining_mod, self.tcx) {
                     if let Res::Def(def_kind, def_id) = export.res {
                         let vis = def_id_visibility(self.tcx, def_id).0;
                         if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
-                            self.update_macro_reachable_def(
-                                hir_id,
-                                def_kind,
-                                vis,
-                                defining_mod,
-                            );
+                            self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
                         }
                     }
                 }
@@ -892,10 +882,14 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             self.tcx.hir().local_def_id(md.hir_id)
         ).unwrap();
         let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
+        if !self.tcx.hir().is_hir_id_module(module_id) {
+            // `module_id` doesn't correspond to a `mod`, return early (#63164).
+            return;
+        }
         let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
         let new_level = self.update(md.hir_id, level);
         if new_level.is_none() {
-            return
+            return;
         }
 
         loop {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 42428456b6e..9a794ade729 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -145,7 +145,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
+    crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
         if let Some(ext) = self.macro_map.get(&def_id) {
             return Some(ext.clone());
         }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2dd0ad13c52..875ae449d94 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1647,10 +1647,14 @@ impl<'a> Resolver<'a> {
             if module.expansion != parent.expansion &&
             module.expansion.is_descendant_of(parent.expansion) {
                 // The macro is a proc macro derive
-                if module.expansion.looks_like_proc_macro_derive() {
-                    if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
-                        *poisoned = Some(node_id);
-                        return module.parent;
+                if let Some(&def_id) = self.macro_defs.get(&module.expansion) {
+                    if let Some(ext) = self.get_macro_by_def_id(def_id) {
+                        if !ext.is_builtin && ext.macro_kind() == MacroKind::Derive {
+                            if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
+                                *poisoned = Some(node_id);
+                                return module.parent;
+                            }
+                        }
                     }
                 }
             }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 01ad67252a3..719167eb057 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -140,9 +140,23 @@ impl<'a> base::Resolver for Resolver<'a> {
         ImportResolver { r: self }.resolve_imports()
     }
 
-    fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
-                                -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
-        let parent_scope = self.invocation_parent_scopes[&invoc_id];
+    fn resolve_macro_invocation(
+        &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool
+    ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
+        let invoc_id = invoc.expansion_data.id;
+        let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) {
+            Some(parent_scope) => *parent_scope,
+            None => {
+                // If there's no entry in the table, then we are resolving an eagerly expanded
+                // macro, which should inherit its parent scope from its eager expansion root -
+                // the macro that requested this eager expansion.
+                let parent_scope = *self.invocation_parent_scopes.get(&eager_expansion_root)
+                    .expect("non-eager expansion without a parent scope");
+                self.invocation_parent_scopes.insert(invoc_id, parent_scope);
+                parent_scope
+            }
+        };
+
         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),
@@ -161,7 +175,7 @@ impl<'a> base::Resolver for Resolver<'a> {
                         match self.resolve_macro_path(path, Some(MacroKind::Derive),
                                                       &parent_scope, true, force) {
                             Ok((Some(ref ext), _)) if ext.is_derive_copy => {
-                                self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
+                                self.add_derives(invoc_id, SpecialDerives::COPY);
                                 return Ok(None);
                             }
                             Err(Determinacy::Undetermined) => result = Err(Indeterminate),
@@ -178,19 +192,15 @@ impl<'a> base::Resolver for Resolver<'a> {
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
-        invoc.expansion_data.id.set_expn_data(
-            ext.expn_data(parent_scope.expansion, span, fast_print_path(path))
-        );
+        invoc_id.set_expn_data(ext.expn_data(parent_scope.expansion, span, fast_print_path(path)));
 
         if let Res::Def(_, def_id) = res {
             if after_derive {
                 self.session.span_err(span, "macro attributes must be placed before `#[derive]`");
             }
-            self.macro_defs.insert(invoc.expansion_data.id, def_id);
-            let normal_module_def_id =
-                self.macro_def_scope(invoc.expansion_data.id).normal_ancestor_id;
-            self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.id,
-                                                            normal_module_def_id);
+            self.macro_defs.insert(invoc_id, def_id);
+            let normal_module_def_id = self.macro_def_scope(invoc_id).normal_ancestor_id;
+            self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
         }
 
         Ok(Some(ext))
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index fc1ee649e28..9c7ac83e82e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4197,8 +4197,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// A possible error is to forget to add `.await` when using futures:
     ///
     /// ```
-    /// #![feature(async_await)]
-    ///
     /// async fn make_u32() -> u32 {
     ///     22
     /// }
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index ca9ce3d22b5..b52183d4b1b 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -4751,7 +4751,6 @@ E0733: r##"
 Recursion in an `async fn` requires boxing. For example, this will not compile:
 
 ```edition2018,compile_fail,E0733
-#![feature(async_await)]
 async fn foo(n: usize) {
     if n > 0 {
         foo(n - 1).await;
@@ -4763,12 +4762,11 @@ To achieve async recursion, the `async fn` needs to be desugared
 such that the `Future` is explicit in the return type:
 
 ```edition2018,compile_fail,E0720
-# #![feature(async_await)]
 use std::future::Future;
-fn foo_desugered(n: usize) -> impl Future<Output = ()> {
+fn foo_desugared(n: usize) -> impl Future<Output = ()> {
     async move {
         if n > 0 {
-            foo_desugered(n - 1).await;
+            foo_desugared(n - 1).await;
         }
     }
 }
@@ -4777,7 +4775,6 @@ fn foo_desugered(n: usize) -> impl Future<Output = ()> {
 Finally, the future is wrapped in a pinned box:
 
 ```edition2018
-# #![feature(async_await)]
 use std::future::Future;
 use std::pin::Pin;
 fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ea97cea9428..b64e74468e6 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -876,22 +876,22 @@ r#"var themes = document.getElementById("theme-choices");
 var themePicker = document.getElementById("theme-picker");
 
 function showThemeButtonState() {{
-    themes.style.display = "none";
-    themePicker.style.borderBottomRightRadius = "3px";
-    themePicker.style.borderBottomLeftRadius = "3px";
-}}
-
-function hideThemeButtonState() {{
     themes.style.display = "block";
     themePicker.style.borderBottomRightRadius = "0";
     themePicker.style.borderBottomLeftRadius = "0";
 }}
 
+function hideThemeButtonState() {{
+    themes.style.display = "none";
+    themePicker.style.borderBottomRightRadius = "3px";
+    themePicker.style.borderBottomLeftRadius = "3px";
+}}
+
 function switchThemeButtonState() {{
     if (themes.style.display === "block") {{
-        showThemeButtonState();
-    }} else {{
         hideThemeButtonState();
+    }} else {{
+        showThemeButtonState();
     }}
 }};
 
@@ -914,7 +914,7 @@ themePicker.onblur = handleThemeButtonsBlur;
     var but = document.createElement('button');
     but.innerHTML = item;
     but.onclick = function(el) {{
-        switchTheme(currentTheme, mainTheme, item);
+        switchTheme(currentTheme, mainTheme, item, true);
     }};
     but.onblur = handleThemeButtonsBlur;
     themes.appendChild(but);
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 82d2c11b249..3d0f00095ac 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -105,9 +105,9 @@ if (!DOMTokenList.prototype.remove) {
                 sidebar.appendChild(div);
             }
         }
-        var themePicker = document.getElementsByClassName("theme-picker");
-        if (themePicker && themePicker.length > 0) {
-            themePicker[0].style.display = "none";
+        var themePickers = document.getElementsByClassName("theme-picker");
+        if (themePickers && themePickers.length > 0) {
+            themePickers[0].style.display = "none";
         }
     }
 
@@ -123,9 +123,9 @@ if (!DOMTokenList.prototype.remove) {
             filler.remove();
         }
         document.getElementsByTagName("body")[0].style.marginTop = "";
-        var themePicker = document.getElementsByClassName("theme-picker");
-        if (themePicker && themePicker.length > 0) {
-            themePicker[0].style.display = null;
+        var themePickers = document.getElementsByClassName("theme-picker");
+        if (themePickers && themePickers.length > 0) {
+            themePickers[0].style.display = null;
         }
     }
 
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 59d10668f11..244b24af43f 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -54,6 +54,21 @@
 		  box-sizing: border-box;
 }
 
+/* This part handles the "default" theme being used depending on the system one. */
+html {
+	content: "";
+}
+@media (prefers-color-scheme: light) {
+	html {
+		content: "light";
+	}
+}
+@media (prefers-color-scheme: dark) {
+	html {
+		content: "dark";
+	}
+}
+
 /* General structure and fonts */
 
 body {
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index e3927350d11..c55b1e41443 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -86,7 +86,7 @@ function getCurrentValue(name) {
     return null;
 }
 
-function switchTheme(styleElem, mainStyleElem, newTheme) {
+function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
     var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
     var fullNewTheme = newTheme + resourcesSuffix + ".css";
     var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
@@ -109,8 +109,18 @@ function switchTheme(styleElem, mainStyleElem, newTheme) {
     });
     if (found === true) {
         styleElem.href = newHref;
-        updateLocalStorage("rustdoc-theme", newTheme);
+        // If this new value comes from a system setting or from the previously saved theme, no
+        // need to save it.
+        if (saveTheme === true) {
+            updateLocalStorage("rustdoc-theme", newTheme);
+        }
     }
 }
 
-switchTheme(currentTheme, mainTheme, getCurrentValue("rustdoc-theme") || "light");
+function getSystemValue() {
+    return getComputedStyle(document.documentElement).getPropertyValue('content');
+}
+
+switchTheme(currentTheme, mainTheme,
+            getCurrentValue("rustdoc-theme") || getSystemValue() || "light",
+            false);
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index f649170c403..e55afc2344f 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -236,7 +236,7 @@ impl f32 {
     /// let b = 60.0_f32;
     ///
     /// // 100.0
-    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -318,7 +318,7 @@ impl f32 {
     /// use std::f32;
     ///
     /// let x = 2.0_f32;
-    /// let abs_difference = (x.powi(2) - x*x).abs();
+    /// let abs_difference = (x.powi(2) - (x * x)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -336,7 +336,7 @@ impl f32 {
     /// use std::f32;
     ///
     /// let x = 2.0_f32;
-    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -600,7 +600,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = f32::consts::PI/2.0;
+    /// let x = f32::consts::FRAC_PI_2;
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
@@ -623,7 +623,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = 2.0*f32::consts::PI;
+    /// let x = 2.0 * f32::consts::PI;
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
@@ -646,7 +646,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = f32::consts::PI / 4.0;
+    /// let x = f32::consts::FRAC_PI_4;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
@@ -666,10 +666,10 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let f = f32::consts::PI / 2.0;
+    /// let f = f32::consts::FRAC_PI_2;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f32::consts::PI / 2.0).abs();
+    /// let abs_difference = (f.sin().asin() - f32::consts::FRAC_PI_2).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -688,10 +688,10 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let f = f32::consts::PI / 4.0;
+    /// let f = f32::consts::FRAC_PI_4;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f32::consts::PI / 4.0).abs();
+    /// let abs_difference = (f.cos().acos() - f32::consts::FRAC_PI_4).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -734,7 +734,6 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let pi = f32::consts::PI;
     /// // Positive angles measured counter-clockwise
     /// // from positive x axis
     /// // -pi/4 radians (45 deg clockwise)
@@ -745,8 +744,8 @@ impl f32 {
     /// let x2 = -3.0f32;
     /// let y2 = 3.0f32;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-f32::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f32::consts::FRAC_PI_4)).abs();
     ///
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// assert!(abs_difference_2 <= f32::EPSILON);
@@ -765,7 +764,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = f32::consts::PI/4.0;
+    /// let x = f32::consts::FRAC_PI_4;
     /// let f = x.sin_cos();
     ///
     /// let abs_difference_0 = (f.0 - x.sin()).abs();
@@ -834,7 +833,7 @@ impl f32 {
     ///
     /// let f = x.sinh();
     /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
-    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let g = ((e * e) - 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
@@ -856,7 +855,7 @@ impl f32 {
     /// let x = 1.0f32;
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
-    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let g = ((e * e) + 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// // Same result
@@ -880,7 +879,7 @@ impl f32 {
     ///
     /// let f = x.tanh();
     /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
-    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index f61630997dc..b3571026300 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -212,7 +212,7 @@ impl f64 {
     /// let b = 60.0_f64;
     ///
     /// // 100.0
-    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -291,7 +291,7 @@ impl f64 {
     ///
     /// ```
     /// let x = 2.0_f64;
-    /// let abs_difference = (x.powi(2) - x*x).abs();
+    /// let abs_difference = (x.powi(2) - (x * x)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -307,7 +307,7 @@ impl f64 {
     ///
     /// ```
     /// let x = 2.0_f64;
-    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -537,7 +537,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = f64::consts::PI/2.0;
+    /// let x = f64::consts::FRAC_PI_2;
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
@@ -556,7 +556,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = 2.0*f64::consts::PI;
+    /// let x = 2.0 * f64::consts::PI;
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
@@ -575,7 +575,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = f64::consts::PI/4.0;
+    /// let x = f64::consts::FRAC_PI_4;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
     /// assert!(abs_difference < 1e-14);
@@ -595,10 +595,10 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let f = f64::consts::PI / 2.0;
+    /// let f = f64::consts::FRAC_PI_2;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    /// let abs_difference = (f.sin().asin() - f64::consts::FRAC_PI_2).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -617,10 +617,10 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let f = f64::consts::PI / 4.0;
+    /// let f = f64::consts::FRAC_PI_4;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    /// let abs_difference = (f.cos().acos() - f64::consts::FRAC_PI_4).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -661,7 +661,6 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let pi = f64::consts::PI;
     /// // Positive angles measured counter-clockwise
     /// // from positive x axis
     /// // -pi/4 radians (45 deg clockwise)
@@ -672,8 +671,8 @@ impl f64 {
     /// let x2 = -3.0_f64;
     /// let y2 = 3.0_f64;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-f64::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f64::consts::FRAC_PI_4)).abs();
     ///
     /// assert!(abs_difference_1 < 1e-10);
     /// assert!(abs_difference_2 < 1e-10);
@@ -692,7 +691,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = f64::consts::PI/4.0;
+    /// let x = f64::consts::FRAC_PI_4;
     /// let f = x.sin_cos();
     ///
     /// let abs_difference_0 = (f.0 - x.sin()).abs();
@@ -759,7 +758,7 @@ impl f64 {
     ///
     /// let f = x.sinh();
     /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
-    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let g = ((e * e) - 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference < 1e-10);
@@ -781,7 +780,7 @@ impl f64 {
     /// let x = 1.0_f64;
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
-    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let g = ((e * e) + 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// // Same result
@@ -805,7 +804,7 @@ impl f64 {
     ///
     /// let f = x.tanh();
     /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
-    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference < 1.0e-10);
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 512839a12c0..65f4e0cafe0 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -572,8 +572,8 @@ impl CString {
     /// use std::ffi::{CString, CStr};
     ///
     /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed");
-    /// let c_str = c_string.as_c_str();
-    /// assert_eq!(c_str,
+    /// let cstr = c_string.as_c_str();
+    /// assert_eq!(cstr,
     ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
     /// ```
     #[inline]
@@ -994,8 +994,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"hello");
-    /// assert!(c_str.is_err());
+    /// let cstr = CStr::from_bytes_with_nul(b"hello");
+    /// assert!(cstr.is_err());
     /// ```
     ///
     /// Creating a `CStr` with an interior nul byte is an error:
@@ -1003,8 +1003,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"he\0llo\0");
-    /// assert!(c_str.is_err());
+    /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
+    /// assert!(cstr.is_err());
     /// ```
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     pub fn from_bytes_with_nul(bytes: &[u8])
@@ -1111,8 +1111,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_bytes(), b"foo");
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_bytes(), b"foo");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1137,8 +1137,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_bytes_with_nul(), b"foo\0");
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1164,8 +1164,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_str(), Ok("foo"));
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_str(), Ok("foo"));
     /// ```
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
@@ -1205,9 +1205,9 @@ impl CStr {
     /// use std::borrow::Cow;
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"Hello World\0")
+    /// let cstr = CStr::from_bytes_with_nul(b"Hello World\0")
     ///                  .expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_string_lossy(), Cow::Borrowed("Hello World"));
+    /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World"));
     /// ```
     ///
     /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
@@ -1216,10 +1216,10 @@ impl CStr {
     /// use std::borrow::Cow;
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
+    /// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
     ///                  .expect("CStr::from_bytes_with_nul failed");
     /// assert_eq!(
-    ///     c_str.to_string_lossy(),
+    ///     cstr.to_string_lossy(),
     ///     Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
     /// );
     /// ```
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 1f384cbada3..6cf062d4f30 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -233,7 +233,7 @@ impl OsString {
     /// ```
     /// use std::ffi::OsString;
     ///
-    /// let mut os_string = OsString::with_capacity(10);
+    /// let os_string = OsString::with_capacity(10);
     /// assert!(os_string.capacity() >= 10);
     /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
@@ -616,7 +616,7 @@ impl OsStr {
     /// Note that this does **not** return the number of bytes in the string in
     /// OS string form.
     ///
-    /// The length returned is that of the underlying storage used by `OsStr`;
+    /// The length returned is that of the underlying storage used by `OsStr`.
     /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
     /// store strings in a form best suited for cheap inter-conversion between
     /// native-platform and Rust string forms, which may differ significantly
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index f2b6ce6feb2..5060f368229 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -353,12 +353,17 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
 // Because we're extending the buffer with uninitialized data for trusted
 // readers, we need to make sure to truncate that if any of this panics.
 fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
-    read_to_end_with_reservation(r, buf, 32)
+    read_to_end_with_reservation(r, buf, |_| 32)
 }
 
-fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
-                                                  buf: &mut Vec<u8>,
-                                                  reservation_size: usize) -> Result<usize>
+fn read_to_end_with_reservation<R, F>(
+    r: &mut R,
+    buf: &mut Vec<u8>,
+    mut reservation_size: F,
+) -> Result<usize>
+where
+    R: Read + ?Sized,
+    F: FnMut(&R) -> usize,
 {
     let start_len = buf.len();
     let mut g = Guard { len: buf.len(), buf: buf };
@@ -366,7 +371,7 @@ fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
     loop {
         if g.len == g.buf.len() {
             unsafe {
-                g.buf.reserve(reservation_size);
+                g.buf.reserve(reservation_size(r));
                 let capacity = g.buf.capacity();
                 g.buf.set_len(capacity);
                 r.initializer().initialize(&mut g.buf[g.len..]);
@@ -2253,9 +2258,10 @@ impl<T: Read> Read for Take<T> {
     }
 
     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
-        let reservation_size = cmp::min(self.limit, 32) as usize;
-
-        read_to_end_with_reservation(self, buf, reservation_size)
+        // Pass in a reservation_size closure that respects the current value
+        // of limit for each read. If we hit the read limit, this prevents the
+        // final zero-byte read from allocating again.
+        read_to_end_with_reservation(self, buf, |self_| cmp::min(self_.limit, 32) as usize)
     }
 }
 
@@ -2378,6 +2384,7 @@ impl<B: BufRead> Iterator for Lines<B> {
 
 #[cfg(test)]
 mod tests {
+    use crate::cmp;
     use crate::io::prelude::*;
     use super::{Cursor, SeekFrom, repeat};
     use crate::io::{self, IoSlice, IoSliceMut};
@@ -2651,6 +2658,49 @@ mod tests {
         Ok(())
     }
 
+    // A simple example reader which uses the default implementation of
+    // read_to_end.
+    struct ExampleSliceReader<'a> {
+        slice: &'a [u8],
+    }
+
+    impl<'a> Read for ExampleSliceReader<'a> {
+        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+            let len = cmp::min(self.slice.len(), buf.len());
+            buf[..len].copy_from_slice(&self.slice[..len]);
+            self.slice = &self.slice[len..];
+            Ok(len)
+        }
+    }
+
+    #[test]
+    fn test_read_to_end_capacity() -> io::Result<()> {
+        let input = &b"foo"[..];
+
+        // read_to_end() generally needs to over-allocate, both for efficiency
+        // and so that it can distinguish EOF. Assert that this is the case
+        // with this simple ExampleSliceReader struct, which uses the default
+        // implementation of read_to_end. Even though vec1 is allocated with
+        // exactly enough capacity for the read, read_to_end will allocate more
+        // space here.
+        let mut vec1 = Vec::with_capacity(input.len());
+        ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
+        assert_eq!(vec1.len(), input.len());
+        assert!(vec1.capacity() > input.len(), "allocated more");
+
+        // However, std::io::Take includes an implementation of read_to_end
+        // that will not allocate when the limit has already been reached. In
+        // this case, vec2 never grows.
+        let mut vec2 = Vec::with_capacity(input.len());
+        ExampleSliceReader { slice: input }
+            .take(input.len() as u64)
+            .read_to_end(&mut vec2)?;
+        assert_eq!(vec2.len(), input.len());
+        assert_eq!(vec2.capacity(), input.len(), "did not allocate more");
+
+        Ok(())
+    }
+
     #[test]
     fn io_slice_mut_advance() {
         let mut buf1 = [1; 8];
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index f5018485ef7..85a9dea09ed 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -984,7 +984,6 @@ mod where_keyword { }
 
 // 2018 Edition keywords
 
-#[unstable(feature = "async_await", issue = "50547")]
 #[doc(keyword = "async")]
 //
 /// Return a [`Future`] instead of blocking the current thread.
@@ -995,7 +994,6 @@ mod where_keyword { }
 /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
 mod async_keyword { }
 
-#[unstable(feature = "async_await", issue = "50547")]
 #[doc(keyword = "await")]
 //
 /// Suspend execution until the result of a [`Future`] is ready.
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index d9a3da66a67..45816ffd229 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -655,7 +655,7 @@ mod prim_slice { }
 /// [`len`]: #method.len
 ///
 /// Note: This example shows the internals of `&str`. `unsafe` should not be
-/// used to get a string slice under normal circumstances. Use `as_slice`
+/// used to get a string slice under normal circumstances. Use `as_str`
 /// instead.
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_str { }
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 6bb20bbe087..21fca23a8fe 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -20,6 +20,30 @@ cfg_if::cfg_if! {
     }
 }
 
+// Android with api less than 21 define sig* functions inline, so it is not
+// available for dynamic link. Implementing sigemptyset and sigaddset allow us
+// to support older Android version (independent of libc version).
+// The following implementations are based on https://git.io/vSkNf
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "android")] {
+        pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
+            set.write_bytes(0u8, 1);
+            return 0;
+        }
+        #[allow(dead_code)]
+        pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
+            use crate::{slice, mem};
+
+            let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
+            let bit = (signum - 1) as usize;
+            raw[bit / 8] |= 1 << (bit % 8);
+            return 0;
+        }
+    } else {
+        pub use libc::{sigemptyset, sigaddset};
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
@@ -429,36 +453,6 @@ mod tests {
         }
     }
 
-    // Android with api less than 21 define sig* functions inline, so it is not
-    // available for dynamic link. Implementing sigemptyset and sigaddset allow us
-    // to support older Android version (independent of libc version).
-    // The following implementations are based on https://git.io/vSkNf
-
-    #[cfg(not(target_os = "android"))]
-    extern {
-        #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
-        fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
-
-        #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
-        fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
-    }
-
-    #[cfg(target_os = "android")]
-    unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
-        set.write_bytes(0u8, 1);
-        return 0;
-    }
-
-    #[cfg(target_os = "android")]
-    unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
-        use crate::slice;
-
-        let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
-        let bit = (signum - 1) as usize;
-        raw[bit / 8] |= 1 << (bit % 8);
-        return 0;
-    }
-
     // See #14232 for more information, but it appears that signal delivery to a
     // newly spawned process may just be raced in the macOS, so to prevent this
     // test from being flaky we ignore it on macOS.
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 327d82e60cf..e6a742bd45d 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -178,23 +178,22 @@ impl Command {
             cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
         }
 
-        if cfg!(not(any(target_os = "l4re"))) {
+        #[cfg(not(target_os = "l4re"))]
+        {
             if let Some(u) = self.get_gid() {
                 cvt(libc::setgid(u as gid_t))?;
             }
             if let Some(u) = self.get_uid() {
+                // When dropping privileges from root, the `setgroups` call
+                // will remove any extraneous groups. If we don't call this,
+                // then even though our uid has dropped, we may still have
+                // groups that enable us to do super-user things. This will
+                // fail if we aren't root, so don't bother checking the
+                // return value, this is just done as an optimistic
+                // privilege dropping function.
                 //FIXME: Redox kernel does not support setgroups yet
-                if cfg!(not(target_os = "redox")) {
-                    // When dropping privileges from root, the `setgroups` call
-                    // will remove any extraneous groups. If we don't call this,
-                    // then even though our uid has dropped, we may still have
-                    // groups that enable us to do super-user things. This will
-                    // fail if we aren't root, so don't bother checking the
-                    // return value, this is just done as an optimistic
-                    // privilege dropping function.
-                    let _ = libc::setgroups(0, ptr::null());
-                }
-
+                #[cfg(not(target_os = "redox"))]
+                let _ = libc::setgroups(0, ptr::null());
                 cvt(libc::setuid(u as uid_t))?;
             }
         }
@@ -203,7 +202,7 @@ impl Command {
         }
 
         // emscripten has no signal support.
-        #[cfg(not(any(target_os = "emscripten")))]
+        #[cfg(not(target_os = "emscripten"))]
         {
             use crate::mem::MaybeUninit;
             // Reset signal handling so the child process starts in a
@@ -214,14 +213,7 @@ impl Command {
             // need to clean things up now to avoid confusing the program
             // we're about to run.
             let mut set = MaybeUninit::<libc::sigset_t>::uninit();
-            if cfg!(target_os = "android") {
-                // Implementing sigemptyset allow us to support older Android
-                // versions. See the comment about Android and sig* functions in
-                // process_common.rs
-                set.as_mut_ptr().write_bytes(0u8, 1);
-            } else {
-                cvt(libc::sigemptyset(set.as_mut_ptr()))?;
-            }
+            cvt(sigemptyset(set.as_mut_ptr()))?;
             cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(),
                                          ptr::null_mut()))?;
             let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
@@ -363,10 +355,10 @@ impl Command {
             }
 
             let mut set = MaybeUninit::<libc::sigset_t>::uninit();
-            cvt(libc::sigemptyset(set.as_mut_ptr()))?;
+            cvt(sigemptyset(set.as_mut_ptr()))?;
             cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(),
                                                  set.as_ptr()))?;
-            cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
+            cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
             cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(),
                                                     set.as_ptr()))?;
 
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index f87e4d16fcd..4007b7ac0ec 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -67,8 +67,25 @@ pub fn unsupported_err() -> std_io::Error {
     )
 }
 
-pub fn decode_error_kind(_code: i32) -> std_io::ErrorKind {
-    std_io::ErrorKind::Other
+pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
+    use std_io::ErrorKind::*;
+    match errno as libc::c_int {
+        wasi::ECONNREFUSED => ConnectionRefused,
+        wasi::ECONNRESET => ConnectionReset,
+        wasi::EPERM | libc::EACCES => PermissionDenied,
+        wasi::EPIPE => BrokenPipe,
+        wasi::ENOTCONN => NotConnected,
+        wasi::ECONNABORTED => ConnectionAborted,
+        wasi::EADDRNOTAVAIL => AddrNotAvailable,
+        wasi::EADDRINUSE => AddrInUse,
+        wasi::ENOENT => NotFound,
+        wasi::EINTR => Interrupted,
+        wasi::EINVAL => InvalidInput,
+        wasi::ETIMEDOUT => TimedOut,
+        wasi::EEXIST => AlreadyExists,
+        wasi::EAGAIN => WouldBlock,
+        _ => ErrorKind::Other,
+    }
 }
 
 // This enum is used as the storage for a bunch of types which can't actually
diff --git a/src/libsyntax/diagnostics/metadata.rs b/src/libsyntax/diagnostics/metadata.rs
deleted file mode 100644
index 53f37bb10bd..00000000000
--- a/src/libsyntax/diagnostics/metadata.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//! This module contains utilities for outputting metadata for diagnostic errors.
-//!
-//! Each set of errors is mapped to a metadata file by a name, which is
-//! currently always a crate name.
-
-use std::collections::BTreeMap;
-use std::env;
-use std::fs::{remove_file, create_dir_all, File};
-use std::io::Write;
-use std::path::PathBuf;
-use std::error::Error;
-use rustc_serialize::json::as_json;
-
-use syntax_pos::{Span, FileName};
-
-use crate::ext::base::ExtCtxt;
-use crate::diagnostics::plugin::{ErrorMap, ErrorInfo};
-
-/// JSON encodable/decodable version of `ErrorInfo`.
-#[derive(PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ErrorMetadata {
-    pub description: Option<String>,
-    pub use_site: Option<ErrorLocation>
-}
-
-/// Mapping from error codes to metadata that can be (de)serialized.
-pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
-
-/// JSON encodable error location type with filename and line number.
-#[derive(PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ErrorLocation {
-    pub filename: FileName,
-    pub line: usize
-}
-
-impl ErrorLocation {
-    /// Creates an error location from a span.
-    pub fn from_span(ecx: &ExtCtxt<'_>, sp: Span) -> ErrorLocation {
-        let loc = ecx.source_map().lookup_char_pos(sp.lo());
-        ErrorLocation {
-            filename: loc.file.name.clone(),
-            line: loc.line
-        }
-    }
-}
-
-/// Gets the directory where metadata for a given `prefix` should be stored.
-///
-/// See `output_metadata`.
-pub fn get_metadata_dir(prefix: &str) -> PathBuf {
-    env::var_os("RUSTC_ERROR_METADATA_DST")
-        .map(PathBuf::from)
-        .expect("env var `RUSTC_ERROR_METADATA_DST` isn't set")
-        .join(prefix)
-}
-
-/// Map `name` to a path in the given directory: <directory>/<name>.json
-fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf {
-    directory.join(format!("{}.json", name))
-}
-
-/// Write metadata for the errors in `err_map` to disk, to a file corresponding to `prefix/name`.
-///
-/// For our current purposes the prefix is the target architecture and the name is a crate name.
-/// If an error occurs steps will be taken to ensure that no file is created.
-pub fn output_metadata(ecx: &ExtCtxt<'_>, prefix: &str, name: &str, err_map: &ErrorMap)
-    -> Result<(), Box<dyn Error>>
-{
-    // Create the directory to place the file in.
-    let metadata_dir = get_metadata_dir(prefix);
-    create_dir_all(&metadata_dir)?;
-
-    // Open the metadata file.
-    let metadata_path = get_metadata_path(metadata_dir, name);
-    let mut metadata_file = File::create(&metadata_path)?;
-
-    // Construct a serializable map.
-    let json_map = err_map.iter().map(|(k, &ErrorInfo { description, use_site })| {
-        let key = k.as_str().to_string();
-        let value = ErrorMetadata {
-            description: description.map(|n| n.as_str().to_string()),
-            use_site: use_site.map(|sp| ErrorLocation::from_span(ecx, sp))
-        };
-        (key, value)
-    }).collect::<ErrorMetadataMap>();
-
-    // Write the data to the file, deleting it if the write fails.
-    let result = write!(&mut metadata_file, "{}", as_json(&json_map));
-    if result.is_err() {
-        remove_file(&metadata_path)?;
-    }
-    Ok(result?)
-}
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 9618b5acfb0..e9a55af52e8 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -1,5 +1,4 @@
 use std::collections::BTreeMap;
-use std::env;
 
 use crate::ast::{self, Ident, Name};
 use crate::source_map;
@@ -12,8 +11,6 @@ use crate::tokenstream::{TokenTree};
 use smallvec::smallvec;
 use syntax_pos::Span;
 
-use crate::diagnostics::metadata::output_metadata;
-
 pub use errors::*;
 
 // Maximum width of any line in an extended error description (inclusive).
@@ -127,36 +124,13 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                           token_tree: &[TokenTree])
                                           -> Box<dyn MacResult+'cx> {
     assert_eq!(token_tree.len(), 3);
-    let (crate_name, ident) = match (&token_tree[0], &token_tree[2]) {
-        (
-            // Crate name.
-            &TokenTree::Token(Token { kind: token::Ident(crate_name, _), .. }),
-            // DIAGNOSTICS ident.
-            &TokenTree::Token(Token { kind: token::Ident(name, _), span })
-        ) => (crate_name, Ident::new(name, span)),
+    let ident = match &token_tree[2] {
+        // DIAGNOSTICS ident.
+        &TokenTree::Token(Token { kind: token::Ident(name, _), span })
+        => Ident::new(name, span),
         _ => unreachable!()
     };
 
-    // Output error metadata to `tmp/extended-errors/<target arch>/<crate name>.json`
-    if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") {
-        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-            if let Err(e) = output_metadata(ecx,
-                                            &target_triple,
-                                            &crate_name.as_str(),
-                                            diagnostics) {
-                ecx.span_bug(span, &format!(
-                    "error writing metadata for triple `{}` and crate `{}`, error: {}, \
-                     cause: {:?}",
-                    target_triple, crate_name, e.description(), e.source()
-                ));
-            }
-        });
-    } else {
-        ecx.span_err(span, &format!(
-            "failed to write metadata for crate `{}` because $CFG_COMPILER_HOST_TRIPLE is not set",
-            crate_name));
-    }
-
     // Construct the output expression.
     let (count, expr) =
         ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index b0a4a6af983..a63c4181d5e 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -3,7 +3,7 @@ use crate::attr::{HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
 use crate::ext::expand::{self, AstFragment, Invocation};
-use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency};
+use crate::ext::hygiene::{ExpnId, Transparency};
 use crate::mut_visit::{self, MutVisitor};
 use crate::parse::{self, parser, DirectoryOwnership};
 use crate::parse::token;
@@ -549,8 +549,6 @@ pub struct SyntaxExtension {
     pub kind: SyntaxExtensionKind,
     /// Span of the macro definition.
     pub span: Span,
-    /// Hygienic properties of spans produced by this macro by default.
-    pub default_transparency: Transparency,
     /// Whitelist of unstable features that are treated as stable inside this macro.
     pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
     /// Suppresses the `unsafe_code` lint for code produced by this macro.
@@ -572,22 +570,6 @@ pub struct SyntaxExtension {
     pub is_derive_copy: bool,
 }
 
-impl SyntaxExtensionKind {
-    /// When a syntax extension is constructed,
-    /// its transparency can often be inferred from its kind.
-    fn default_transparency(&self) -> Transparency {
-        match self {
-            SyntaxExtensionKind::Bang(..) |
-            SyntaxExtensionKind::Attr(..) |
-            SyntaxExtensionKind::Derive(..) |
-            SyntaxExtensionKind::NonMacroAttr { .. } => Transparency::Opaque,
-            SyntaxExtensionKind::LegacyBang(..) |
-            SyntaxExtensionKind::LegacyAttr(..) |
-            SyntaxExtensionKind::LegacyDerive(..) => Transparency::SemiTransparent,
-        }
-    }
-}
-
 impl SyntaxExtension {
     /// Returns which kind of macro calls this syntax extension.
     pub fn macro_kind(&self) -> MacroKind {
@@ -606,7 +588,6 @@ impl SyntaxExtension {
     pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
         SyntaxExtension {
             span: DUMMY_SP,
-            default_transparency: kind.default_transparency(),
             allow_internal_unstable: None,
             allow_internal_unsafe: false,
             local_inner_macros: false,
@@ -646,7 +627,6 @@ impl SyntaxExtension {
             parent,
             call_site,
             def_site: self.span,
-            default_transparency: self.default_transparency,
             allow_internal_unstable: self.allow_internal_unstable.clone(),
             allow_internal_unsafe: self.allow_internal_unsafe,
             local_inner_macros: self.local_inner_macros,
@@ -682,8 +662,9 @@ pub trait Resolver {
 
     fn resolve_imports(&mut self);
 
-    fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
-                                -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>;
+    fn resolve_macro_invocation(
+        &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool
+    ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>;
 
     fn check_unused_macros(&self);
 
@@ -759,23 +740,39 @@ impl<'a> ExtCtxt<'a> {
     pub fn call_site(&self) -> Span {
         self.current_expansion.id.expn_data().call_site
     }
-    pub fn backtrace(&self) -> SyntaxContext {
-        SyntaxContext::root().apply_mark(self.current_expansion.id)
+
+    /// Equivalent of `Span::def_site` from the proc macro API,
+    /// except that the location is taken from the span passed as an argument.
+    pub fn with_def_site_ctxt(&self, span: Span) -> Span {
+        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Opaque)
+    }
+
+    /// Equivalent of `Span::call_site` from the proc macro API,
+    /// except that the location is taken from the span passed as an argument.
+    pub fn with_call_site_ctxt(&self, span: Span) -> Span {
+        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Transparent)
+    }
+
+    /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
+    /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
+    /// or with `with_call_site_ctxt` (where necessary).
+    pub fn with_legacy_ctxt(&self, span: Span) -> Span {
+        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::SemiTransparent)
     }
 
     /// Returns span for the macro which originally caused the current expansion to happen.
     ///
     /// Stops backtracing at include! boundary.
     pub fn expansion_cause(&self) -> Option<Span> {
-        let mut ctxt = self.backtrace();
+        let mut expn_id = self.current_expansion.id;
         let mut last_macro = None;
         loop {
-            let expn_data = ctxt.outer_expn_data();
+            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;
             }
-            ctxt = expn_data.call_site.ctxt();
+            expn_id = expn_data.call_site.ctxt().outer_expn();
             last_macro = Some(expn_data.call_site);
         }
         last_macro
@@ -864,7 +861,7 @@ impl<'a> ExtCtxt<'a> {
         ast::Ident::from_str(st)
     }
     pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
-        let def_site = DUMMY_SP.apply_mark(self.current_expansion.id);
+        let def_site = self.with_def_site_ctxt(DUMMY_SP);
         iter::once(Ident::new(kw::DollarCrate, def_site))
             .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
             .collect()
@@ -908,12 +905,9 @@ impl<'a> ExtCtxt<'a> {
 /// compilation on error, merely emits a non-fatal error and returns `None`.
 pub fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt<'_>,
-    mut expr: P<ast::Expr>,
+    expr: P<ast::Expr>,
     err_msg: &str,
 ) -> Result<(Symbol, ast::StrStyle, Span), Option<DiagnosticBuilder<'a>>> {
-    // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation.
-    expr.span = expr.span.apply_mark(cx.current_expansion.id);
-
     // Perform eager expansion on the expression.
     // We want to be able to handle e.g., `concat!("foo", "bar")`.
     let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index c1d52c97455..c8c0f4ce36e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -305,9 +305,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 continue
             };
 
-            let scope =
+            let eager_expansion_root =
                 if self.monotonic { invoc.expansion_data.id } else { orig_expansion_data.id };
-            let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) {
+            let ext = match self.cx.resolver.resolve_macro_invocation(
+                &invoc, eager_expansion_root, force
+            ) {
                 Ok(ext) => ext,
                 Err(Indeterminate) => {
                     undetermined_invocations.push(invoc);
@@ -318,7 +320,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             progress = true;
             let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
             self.cx.current_expansion = invoc.expansion_data.clone();
-            self.cx.current_expansion.id = scope;
 
             // FIXME(jseyfried): Refactor out the following logic
             let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
@@ -564,7 +565,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         return fragment_kind.dummy(span);
                     }
                     let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path };
-                    let span = span.with_ctxt(self.cx.backtrace());
                     let items = expander.expand(self.cx, span, &meta, item);
                     fragment_kind.expect_from_annotatables(items)
                 }
@@ -1388,17 +1388,3 @@ impl<'feat> ExpansionConfig<'feat> {
         self.features.map_or(false, |features| features.custom_inner_attributes)
     }
 }
-
-// A Marker adds the given mark to the syntax context.
-#[derive(Debug)]
-pub struct Marker(pub ExpnId);
-
-impl MutVisitor for Marker {
-    fn visit_span(&mut self, span: &mut Span) {
-        *span = span.apply_mark(self.0)
-    }
-
-    fn visit_mac(&mut self, mac: &mut ast::Mac) {
-        noop_visit_mac(mac, self)
-    }
-}
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 1619fa69941..b1bbd2aaac9 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -7,7 +7,6 @@ use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}
 use errors::{Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
-use syntax_pos::hygiene::{SyntaxContext, Transparency};
 use syntax_pos::symbol::{kw, sym, Symbol};
 
 use proc_macro::{Delimiter, Level, LineColumn, Spacing};
@@ -363,16 +362,10 @@ impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
         // No way to determine def location for a proc macro right now, so use call location.
         let location = cx.current_expansion.id.expn_data().call_site;
-        let to_span = |transparency| {
-            location.with_ctxt(
-                SyntaxContext::root()
-                    .apply_mark_with_transparency(cx.current_expansion.id, transparency),
-            )
-        };
         Rustc {
             sess: cx.parse_sess,
-            def_site: to_span(Transparency::Opaque),
-            call_site: to_span(Transparency::Transparent),
+            def_site: cx.with_def_site_ctxt(location),
+            call_site: cx.with_call_site_ctxt(location),
         }
     }
 
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index b057a9ad44d..37cb8467ff5 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -19,6 +19,7 @@ use crate::{ast, attr, attr::TransparencyError};
 
 use errors::{DiagnosticBuilder, FatalError};
 use log::debug;
+use syntax_pos::hygiene::Transparency;
 use syntax_pos::Span;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -128,6 +129,7 @@ impl<'a> ParserAnyMacro<'a> {
 struct MacroRulesMacroExpander {
     name: ast::Ident,
     span: Span,
+    transparency: Transparency,
     lhses: Vec<quoted::TokenTree>,
     rhses: Vec<quoted::TokenTree>,
     valid: bool,
@@ -143,7 +145,9 @@ impl TTMacroExpander for MacroRulesMacroExpander {
         if !self.valid {
             return DummyResult::any(sp);
         }
-        generic_extension(cx, sp, self.span, self.name, input, &self.lhses, &self.rhses)
+        generic_extension(
+            cx, sp, self.span, self.name, self.transparency, input, &self.lhses, &self.rhses
+        )
     }
 }
 
@@ -158,6 +162,7 @@ fn generic_extension<'cx>(
     sp: Span,
     def_span: Span,
     name: ast::Ident,
+    transparency: Transparency,
     arg: TokenStream,
     lhses: &[quoted::TokenTree],
     rhses: &[quoted::TokenTree],
@@ -187,7 +192,7 @@ fn generic_extension<'cx>(
 
                 let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
                 // rhs has holes ( `$id` and `$(...)` that need filled)
-                let mut tts = transcribe(cx, &named_matches, rhs);
+                let mut tts = transcribe(cx, &named_matches, rhs, transparency);
 
                 // Replace all the tokens for the corresponding positions in the macro, to maintain
                 // proper positions in error reporting, while maintaining the macro_backtrace.
@@ -415,11 +420,7 @@ pub fn compile(
     // that is not lint-checked and trigger the "failed to process buffered lint here" bug.
     valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses);
 
-    let expander: Box<_> =
-        Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, lhses, rhses, valid });
-
-    let (default_transparency, transparency_error) =
-        attr::find_transparency(&def.attrs, body.legacy);
+    let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
     match transparency_error {
         Some(TransparencyError::UnknownTransparency(value, span)) =>
             sess.span_diagnostic.span_err(
@@ -432,6 +433,10 @@ pub fn compile(
         None => {}
     }
 
+    let expander: Box<_> = Box::new(MacroRulesMacroExpander {
+        name: def.ident, span: def.span, transparency, lhses, rhses, valid
+    });
+
     let allow_internal_unstable =
         attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
             attr.meta_item_list()
@@ -473,7 +478,6 @@ pub fn compile(
     SyntaxExtension {
         kind: SyntaxExtensionKind::LegacyBang(expander),
         span: def.span,
-        default_transparency,
         allow_internal_unstable,
         allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
         local_inner_macros,
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 214e721fd15..30d5df13dce 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -1,9 +1,8 @@
-use crate::ast::Ident;
+use crate::ast::{Ident, Mac};
 use crate::ext::base::ExtCtxt;
-use crate::ext::expand::Marker;
 use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
 use crate::ext::tt::quoted;
-use crate::mut_visit::noop_visit_tt;
+use crate::mut_visit::{self, MutVisitor};
 use crate::parse::token::{self, NtTT, Token};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
@@ -11,8 +10,31 @@ use smallvec::{smallvec, SmallVec};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
+use syntax_pos::hygiene::{ExpnId, Transparency};
+use syntax_pos::Span;
+
 use std::mem;
 
+// A Marker adds the given mark to the syntax context.
+struct Marker(ExpnId, Transparency);
+
+impl MutVisitor for Marker {
+    fn visit_span(&mut self, span: &mut Span) {
+        *span = span.apply_mark(self.0, self.1)
+    }
+
+    fn visit_mac(&mut self, mac: &mut Mac) {
+        mut_visit::noop_visit_mac(mac, self)
+    }
+}
+
+impl Marker {
+    fn visit_delim_span(&mut self, dspan: &mut DelimSpan) {
+        self.visit_span(&mut dspan.open);
+        self.visit_span(&mut dspan.close);
+    }
+}
+
 /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
 enum Frame {
     Delimited { forest: Lrc<quoted::Delimited>, idx: usize, span: DelimSpan },
@@ -68,6 +90,7 @@ pub(super) fn transcribe(
     cx: &ExtCtxt<'_>,
     interp: &FxHashMap<Ident, NamedMatch>,
     src: Vec<quoted::TokenTree>,
+    transparency: Transparency,
 ) -> TokenStream {
     // Nothing for us to transcribe...
     if src.is_empty() {
@@ -96,6 +119,7 @@ pub(super) fn transcribe(
     // again, and we are done transcribing.
     let mut result: Vec<TreeAndJoint> = Vec::new();
     let mut result_stack = Vec::new();
+    let mut marker = Marker(cx.current_expansion.id, transparency);
 
     loop {
         // Look at the last frame on the stack.
@@ -207,7 +231,7 @@ pub(super) fn transcribe(
             }
 
             // Replace the meta-var with the matched token tree from the invocation.
-            quoted::TokenTree::MetaVar(mut sp, ident) => {
+            quoted::TokenTree::MetaVar(mut sp, mut ident) => {
                 // Find the matched nonterminal from the macro invocation, and use it to replace
                 // the meta-var.
                 if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
@@ -218,7 +242,7 @@ pub(super) fn transcribe(
                         if let NtTT(ref tt) = **nt {
                             result.push(tt.clone().into());
                         } else {
-                            sp = sp.apply_mark(cx.current_expansion.id);
+                            marker.visit_span(&mut sp);
                             let token = TokenTree::token(token::Interpolated(nt.clone()), sp);
                             result.push(token.into());
                         }
@@ -232,9 +256,8 @@ pub(super) fn transcribe(
                 } else {
                     // If we aren't able to match the meta-var, we push it back into the result but
                     // with modified syntax context. (I believe this supports nested macros).
-                    let ident =
-                        Ident::new(ident.name, ident.span.apply_mark(cx.current_expansion.id));
-                    sp = sp.apply_mark(cx.current_expansion.id);
+                    marker.visit_span(&mut sp);
+                    marker.visit_ident(&mut ident);
                     result.push(TokenTree::token(token::Dollar, sp).into());
                     result.push(TokenTree::Token(Token::from_ast_ident(ident)).into());
                 }
@@ -246,7 +269,7 @@ pub(super) fn transcribe(
             // jump back out of the Delimited, pop the result_stack and add the new results back to
             // the previous results (from outside the Delimited).
             quoted::TokenTree::Delimited(mut span, delimited) => {
-                span = span.apply_mark(cx.current_expansion.id);
+                marker.visit_delim_span(&mut span);
                 stack.push(Frame::Delimited { forest: delimited, idx: 0, span });
                 result_stack.push(mem::take(&mut result));
             }
@@ -254,9 +277,8 @@ pub(super) fn transcribe(
             // Nothing much to do here. Just push the token to the result, being careful to
             // preserve syntax context.
             quoted::TokenTree::Token(token) => {
-                let mut marker = Marker(cx.current_expansion.id);
                 let mut tt = TokenTree::Token(token);
-                noop_visit_tt(&mut tt, &mut marker);
+                marker.visit_tt(&mut tt);
                 result.push(tt.into());
             }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
deleted file mode 100644
index bbc3ae28225..00000000000
--- a/src/libsyntax/feature_gate.rs
+++ /dev/null
@@ -1,2510 +0,0 @@
-//! # Feature gating
-//!
-//! This module implements the gating necessary for preventing certain compiler
-//! features from being used by default. This module will crawl a pre-expanded
-//! AST to ensure that there are no features which are used that are not
-//! enabled.
-//!
-//! Features are enabled in programs via the crate-level attributes of
-//! `#![feature(...)]` with a comma-separated list of features.
-//!
-//! For the purpose of future feature-tracking, once code for detection of feature
-//! gate usage is added, *do not remove it again* even once the feature
-//! becomes stable.
-
-use AttributeType::*;
-use AttributeGate::*;
-
-use crate::ast::{
-    self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
-    PatKind, RangeEnd,
-};
-use crate::attr::{self, check_builtin_attribute, AttributeTemplate};
-use crate::source_map::Spanned;
-use crate::edition::{ALL_EDITIONS, Edition};
-use crate::visit::{self, FnKind, Visitor};
-use crate::parse::{token, ParseSess};
-use crate::parse::parser::Parser;
-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 lazy_static::lazy_static;
-
-use std::env;
-
-macro_rules! set {
-    ($field: ident) => {{
-        fn f(features: &mut Features, _: Span) {
-            features.$field = true;
-        }
-        f as fn(&mut Features, Span)
-    }}
-}
-
-macro_rules! declare_features {
-    ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => {
-        /// Represents active features that are currently being implemented or
-        /// currently being considered for addition/removal.
-        const ACTIVE_FEATURES:
-            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
-            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
-
-        /// A set of features to be used by later passes.
-        #[derive(Clone)]
-        pub struct Features {
-            /// `#![feature]` attrs for language features, for error reporting
-            pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
-            /// `#![feature]` attrs for non-language (library) features
-            pub declared_lib_features: Vec<(Symbol, Span)>,
-            $(pub $feature: bool),+
-        }
-
-        impl Features {
-            pub fn new() -> Features {
-                Features {
-                    declared_lang_features: Vec::new(),
-                    declared_lib_features: Vec::new(),
-                    $($feature: false),+
-                }
-            }
-
-            pub fn walk_feature_fields<F>(&self, mut f: F)
-                where F: FnMut(&str, bool)
-            {
-                $(f(stringify!($feature), self.$feature);)+
-            }
-        }
-    };
-
-    ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
-        /// Represents unstable features which have since been removed (it was once Active)
-        const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, $reason)),+
-        ];
-    };
-
-    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
-        /// Represents stable features which have since been removed (it was once Accepted)
-        const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
-        ];
-    };
-
-    ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
-        /// Those language feature has since been Accepted (it was once Active)
-        const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
-        ];
-    }
-}
-
-// If you change this, please modify `src/doc/unstable-book` as well.
-//
-// Don't ever remove anything from this list; set them to 'Removed'.
-//
-// The version numbers here correspond to the version in which the current status
-// was set. This is most important for knowing when a particular feature became
-// stable (active).
-//
-// Note that the features are grouped into internal/user-facing and then
-// sorted by version inside those groups. This is inforced with tidy.
-//
-// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
-// source, so take care when modifying it.
-
-declare_features! (
-    // -------------------------------------------------------------------------
-    // feature-group-start: internal feature gates
-    // -------------------------------------------------------------------------
-
-    // no-tracking-issue-start
-
-    // Allows using compiler's own crates.
-    (active, rustc_private, "1.0.0", Some(27812), None),
-
-    // Allows using the `rust-intrinsic`'s "ABI".
-    (active, intrinsics, "1.0.0", None, None),
-
-    // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
-    (active, lang_items, "1.0.0", None, None),
-
-    // Allows using the `#[stable]` and `#[unstable]` attributes.
-    (active, staged_api, "1.0.0", None, None),
-
-    // Allows using `#[allow_internal_unstable]`. This is an
-    // attribute on `macro_rules!` and can't use the attribute handling
-    // below (it has to be checked before expansion possibly makes
-    // macros disappear).
-    (active, allow_internal_unstable, "1.0.0", None, None),
-
-    // Allows using `#[allow_internal_unsafe]`. This is an
-    // attribute on `macro_rules!` and can't use the attribute handling
-    // below (it has to be checked before expansion possibly makes
-    // macros disappear).
-    (active, allow_internal_unsafe, "1.0.0", None, None),
-
-    // Allows using the macros:
-    // + `__diagnostic_used`
-    // + `__register_diagnostic`
-    // +`__build_diagnostic_array`
-    (active, rustc_diagnostic_macros, "1.0.0", None, None),
-
-    // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
-    // lets a function to be `const` when opted into with `#![feature(foo)]`.
-    (active, rustc_const_unstable, "1.0.0", None, None),
-
-    // no-tracking-issue-end
-
-    // Allows using `#[link_name="llvm.*"]`.
-    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
-
-    // 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),
-
-    // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
-    (active, main, "1.0.0", Some(29634), None),
-
-    // Allows using `#[start]` on a function indicating that it is the program entrypoint.
-    (active, start, "1.0.0", Some(29633), None),
-
-    // Allows using the `#[fundamental]` attribute.
-    (active, fundamental, "1.0.0", Some(29635), None),
-
-    // Allows using the `rust-call` ABI.
-    (active, unboxed_closures, "1.0.0", Some(29625), None),
-
-    // Allows using the `#[linkage = ".."]` attribute.
-    (active, linkage, "1.0.0", Some(29603), None),
-
-    // Allows features specific to OIBIT (auto traits).
-    (active, optin_builtin_traits, "1.0.0", Some(13231), None),
-
-    // Allows using `box` in patterns (RFC 469).
-    (active, box_patterns, "1.0.0", Some(29641), None),
-
-    // no-tracking-issue-start
-
-    // Allows using `#[prelude_import]` on glob `use` items.
-    (active, prelude_import, "1.2.0", None, None),
-
-    // no-tracking-issue-end
-
-    // no-tracking-issue-start
-
-    // Allows using `#[omit_gdb_pretty_printer_section]`.
-    (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
-
-    // Allows using the `vectorcall` ABI.
-    (active, abi_vectorcall, "1.7.0", None, None),
-
-    // no-tracking-issue-end
-
-    // Allows using `#[structural_match]` which indicates that a type is structurally matchable.
-    (active, structural_match, "1.8.0", Some(31434), None),
-
-    // Allows using the `may_dangle` attribute (RFC 1327).
-    (active, dropck_eyepatch, "1.10.0", Some(34761), None),
-
-    // Allows using the `#![panic_runtime]` attribute.
-    (active, panic_runtime, "1.10.0", Some(32837), None),
-
-    // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
-    (active, needs_panic_runtime, "1.10.0", Some(32837), None),
-
-    // no-tracking-issue-start
-
-    // Allows identifying the `compiler_builtins` crate.
-    (active, compiler_builtins, "1.13.0", None, None),
-
-    // Allows using the `unadjusted` ABI; perma-unstable.
-    (active, abi_unadjusted, "1.16.0", None, None),
-
-    // Allows identifying crates that contain sanitizer runtimes.
-    (active, sanitizer_runtime, "1.17.0", None, None),
-
-    // Used to identify crates that contain the profiler runtime.
-    (active, profiler_runtime, "1.18.0", None, None),
-
-    // Allows using the `thiscall` ABI.
-    (active, abi_thiscall, "1.19.0", None, None),
-
-    // 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)),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: internal feature gates
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // feature-group-start: actual feature gates (target features)
-    // -------------------------------------------------------------------------
-
-    // FIXME: Document these and merge with the list below.
-
-    // Unstable `#[target_feature]` directives.
-    (active, arm_target_feature, "1.27.0", Some(44839), None),
-    (active, aarch64_target_feature, "1.27.0", Some(44839), None),
-    (active, hexagon_target_feature, "1.27.0", Some(44839), None),
-    (active, powerpc_target_feature, "1.27.0", Some(44839), None),
-    (active, mips_target_feature, "1.27.0", Some(44839), None),
-    (active, avx512_target_feature, "1.27.0", Some(44839), None),
-    (active, mmx_target_feature, "1.27.0", Some(44839), None),
-    (active, sse4a_target_feature, "1.27.0", Some(44839), None),
-    (active, tbm_target_feature, "1.27.0", Some(44839), None),
-    (active, wasm_target_feature, "1.30.0", Some(44839), None),
-    (active, adx_target_feature, "1.32.0", Some(44839), None),
-    (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
-    (active, movbe_target_feature, "1.34.0", Some(44839), None),
-    (active, rtm_target_feature, "1.35.0", Some(44839), None),
-    (active, f16c_target_feature, "1.36.0", Some(44839), None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: actual feature gates (target features)
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // feature-group-start: actual feature gates
-    // -------------------------------------------------------------------------
-
-    // Allows using the `#[link_args]` attribute.
-    (active, link_args, "1.0.0", Some(29596), None),
-
-    // Allows defining identifiers beyond ASCII.
-    (active, non_ascii_idents, "1.0.0", Some(55467), None),
-
-    // Allows using `#[plugin_registrar]` on functions.
-    (active, plugin_registrar, "1.0.0", Some(29597), None),
-
-    // Allows using `#![plugin(myplugin)]`.
-    (active, plugin, "1.0.0", Some(29597), None),
-
-    // Allows using `#[thread_local]` on `static` items.
-    (active, thread_local, "1.0.0", Some(29594), None),
-
-    // 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),
-
-    // Allows using slice patterns.
-    (active, slice_patterns, "1.0.0", Some(62254), None),
-
-    // Allows the definition of `const` functions with some advanced features.
-    (active, const_fn, "1.2.0", Some(57563), None),
-
-    // Allows associated type defaults.
-    (active, associated_type_defaults, "1.2.0", Some(29661), None),
-
-    // Allows `#![no_core]`.
-    (active, no_core, "1.3.0", Some(29639), None),
-
-    // Allows default type parameters to influence type inference.
-    (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
-
-    // Allows `repr(simd)` and importing the various simd intrinsics.
-    (active, repr_simd, "1.4.0", Some(27731), None),
-
-    // Allows `extern "platform-intrinsic" { ... }`.
-    (active, platform_intrinsics, "1.4.0", Some(27731), None),
-
-    // Allows `#[unwind(..)]`.
-    //
-    // Permits specifying whether a function should permit unwinding or abort on unwind.
-    (active, unwind_attributes, "1.4.0", Some(58760), None),
-
-    // Allows `#[no_debug]`.
-    (active, no_debug, "1.5.0", Some(29721), None),
-
-    // Allows attributes on expressions and non-item statements.
-    (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
-
-    // Allows the use of type ascription in expressions.
-    (active, type_ascription, "1.6.0", Some(23416), None),
-
-    // Allows `cfg(target_thread_local)`.
-    (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
-
-    // Allows specialization of implementations (RFC 1210).
-    (active, specialization, "1.7.0", Some(31844), None),
-
-    // Allows using `#[naked]` on functions.
-    (active, naked_functions, "1.9.0", Some(32408), None),
-
-    // Allows `cfg(target_has_atomic = "...")`.
-    (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
-
-    // Allows `X..Y` patterns.
-    (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
-
-    // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
-    (active, never_type, "1.13.0", Some(35121), None),
-
-    // Allows exhaustive pattern matching on types that contain uninhabited types.
-    (active, exhaustive_patterns, "1.13.0", Some(51085), None),
-
-    // Allows untagged unions `union U { ... }`.
-    (active, untagged_unions, "1.13.0", Some(32836), None),
-
-    // Allows `#[link(..., cfg(..))]`.
-    (active, link_cfg, "1.14.0", Some(37406), None),
-
-    // Allows `extern "ptx-*" fn()`.
-    (active, abi_ptx, "1.15.0", Some(38788), None),
-
-    // Allows the `#[repr(i128)]` attribute for enums.
-    (active, repr128, "1.16.0", Some(35118), None),
-
-    // Allows `#[link(kind="static-nobundle"...)]`.
-    (active, static_nobundle, "1.16.0", Some(37403), None),
-
-    // Allows `extern "msp430-interrupt" fn()`.
-    (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
-
-    // Allows declarative macros 2.0 (`macro`).
-    (active, decl_macro, "1.17.0", Some(39412), None),
-
-    // Allows `extern "x86-interrupt" fn()`.
-    (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
-
-    // Allows overlapping impls of marker traits.
-    (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
-
-    // Allows a test to fail without failing the whole suite.
-    (active, allow_fail, "1.19.0", Some(46488), None),
-
-    // Allows unsized tuple coercion.
-    (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
-
-    // Allows defining generators.
-    (active, generators, "1.21.0", Some(43122), None),
-
-    // Allows `#[doc(cfg(...))]`.
-    (active, doc_cfg, "1.21.0", Some(43781), None),
-
-    // Allows `#[doc(masked)]`.
-    (active, doc_masked, "1.21.0", Some(44027), None),
-
-    // Allows `#[doc(spotlight)]`.
-    (active, doc_spotlight, "1.22.0", Some(45040), None),
-
-    // Allows `#[doc(include = "some-file")]`.
-    (active, external_doc, "1.22.0", Some(44732), None),
-
-    // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
-    (active, non_exhaustive, "1.22.0", Some(44109), None),
-
-    // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
-    (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
-
-    // Allows defining `extern type`s.
-    (active, extern_types, "1.23.0", Some(43467), None),
-
-    // Allows trait methods with arbitrary self types.
-    (active, arbitrary_self_types, "1.23.0", Some(44874), None),
-
-    // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
-    (active, in_band_lifetimes, "1.23.0", Some(44524), None),
-
-    // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
-    (active, generic_associated_types, "1.23.0", Some(44265), None),
-
-    // Allows defining `trait X = A + B;` alias items.
-    (active, trait_alias, "1.24.0", Some(41517), None),
-
-    // Allows infering `'static` outlives requirements (RFC 2093).
-    (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
-
-    // Allows macro invocations in `extern {}` blocks.
-    (active, macros_in_extern, "1.27.0", Some(49476), None),
-
-    // Allows accessing fields of unions inside `const` functions.
-    (active, const_fn_union, "1.27.0", Some(51909), None),
-
-    // Allows casting raw pointers to `usize` during const eval.
-    (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
-
-    // Allows dereferencing raw pointers during const eval.
-    (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
-
-    // Allows comparing raw pointers during const eval.
-    (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
-
-    // Allows `#[doc(alias = "...")]`.
-    (active, doc_alias, "1.27.0", Some(50146), None),
-
-    // Allows inconsistent bounds in where clauses.
-    (active, trivial_bounds, "1.28.0", Some(48214), None),
-
-    // Allows `'a: { break 'a; }`.
-    (active, label_break_value, "1.28.0", Some(48594), None),
-
-    // Allows using `#[doc(keyword = "...")]`.
-    (active, doc_keyword, "1.28.0", Some(51315), None),
-
-    // Allows async and await syntax.
-    (active, async_await, "1.28.0", Some(50547), None),
-
-    // Allows reinterpretation of the bits of a value of one type as another type during const eval.
-    (active, const_transmute, "1.29.0", Some(53605), None),
-
-    // Allows using `try {...}` expressions.
-    (active, try_blocks, "1.29.0", Some(31436), None),
-
-    // Allows defining an `#[alloc_error_handler]`.
-    (active, alloc_error_handler, "1.29.0", Some(51540), None),
-
-    // Allows using the `amdgpu-kernel` ABI.
-    (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
-
-    // Allows panicking during const eval (producing compile-time errors).
-    (active, const_panic, "1.30.0", Some(51999), None),
-
-    // Allows `#[marker]` on certain traits allowing overlapping implementations.
-    (active, marker_trait_attr, "1.30.0", Some(29864), None),
-
-    // Allows macro invocations on modules expressions and statements and
-    // procedural macros to expand to non-items.
-    (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
-
-    // Allows unsized rvalues at arguments and parameters.
-    (active, unsized_locals, "1.30.0", Some(48055), None),
-
-    // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
-    (active, custom_test_frameworks, "1.30.0", Some(50297), None),
-
-    // Allows non-builtin attributes in inner attribute position.
-    (active, custom_inner_attributes, "1.30.0", Some(54726), None),
-
-    // Allows mixing bind-by-move in patterns and references to those identifiers in guards.
-    (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
-
-    // Allows `impl Trait` in bindings (`let`, `const`, `static`).
-    (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
-
-    // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
-    (active, lint_reasons, "1.31.0", Some(54503), None),
-
-    // 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),
-
-    // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
-    (active, const_generics, "1.34.0", Some(44580), None),
-
-    // Allows using `#[optimize(X)]`.
-    (active, optimize_attribute, "1.34.0", Some(54882), None),
-
-    // Allows using C-variadics.
-    (active, c_variadic, "1.34.0", Some(44930), None),
-
-    // Allows the user of associated type bounds.
-    (active, associated_type_bounds, "1.34.0", Some(52662), None),
-
-    // Attributes on formal function params.
-    (active, param_attrs, "1.36.0", Some(60406), None),
-
-    // Allows calling constructor functions in `const fn`.
-    (active, const_constructor, "1.37.0", Some(61456), None),
-
-    // Allows `if/while p && let q = r && ...` chains.
-    (active, let_chains, "1.37.0", Some(53667), None),
-
-    // Allows #[repr(transparent)] on enums (RFC 2645).
-    (active, transparent_enums, "1.37.0", Some(60405), None),
-
-    // Allows #[repr(transparent)] on unions (RFC 2645).
-    (active, transparent_unions, "1.37.0", Some(60405), None),
-
-    // Allows explicit discriminants on non-unit enum variants.
-    (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
-
-    // Allows `impl Trait` with multiple unrelated lifetimes.
-    (active, member_constraints, "1.37.0", Some(61977), None),
-
-    // Allows `async || body` closures.
-    (active, async_closure, "1.37.0", Some(62290), None),
-
-    // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
-    (active, cfg_doctest, "1.37.0", Some(62210), None),
-
-    // Allows `[x; N]` where `x` is a constant (RFC 2203).
-    (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
-
-    // Allows `impl Trait` to be used inside type aliases (RFC 2515).
-    (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
-
-    // Allows the use of or-patterns, e.g. `0 | 1`.
-    (active, or_patterns, "1.38.0", Some(54883), None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: actual feature gates
-    // -------------------------------------------------------------------------
-);
-
-/// Some features are known to be incomplete and using them is likely to have
-/// unanticipated results, such as compiler crashes. We warn the user about these
-/// to alert them.
-pub const INCOMPLETE_FEATURES: &[Symbol] = &[
-    sym::impl_trait_in_bindings,
-    sym::generic_associated_types,
-    sym::const_generics,
-    sym::or_patterns,
-    sym::let_chains,
-];
-
-declare_features! (
-    // -------------------------------------------------------------------------
-    // feature-group-start: removed features
-    // -------------------------------------------------------------------------
-
-    (removed, import_shadowing, "1.0.0", None, None, None),
-    (removed, managed_boxes, "1.0.0", None, None, None),
-    // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
-    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
-    (removed, reflect, "1.0.0", Some(27749), None, None),
-    // A way to temporarily opt out of opt in copy. This will *never* be accepted.
-    (removed, opt_out_copy, "1.0.0", None, None, None),
-    (removed, quad_precision_float, "1.0.0", None, None, None),
-    (removed, struct_inherit, "1.0.0", None, None, None),
-    (removed, test_removed_feature, "1.0.0", None, None, None),
-    (removed, visible_private_types, "1.0.0", None, None, None),
-    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
-    // Allows using items which are missing stability attributes
-    (removed, unmarked_api, "1.0.0", None, None, None),
-    (removed, allocator, "1.0.0", None, None, None),
-    (removed, simd, "1.0.0", Some(27731), None,
-     Some("removed in favor of `#[repr(simd)]`")),
-    (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
-     Some("merged into `#![feature(slice_patterns)]`")),
-    (removed, macro_reexport, "1.0.0", Some(29638), None,
-     Some("subsumed by `pub use`")),
-    (removed, pushpop_unsafe, "1.2.0", None, None, None),
-    (removed, needs_allocator, "1.4.0", Some(27389), None,
-     Some("subsumed by `#![feature(allocator_internals)]`")),
-    (removed, proc_macro_mod, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_expr, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_non_items, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_gen, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, panic_implementation, "1.28.0", Some(44489), None,
-     Some("subsumed by `#[panic_handler]`")),
-    // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
-    (removed, custom_derive, "1.32.0", Some(29644), None,
-     Some("subsumed by `#[proc_macro_derive]`")),
-    // Paths of the form: `extern::foo::bar`
-    (removed, extern_in_paths, "1.33.0", Some(55600), None,
-     Some("subsumed by `::foo::bar` paths")),
-    (removed, quote, "1.33.0", Some(29601), None, None),
-    // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
-    (removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
-    (removed, await_macro, "1.38.0", Some(50547), None,
-     Some("subsumed by `.await` syntax")),
-    // Allows defining `existential type`s.
-    (removed, existential_type, "1.38.0", Some(63063), None,
-     Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: removed features
-    // -------------------------------------------------------------------------
-);
-
-declare_features! (
-    (stable_removed, no_stack_check, "1.0.0", None, None),
-);
-
-declare_features! (
-    // -------------------------------------------------------------------------
-    // feature-group-start: for testing purposes
-    // -------------------------------------------------------------------------
-
-    // A temporary feature gate used to enable parser extensions needed
-    // to bootstrap fix for #5723.
-    (accepted, issue_5723_bootstrap, "1.0.0", None, None),
-    // These are used to test this portion of the compiler,
-    // they don't actually mean anything.
-    (accepted, test_accepted_feature, "1.0.0", None, None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: for testing purposes
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // feature-group-start: accepted features
-    // -------------------------------------------------------------------------
-
-    // Allows using associated `type`s in `trait`s.
-    (accepted, associated_types, "1.0.0", None, None),
-    // Allows using assigning a default type to type parameters in algebraic data type definitions.
-    (accepted, default_type_params, "1.0.0", None, None),
-    // FIXME: explain `globs`.
-    (accepted, globs, "1.0.0", None, None),
-    // Allows `macro_rules!` items.
-    (accepted, macro_rules, "1.0.0", None, None),
-    // Allows use of `&foo[a..b]` as a slicing syntax.
-    (accepted, slicing_syntax, "1.0.0", None, None),
-    // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
-    (accepted, struct_variant, "1.0.0", None, None),
-    // Allows indexing tuples.
-    (accepted, tuple_indexing, "1.0.0", None, None),
-    // Allows the use of `if let` expressions.
-    (accepted, if_let, "1.0.0", None, None),
-    // Allows the use of `while let` expressions.
-    (accepted, while_let, "1.0.0", None, None),
-    // Allows using `#![no_std]`.
-    (accepted, no_std, "1.6.0", None, None),
-    // Allows overloading augmented assignment operations like `a += b`.
-    (accepted, augmented_assignments, "1.8.0", Some(28235), None),
-    // Allows empty structs and enum variants with braces.
-    (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
-    // Allows `#[deprecated]` attribute.
-    (accepted, deprecated, "1.9.0", Some(29935), None),
-    // Allows macros to appear in the type position.
-    (accepted, type_macros, "1.13.0", Some(27245), None),
-    // Allows use of the postfix `?` operator in expressions.
-    (accepted, question_mark, "1.13.0", Some(31436), None),
-    // Allows `..` in tuple (struct) patterns.
-    (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
-    // Allows some increased flexibility in the name resolution rules,
-    // especially around globs and shadowing (RFC 1560).
-    (accepted, item_like_imports, "1.15.0", Some(35120), None),
-    // Allows using `Self` and associated types in struct expressions and patterns.
-    (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
-    // Allows elision of `'static` lifetimes in `static`s and `const`s.
-    (accepted, static_in_const, "1.17.0", Some(35897), None),
-    // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
-    (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
-    // Allows the definition recursive static items.
-    (accepted, static_recursion, "1.17.0", Some(29719), None),
-    // Allows `pub(restricted)` visibilities (RFC 1422).
-    (accepted, pub_restricted, "1.18.0", Some(32409), None),
-    // Allows `#![windows_subsystem]`.
-    (accepted, windows_subsystem, "1.18.0", Some(37499), None),
-    // Allows `break {expr}` with a value inside `loop`s.
-    (accepted, loop_break_value, "1.19.0", Some(37339), None),
-    // Allows numeric fields in struct expressions and patterns.
-    (accepted, relaxed_adts, "1.19.0", Some(35626), None),
-    // Allows coercing non capturing closures to function pointers.
-    (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
-    // Allows attributes on struct literal fields.
-    (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
-    // Allows the definition of associated constants in `trait` or `impl` blocks.
-    (accepted, associated_consts, "1.20.0", Some(29646), None),
-    // Allows usage of the `compile_error!` macro.
-    (accepted, compile_error, "1.20.0", Some(40872), None),
-    // Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
-    (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
-    // Allows `Drop` types in constants (RFC 1440).
-    (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
-    // Allows the sysV64 ABI to be specified on all platforms
-    // instead of just the platforms on which it is the C ABI.
-    (accepted, abi_sysv64, "1.24.0", Some(36167), None),
-    // Allows `repr(align(16))` struct attribute (RFC 1358).
-    (accepted, repr_align, "1.25.0", Some(33626), None),
-    // Allows '|' at beginning of match arms (RFC 1925).
-    (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
-    // Allows nested groups in `use` items (RFC 2128).
-    (accepted, use_nested_groups, "1.25.0", Some(44494), None),
-    // Allows indexing into constant arrays.
-    (accepted, const_indexing, "1.26.0", Some(29947), None),
-    // Allows using `a..=b` and `..=b` as inclusive range syntaxes.
-    (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
-    // Allows `..=` in patterns (RFC 1192).
-    (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
-    // Allows `fn main()` with return types which implements `Termination` (RFC 1937).
-    (accepted, termination_trait, "1.26.0", Some(43301), None),
-    // Allows implementing `Clone` for closures where possible (RFC 2132).
-    (accepted, clone_closures, "1.26.0", Some(44490), None),
-    // Allows implementing `Copy` for closures where possible (RFC 2132).
-    (accepted, copy_closures, "1.26.0", Some(44490), None),
-    // Allows `impl Trait` in function arguments.
-    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
-    // Allows `impl Trait` in function return types.
-    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
-    // Allows using the `u128` and `i128` types.
-    (accepted, i128_type, "1.26.0", Some(35118), None),
-    // Allows default match binding modes (RFC 2005).
-    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
-    // Allows `'_` placeholder lifetimes.
-    (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
-    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
-    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
-    // Allows `cfg(target_feature = "...")`.
-    (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
-    // Allows `#[target_feature(...)]`.
-    (accepted, target_feature, "1.27.0", None, None),
-    // Allows using `dyn Trait` as a syntax for trait objects.
-    (accepted, dyn_trait, "1.27.0", Some(44662), None),
-    // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
-    (accepted, fn_must_use, "1.27.0", Some(43302), None),
-    // Allows use of the `:lifetime` macro fragment specifier.
-    (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
-    // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
-    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
-    // Allows the `#[global_allocator]` attribute.
-    (accepted, global_allocator, "1.28.0", Some(27389), None),
-    // Allows `#[repr(transparent)]` attribute on newtype structs.
-    (accepted, repr_transparent, "1.28.0", Some(43036), None),
-    // Allows procedural macros in `proc-macro` crates.
-    (accepted, proc_macro, "1.29.0", Some(38356), None),
-    // Allows `foo.rs` as an alternative to `foo/mod.rs`.
-    (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
-    // Allows use of the `:vis` macro fragment specifier
-    (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
-    // Allows importing and reexporting macros with `use`,
-    // enables macro modularization in general.
-    (accepted, use_extern_macros, "1.30.0", Some(35896), None),
-    // Allows keywords to be escaped for use as identifiers.
-    (accepted, raw_identifiers, "1.30.0", Some(48589), None),
-    // Allows attributes scoped to tools.
-    (accepted, tool_attributes, "1.30.0", Some(44690), None),
-    // Allows multi-segment paths in attributes and derives.
-    (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
-    // Allows all literals in attribute lists and values of key-value pairs.
-    (accepted, attr_literals, "1.30.0", Some(34981), None),
-    // Allows inferring outlives requirements (RFC 2093).
-    (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
-    // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
-    // This defines the behavior of panics.
-    (accepted, panic_handler, "1.30.0", Some(44489), None),
-    // Allows `#[used]` to preserve symbols (see llvm.used).
-    (accepted, used, "1.30.0", Some(40289), None),
-    // Allows `crate` in paths.
-    (accepted, crate_in_paths, "1.30.0", Some(45477), None),
-    // Allows resolving absolute paths as paths from other crates.
-    (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
-    // Allows access to crate names passed via `--extern` through prelude.
-    (accepted, extern_prelude, "1.30.0", Some(44660), None),
-    // Allows parentheses in patterns.
-    (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
-    // Allows the definition of `const fn` functions.
-    (accepted, min_const_fn, "1.31.0", Some(53555), None),
-    // Allows scoped lints.
-    (accepted, tool_lints, "1.31.0", Some(44690), None),
-    // Allows lifetime elision in `impl` headers. For example:
-    // + `impl<I:Iterator> Iterator for &mut Iterator`
-    // + `impl Debug for Foo<'_>`
-    (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
-    // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
-    (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
-    // Allows use of the `:literal` macro fragment specifier (RFC 1576).
-    (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
-    // Allows use of `?` as the Kleene "at most one" operator in macros.
-    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
-    // Allows `Self` struct constructor (RFC 2302).
-    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
-    // Allows `Self` in type definitions (RFC 2300).
-    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
-    // Allows `use x::y;` to search `x` in the current scope.
-    (accepted, uniform_paths, "1.32.0", Some(53130), None),
-    // Allows integer match exhaustiveness checking (RFC 2591).
-    (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
-    // Allows `use path as _;` and `extern crate c as _;`.
-    (accepted, underscore_imports, "1.33.0", Some(48216), None),
-    // Allows `#[repr(packed(N))]` attribute on structs.
-    (accepted, repr_packed, "1.33.0", Some(33158), None),
-    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
-    (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
-    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
-    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
-    // Allows let bindings, assignments and destructuring in `const` functions and constants.
-    // As long as control flow is not implemented in const eval, `&&` and `||` may not be used
-    // at the same time as let bindings.
-    (accepted, const_let, "1.33.0", Some(48821), None),
-    // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
-    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
-    // Allows top level or-patterns (`p | q`) in `if let` and `while let`.
-    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
-    // Allows `cfg(target_vendor = "...")`.
-    (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
-    // Allows `extern crate self as foo;`.
-    // This puts local crate root into extern prelude under name `foo`.
-    (accepted, extern_crate_self, "1.34.0", Some(56409), None),
-    // Allows arbitrary delimited token streams in non-macro attributes.
-    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
-    // Allows paths to enum variants on type aliases including `Self`.
-    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
-    // Allows using `#[repr(align(X))]` on enums with equivalent semantics
-    // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
-    (accepted, repr_align_enum, "1.37.0", Some(57996), None),
-    // Allows `const _: TYPE = VALUE`.
-    (accepted, underscore_const_names, "1.37.0", Some(54912), None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: accepted features
-    // -------------------------------------------------------------------------
-);
-
-// If you change this, please modify `src/doc/unstable-book` as well. You must
-// move that documentation into the relevant place in the other docs, and
-// remove the chapter on the flag.
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum AttributeType {
-    /// Normal, builtin attribute that is consumed
-    /// by the compiler before the unused_attribute check
-    Normal,
-
-    /// Builtin attribute that may not be consumed by the compiler
-    /// before the unused_attribute check. These attributes
-    /// will be ignored by the unused_attribute lint
-    Whitelisted,
-
-    /// Builtin attribute that is only allowed at the crate level
-    CrateLevel,
-}
-
-pub enum AttributeGate {
-    /// Is gated by a given feature gate, reason
-    /// and function to check if enabled
-    Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
-
-    /// Ungated attribute, can be used on all release channels
-    Ungated,
-}
-
-/// A convenience macro for constructing attribute templates.
-/// E.g., `template!(Word, List: "description")` means that the attribute
-/// supports forms `#[attr]` and `#[attr(description)]`.
-macro_rules! template {
-    (Word) => { template!(@ true, None, None) };
-    (List: $descr: expr) => { template!(@ false, Some($descr), None) };
-    (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
-    (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
-    (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
-    (List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        template!(@ false, Some($descr1), Some($descr2))
-    };
-    (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        template!(@ true, Some($descr1), Some($descr2))
-    };
-    (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
-        word: $word, list: $list, name_value_str: $name_value_str
-    } };
-}
-
-impl AttributeGate {
-    fn is_deprecated(&self) -> bool {
-        match *self {
-            Gated(Stability::Deprecated(_, _), ..) => true,
-            _ => false,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug)]
-pub enum Stability {
-    Unstable,
-    // First argument is tracking issue link; second argument is an optional
-    // help message, which defaults to "remove this attribute"
-    Deprecated(&'static str, Option<&'static str>),
-}
-
-// fn() is not Debug
-impl std::fmt::Debug for AttributeGate {
-    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match *self {
-            Gated(ref stab, name, expl, _) =>
-                write!(fmt, "Gated({:?}, {}, {})", stab, name, expl),
-            Ungated => write!(fmt, "Ungated")
-        }
-    }
-}
-
-macro_rules! cfg_fn {
-    ($field: ident) => {{
-        fn f(features: &Features) -> bool {
-            features.$field
-        }
-        f as fn(&Features) -> bool
-    }}
-}
-
-pub fn deprecated_attributes() -> Vec<&'static (Symbol, AttributeType,
-                                                AttributeTemplate, AttributeGate)> {
-    BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect()
-}
-
-pub fn is_builtin_attr_name(name: ast::Name) -> bool {
-    BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
-}
-
-pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
-    attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).is_some()
-}
-
-/// Attributes that have a special meaning to rustc or rustdoc
-pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
-    // Normal attributes
-
-    (
-        sym::warn,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::allow,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::forbid,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::deny,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-
-    (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
-    (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
-    (sym::plugin_registrar, Normal, template!(Word), Ungated),
-
-    (sym::cfg, Normal, template!(List: "predicate"), Ungated),
-    (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
-    (sym::main, Normal, template!(Word), Ungated),
-    (sym::start, Normal, template!(Word), Ungated),
-    (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
-    (sym::path, Normal, template!(NameValueStr: "file"), Ungated),
-    (sym::automatically_derived, Normal, template!(Word), Ungated),
-    (sym::no_mangle, Whitelisted, template!(Word), Ungated),
-    (sym::no_link, Normal, template!(Word), Ungated),
-    (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
-    (
-        sym::should_panic,
-        Normal,
-        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
-        Ungated
-    ),
-    (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
-    (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
-    (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
-    (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
-                                sym::link_args,
-                                "the `link_args` attribute is experimental and not \
-                                portable across platforms, it is recommended to \
-                                use `#[link(name = \"foo\")] instead",
-                                cfg_fn!(link_args))),
-    (sym::macro_escape, Normal, template!(Word), Ungated),
-
-    // RFC #1445.
-    (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::structural_match,
-                                            "the semantics of constant patterns is \
-                                            not yet settled",
-                                            cfg_fn!(structural_match))),
-
-    // RFC #2008
-    (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::non_exhaustive,
-                                        "non exhaustive is an experimental feature",
-                                        cfg_fn!(non_exhaustive))),
-
-    // RFC #1268
-    (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
-                            sym::marker_trait_attr,
-                            "marker traits is an experimental feature",
-                            cfg_fn!(marker_trait_attr))),
-
-    (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
-                                sym::plugin,
-                                "compiler plugins are experimental \
-                                and possibly buggy",
-                                cfg_fn!(plugin))),
-
-    (sym::no_std, CrateLevel, template!(Word), Ungated),
-    (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
-                                sym::no_core,
-                                "no_core is experimental",
-                                cfg_fn!(no_core))),
-    (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
-                        sym::lang_items,
-                        "language items are subject to change",
-                        cfg_fn!(lang_items))),
-    (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
-                                Gated(Stability::Unstable,
-                                sym::linkage,
-                                "the `linkage` attribute is experimental \
-                                    and not portable across platforms",
-                                cfg_fn!(linkage))),
-    (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::thread_local,
-                                        "`#[thread_local]` is an experimental feature, and does \
-                                         not currently handle destructors",
-                                        cfg_fn!(thread_local))),
-
-    (sym::rustc_on_unimplemented, Whitelisted, template!(List:
-                        r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
-                        NameValueStr: "message"),
-                                            Gated(Stability::Unstable,
-                                            sym::on_unimplemented,
-                                            "the `#[rustc_on_unimplemented]` attribute \
-                                            is an experimental feature",
-                                            cfg_fn!(on_unimplemented))),
-    (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
-                                            Gated(Stability::Unstable,
-                                            sym::rustc_const_unstable,
-                                            "the `#[rustc_const_unstable]` attribute \
-                                            is an internal feature",
-                                            cfg_fn!(rustc_const_unstable))),
-    (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::allocator_internals,
-                                            "the `#[default_lib_allocator]` \
-                                            attribute is an experimental feature",
-                                            cfg_fn!(allocator_internals))),
-    (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::allocator_internals,
-                                    "the `#[needs_allocator]` \
-                                    attribute is an experimental \
-                                    feature",
-                                    cfg_fn!(allocator_internals))),
-    (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::panic_runtime,
-                                        "the `#[panic_runtime]` attribute is \
-                                        an experimental feature",
-                                        cfg_fn!(panic_runtime))),
-    (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::needs_panic_runtime,
-                                            "the `#[needs_panic_runtime]` \
-                                                attribute is an experimental \
-                                                feature",
-                                            cfg_fn!(needs_panic_runtime))),
-    (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_outlives]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_variance]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout]` attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout_scalar_valid_range_start]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout_scalar_valid_range_end]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_nonnull_optimization_guaranteed]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_regions]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_error]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "this attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
-                                                Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "the `#[rustc_if_this_changed]` attribute \
-                                                is just used for rustc unit tests \
-                                                and will never be stable",
-                                                cfg_fn!(rustc_attrs))),
-    (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
-                                                    Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_if_this_changed]` attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
-                                                    /*opt*/ except = "...""#),
-                                    Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_dirty]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
-                                                    /*opt*/ except = "...""#),
-                                    Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_clean]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (
-        sym::rustc_partition_reused,
-        Whitelisted,
-        template!(List: r#"cfg = "...", module = "...""#),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "this attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-            cfg_fn!(rustc_attrs)
-        )
-    ),
-    (
-        sym::rustc_partition_codegened,
-        Whitelisted,
-        template!(List: r#"cfg = "...", module = "...""#),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "this attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-            cfg_fn!(rustc_attrs),
-        )
-    ),
-    (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
-                                                            kind = "...""#),
-                                                    Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::rustc_attrs,
-                                            "internal rustc attributes will never be stable",
-                                            cfg_fn!(rustc_attrs))),
-    (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::rustc_attrs,
-                                        "internal rustc attributes will never be stable",
-                                        cfg_fn!(rustc_attrs))),
-    (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_mir]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (
-        sym::rustc_inherit_overflow_checks,
-        Whitelisted,
-        template!(Word),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "the `#[rustc_inherit_overflow_checks]` \
-            attribute is just used to control \
-            overflow checking behavior of several \
-            libcore functions that are inlined \
-            across crates and will never be stable",
-            cfg_fn!(rustc_attrs),
-        )
-    ),
-
-    (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_dump_program_clauses]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_dump_env_program_clauses]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_object_lifetime_default]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_test_marker]` attribute \
-                                    is used internally to track tests",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr:
-                                                           "transparent|semitransparent|opaque"),
-                                                Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "used internally for testing macro hygiene",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::compiler_builtins,
-                                            "the `#[compiler_builtins]` attribute is used to \
-                                            identify the `compiler_builtins` crate which \
-                                            contains compiler-rt intrinsics and will never be \
-                                            stable",
-                                        cfg_fn!(compiler_builtins))),
-    (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::sanitizer_runtime,
-                                            "the `#[sanitizer_runtime]` attribute is used to \
-                                            identify crates that contain the runtime of a \
-                                            sanitizer and will never be stable",
-                                            cfg_fn!(sanitizer_runtime))),
-    (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::profiler_runtime,
-                                            "the `#[profiler_runtime]` attribute is used to \
-                                            identify the `profiler_builtins` crate which \
-                                            contains the profiler runtime and will never be \
-                                            stable",
-                                            cfg_fn!(profiler_runtime))),
-
-    (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
-                                            Gated(Stability::Unstable,
-                                            sym::allow_internal_unstable,
-                                            EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
-                                            cfg_fn!(allow_internal_unstable))),
-
-    (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
-                                            sym::allow_internal_unsafe,
-                                            EXPLAIN_ALLOW_INTERNAL_UNSAFE,
-                                            cfg_fn!(allow_internal_unsafe))),
-
-    (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::fundamental,
-                                    "the `#[fundamental]` attribute \
-                                        is an experimental feature",
-                                    cfg_fn!(fundamental))),
-
-    (sym::proc_macro_derive, Normal, template!(List: "TraitName, \
-                                                /*opt*/ attributes(name1, name2, ...)"),
-                                    Ungated),
-
-    (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
-                                         sym::rustc_attrs,
-                                         "used by the test suite",
-                                         cfg_fn!(rustc_attrs))),
-
-    // FIXME: #14408 whitelist docs since rustdoc looks at them
-    (
-        sym::doc,
-        Whitelisted,
-        template!(List: "hidden|inline|...", NameValueStr: "string"),
-        Ungated
-    ),
-
-    // FIXME: #14406 these are processed in codegen, which happens after the
-    // lint pass
-    (sym::cold, Whitelisted, template!(Word), Ungated),
-    (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                sym::naked_functions,
-                                "the `#[naked]` attribute \
-                                is an experimental feature",
-                                cfg_fn!(naked_functions))),
-    (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                sym::ffi_returns_twice,
-                                "the `#[ffi_returns_twice]` attribute \
-                                is an experimental feature",
-                                cfg_fn!(ffi_returns_twice))),
-    (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
-    (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
-    (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
-                                               /*opt*/ cfg = "...""#), Ungated),
-    (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::no_builtins, Whitelisted, template!(Word), Ungated),
-    (sym::no_debug, Whitelisted, template!(Word), Gated(
-        Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
-        sym::no_debug,
-        "the `#[no_debug]` attribute was an experimental feature that has been \
-        deprecated due to lack of demand",
-        cfg_fn!(no_debug))),
-    (
-        sym::omit_gdb_pretty_printer_section,
-        Whitelisted,
-        template!(Word),
-        Gated(
-            Stability::Unstable,
-            sym::omit_gdb_pretty_printer_section,
-            "the `#[omit_gdb_pretty_printer_section]` \
-                attribute is just used for the Rust test \
-                suite",
-            cfg_fn!(omit_gdb_pretty_printer_section)
-        )
-    ),
-    (sym::may_dangle,
-    Normal,
-    template!(Word),
-    Gated(Stability::Unstable,
-        sym::dropck_eyepatch,
-        "`may_dangle` has unstable semantics and may be removed in the future",
-        cfg_fn!(dropck_eyepatch))),
-    (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
-                                sym::unwind_attributes,
-                                "`#[unwind]` is experimental",
-                                cfg_fn!(unwind_attributes))),
-    (sym::used, Whitelisted, template!(Word), Ungated),
-
-    // used in resolve
-    (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::prelude_import,
-                                        "`#[prelude_import]` is for use by rustc only",
-                                        cfg_fn!(prelude_import))),
-
-    // FIXME: #14407 these are only looked at on-demand so we can't
-    // guarantee they'll have already been checked
-    (
-        sym::rustc_deprecated,
-        Whitelisted,
-        template!(List: r#"since = "version", reason = "...""#),
-        Ungated
-    ),
-    (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
-    (
-        sym::stable,
-        Whitelisted,
-        template!(List: r#"feature = "name", since = "version""#),
-        Ungated
-    ),
-    (
-        sym::unstable,
-        Whitelisted,
-        template!(List: r#"feature = "name", reason = "...", issue = "N""#),
-        Ungated
-    ),
-    (sym::deprecated,
-        Normal,
-        template!(
-            Word,
-            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
-            NameValueStr: "reason"
-        ),
-        Ungated
-    ),
-
-    (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
-                                        sym::unboxed_closures,
-                                        "unboxed_closures are still evolving",
-                                        cfg_fn!(unboxed_closures))),
-
-    (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
-
-    (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
-    (sym::proc_macro, Normal, template!(Word), Ungated),
-
-    (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
-                                            sym::rustc_attrs,
-                                            "used internally by rustc",
-                                            cfg_fn!(rustc_attrs))),
-
-    (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
-                                sym::allow_fail,
-                                "allow_fail attribute is currently unstable",
-                                cfg_fn!(allow_fail))),
-
-    (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "this is an internal attribute that will \
-                                    never be stable",
-                                    cfg_fn!(rustc_attrs))),
-
-    // whitelists "identity-like" conversion methods to suggest on type mismatch
-    (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this is an internal attribute that will \
-                                                        never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-
-    (
-        sym::rustc_args_required_const,
-        Whitelisted,
-        template!(List: "N"),
-        Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
-           cfg_fn!(rustc_attrs))
-    ),
-    // RFC 2070
-    (sym::panic_handler, Normal, template!(Word), Ungated),
-
-    (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
-                        sym::alloc_error_handler,
-                        "`#[alloc_error_handler]` is an unstable feature",
-                        cfg_fn!(alloc_error_handler))),
-
-    // RFC 2412
-    (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
-                            sym::optimize_attribute,
-                            "`#[optimize]` attribute is an unstable feature",
-                            cfg_fn!(optimize_attribute))),
-
-    // Crate level attributes
-    (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
-    (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
-    (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
-    (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
-    (sym::no_start, CrateLevel, template!(Word), Ungated),
-    (sym::no_main, CrateLevel, template!(Word), Ungated),
-    (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
-                    sym::custom_test_frameworks,
-                    "custom test frameworks are an unstable feature",
-                    cfg_fn!(custom_test_frameworks))),
-];
-
-pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
-
-lazy_static! {
-    pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = {
-        let mut map = FxHashMap::default();
-        for attr in BUILTIN_ATTRIBUTES.iter() {
-            if map.insert(attr.0, attr).is_some() {
-                panic!("duplicate builtin attribute `{}`", attr.0);
-            }
-        }
-        map
-    };
-}
-
-// cfg(...)'s that are feature gated
-const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
-    // (name in cfg, feature, function to check if the feature is enabled)
-    (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
-    (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
-    (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
-    (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
-];
-
-#[derive(Debug)]
-pub struct GatedCfg {
-    span: Span,
-    index: usize,
-}
-
-impl GatedCfg {
-    pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
-        GATED_CFGS.iter()
-                  .position(|info| cfg.check_name(info.0))
-                  .map(|idx| {
-                      GatedCfg {
-                          span: cfg.span,
-                          index: idx
-                      }
-                  })
-    }
-
-    pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
-        let (cfg, feature, has_feature) = GATED_CFGS[self.index];
-        if !has_feature(features) && !self.span.allows_unstable(feature) {
-            let explain = format!("`cfg({})` is experimental and subject to change", cfg);
-            emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain);
-        }
-    }
-}
-
-struct Context<'a> {
-    features: &'a Features,
-    parse_sess: &'a ParseSess,
-    plugin_attributes: &'a [(Symbol, AttributeType)],
-}
-
-macro_rules! gate_feature_fn {
-    ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
-        let (cx, has_feature, span,
-             name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
-        let has_feature: bool = has_feature(&$cx.features);
-        debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
-        if !has_feature && !span.allows_unstable($name) {
-            leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level)
-                .emit();
-        }
-    }}
-}
-
-macro_rules! gate_feature {
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
-        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         sym::$feature, $explain, GateStrength::Hard)
-    };
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
-        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         sym::$feature, $explain, $level)
-    };
-}
-
-impl<'a> Context<'a> {
-    fn check_attribute(
-        &self,
-        attr: &ast::Attribute,
-        attr_info: Option<&BuiltinAttribute>,
-        is_macro: bool
-    ) {
-        debug!("check_attribute(attr = {:?})", attr);
-        if let Some(&(name, ty, _template, ref gateage)) = attr_info {
-            if let Gated(_, name, desc, ref has_feature) = *gateage {
-                if !attr.span.allows_unstable(name) {
-                    gate_feature_fn!(
-                        self, has_feature, attr.span, name, desc, GateStrength::Hard
-                    );
-                }
-            } else if name == sym::doc {
-                if let Some(content) = attr.meta_item_list() {
-                    if content.iter().any(|c| c.check_name(sym::include)) {
-                        gate_feature!(self, external_doc, attr.span,
-                            "`#[doc(include = \"...\")]` is experimental"
-                        );
-                    }
-                }
-            }
-            debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
-            return;
-        } else {
-            for segment in &attr.path.segments {
-                if segment.ident.as_str().starts_with("rustc") {
-                    let msg = "attributes starting with `rustc` are \
-                               reserved for use by the `rustc` compiler";
-                    gate_feature!(self, rustc_attrs, segment.ident.span, msg);
-                }
-            }
-        }
-        for &(n, ty) in self.plugin_attributes {
-            if attr.path == n {
-                // Plugins can't gate attributes, so we don't check for it
-                // unlike the code above; we only use this loop to
-                // short-circuit to avoid the checks below.
-                debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty);
-                return;
-            }
-        }
-        if !is_macro && !attr::is_known(attr) {
-            // Only run the custom attribute lint during regular feature gate
-            // checking. Macro gating runs before the plugin attributes are
-            // registered, so we skip this in that case.
-            let msg = format!("the attribute `{}` is currently unknown to the compiler and \
-                               may have meaning added to it in the future", attr.path);
-            gate_feature!(self, custom_attribute, attr.span, &msg);
-        }
-    }
-}
-
-pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
-    let cx = Context { features, parse_sess, plugin_attributes: &[] };
-    cx.check_attribute(
-        attr,
-        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)),
-        true
-    );
-}
-
-fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
-    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
-        let issue = info.2;
-        // FIXME (#28244): enforce that active features have issue numbers
-        // assert!(issue.is_some())
-        issue
-    } else {
-        // search in Accepted, Removed, or Stable Removed features
-        let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
-            .find(|t| t.0 == feature);
-        match found {
-            Some(&(_, _, issue, _)) => issue,
-            None => panic!("Feature `{}` is not declared anywhere", feature),
-        }
-    }
-}
-
-pub enum GateIssue {
-    Language,
-    Library(Option<u32>)
-}
-
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub enum GateStrength {
-    /// A hard error. (Most feature gates should use this.)
-    Hard,
-    /// Only a warning. (Use this only as backwards-compatibility demands.)
-    Soft,
-}
-
-pub fn emit_feature_err(
-    sess: &ParseSess,
-    feature: Symbol,
-    span: Span,
-    issue: GateIssue,
-    explain: &str,
-) {
-    feature_err(sess, feature, span, issue, explain).emit();
-}
-
-pub fn feature_err<'a, S: Into<MultiSpan>>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: S,
-    issue: GateIssue,
-    explain: &str,
-) -> DiagnosticBuilder<'a> {
-    leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
-}
-
-fn leveled_feature_err<'a, S: Into<MultiSpan>>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: S,
-    issue: GateIssue,
-    explain: &str,
-    level: GateStrength,
-) -> DiagnosticBuilder<'a> {
-    let diag = &sess.span_diagnostic;
-
-    let issue = match issue {
-        GateIssue::Language => find_lang_feature_issue(feature),
-        GateIssue::Library(lib) => lib,
-    };
-
-    let mut err = match level {
-        GateStrength::Hard => {
-            diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658))
-        }
-        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,
-            ));
-        }
-    }
-
-    // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
-    if sess.unstable_features.is_nightly_build() {
-        err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
-    }
-
-    // If we're on stable and only emitting a "soft" warning, add a note to
-    // clarify that the feature isn't "on" (rather than being on but
-    // warning-worthy).
-    if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
-        err.help("a nightly build of the compiler is required to enable this feature");
-    }
-
-    err
-
-}
-
-const EXPLAIN_BOX_SYNTAX: &str =
-    "box expression syntax is experimental; you can call `Box::new` instead";
-
-pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
-    "attributes on expressions are experimental";
-
-pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
-    "allow_internal_unstable side-steps feature gating and stability checks";
-pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
-    "allow_internal_unsafe side-steps the unsafe_code lint";
-
-pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
-    "unsized tuple coercion is not stable enough for use and is subject to change";
-
-struct PostExpansionVisitor<'a> {
-    context: &'a Context<'a>,
-    builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
-}
-
-macro_rules! gate_feature_post {
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
-        let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(sym::$feature) {
-            gate_feature!(cx.context, $feature, span, $explain)
-        }
-    }};
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
-        let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(sym::$feature) {
-            gate_feature!(cx.context, $feature, span, $explain, $level)
-        }
-    }}
-}
-
-impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: Abi, span: Span) {
-        match abi {
-            Abi::RustIntrinsic => {
-                gate_feature_post!(&self, intrinsics, span,
-                                   "intrinsics are subject to change");
-            },
-            Abi::PlatformIntrinsic => {
-                gate_feature_post!(&self, platform_intrinsics, span,
-                                   "platform intrinsics are experimental and possibly buggy");
-            },
-            Abi::Vectorcall => {
-                gate_feature_post!(&self, abi_vectorcall, span,
-                                   "vectorcall is experimental and subject to change");
-            },
-            Abi::Thiscall => {
-                gate_feature_post!(&self, abi_thiscall, span,
-                                   "thiscall is experimental and subject to change");
-            },
-            Abi::RustCall => {
-                gate_feature_post!(&self, unboxed_closures, span,
-                                   "rust-call ABI is subject to change");
-            },
-            Abi::PtxKernel => {
-                gate_feature_post!(&self, abi_ptx, span,
-                                   "PTX ABIs are experimental and subject to change");
-            },
-            Abi::Unadjusted => {
-                gate_feature_post!(&self, abi_unadjusted, span,
-                                   "unadjusted ABI is an implementation detail and perma-unstable");
-            },
-            Abi::Msp430Interrupt => {
-                gate_feature_post!(&self, abi_msp430_interrupt, span,
-                                   "msp430-interrupt ABI is experimental and subject to change");
-            },
-            Abi::X86Interrupt => {
-                gate_feature_post!(&self, abi_x86_interrupt, span,
-                                   "x86-interrupt ABI is experimental and subject to change");
-            },
-            Abi::AmdGpuKernel => {
-                gate_feature_post!(&self, abi_amdgpu_kernel, span,
-                                   "amdgpu-kernel 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 => {}
-        }
-    }
-}
-
-impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
-    fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        let attr_info = attr.ident().and_then(|ident| {
-            self.builtin_attributes.get(&ident.name).map(|a| *a)
-        });
-
-        // Check for gated attributes.
-        self.context.check_attribute(attr, attr_info, false);
-
-        if attr.check_name(sym::doc) {
-            if let Some(content) = attr.meta_item_list() {
-                if content.len() == 1 && content[0].check_name(sym::cfg) {
-                    gate_feature_post!(&self, doc_cfg, attr.span,
-                        "`#[doc(cfg(...))]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::masked)) {
-                    gate_feature_post!(&self, doc_masked, attr.span,
-                        "`#[doc(masked)]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
-                    gate_feature_post!(&self, doc_spotlight, attr.span,
-                        "`#[doc(spotlight)]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::alias)) {
-                    gate_feature_post!(&self, doc_alias, attr.span,
-                        "`#[doc(alias = \"...\")]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::keyword)) {
-                    gate_feature_post!(&self, doc_keyword, attr.span,
-                        "`#[doc(keyword = \"...\")]` is experimental"
-                    );
-                }
-            }
-        }
-
-        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.context.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.context.parse_sess).map_err(|mut err| err.emit()).ok();
-                }
-            }
-        }
-    }
-
-    fn visit_name(&mut self, sp: Span, name: ast::Name) {
-        if !name.as_str().is_ascii() {
-            gate_feature_post!(
-                &self,
-                non_ascii_idents,
-                self.context.parse_sess.source_map().def_span(sp),
-                "non-ascii idents are not fully supported"
-            );
-        }
-    }
-
-    fn visit_item(&mut self, i: &'a ast::Item) {
-        match i.node {
-            ast::ItemKind::ForeignMod(ref foreign_module) => {
-                self.check_abi(foreign_module.abi, i.span);
-            }
-
-            ast::ItemKind::Fn(..) => {
-                if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
-                    gate_feature_post!(&self, plugin_registrar, i.span,
-                                       "compiler plugins are experimental and possibly buggy");
-                }
-                if attr::contains_name(&i.attrs[..], sym::start) {
-                    gate_feature_post!(&self, start, i.span,
-                                      "a `#[start]` function is an experimental \
-                                       feature whose signature may change \
-                                       over time");
-                }
-                if attr::contains_name(&i.attrs[..], sym::main) {
-                    gate_feature_post!(&self, main, i.span,
-                                       "declaration of a non-standard `#[main]` \
-                                        function may change over time, for now \
-                                        a top-level `fn main()` is required");
-                }
-            }
-
-            ast::ItemKind::Struct(..) => {
-                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
-                    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name(sym::simd) {
-                            gate_feature_post!(&self, repr_simd, attr.span,
-                                               "SIMD types are experimental and possibly buggy");
-                        }
-                    }
-                }
-            }
-
-            ast::ItemKind::Enum(ast::EnumDef{ref variants, ..}, ..) => {
-                for variant in variants {
-                    match (&variant.data, &variant.disr_expr) {
-                        (ast::VariantData::Unit(..), _) => {},
-                        (_, Some(disr_expr)) =>
-                            gate_feature_post!(
-                                &self,
-                                arbitrary_enum_discriminant,
-                                disr_expr.value.span,
-                                "discriminants on non-unit variants are experimental"),
-                        _ => {},
-                    }
-                }
-
-                let has_feature = self.context.features.arbitrary_enum_discriminant;
-                if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
-                    Parser::maybe_report_invalid_custom_discriminants(
-                        self.context.parse_sess,
-                        &variants,
-                    );
-                }
-            }
-
-            ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
-                if polarity == ast::ImplPolarity::Negative {
-                    gate_feature_post!(&self, optin_builtin_traits,
-                                       i.span,
-                                       "negative trait bounds are not yet fully implemented; \
-                                        use marker types for now");
-                }
-
-                if let ast::Defaultness::Default = defaultness {
-                    gate_feature_post!(&self, specialization,
-                                       i.span,
-                                       "specialization is unstable");
-                }
-            }
-
-            ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
-                gate_feature_post!(&self, optin_builtin_traits,
-                                   i.span,
-                                   "auto traits are experimental and possibly buggy");
-            }
-
-            ast::ItemKind::TraitAlias(..) => {
-                gate_feature_post!(
-                    &self,
-                    trait_alias,
-                    i.span,
-                    "trait aliases are experimental"
-                );
-            }
-
-            ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => {
-                let msg = "`macro` is experimental";
-                gate_feature_post!(&self, decl_macro, i.span, msg);
-            }
-
-            ast::ItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    i.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
-
-            _ => {}
-        }
-
-        visit::walk_item(self, i);
-    }
-
-    fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
-        match i.node {
-            ast::ForeignItemKind::Fn(..) |
-            ast::ForeignItemKind::Static(..) => {
-                let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
-                let links_to_llvm = match link_name {
-                    Some(val) => val.as_str().starts_with("llvm."),
-                    _ => false
-                };
-                if links_to_llvm {
-                    gate_feature_post!(&self, link_llvm_intrinsics, i.span,
-                                       "linking to LLVM intrinsics is experimental");
-                }
-            }
-            ast::ForeignItemKind::Ty => {
-                    gate_feature_post!(&self, extern_types, i.span,
-                                       "extern types are experimental");
-            }
-            ast::ForeignItemKind::Macro(..) => {}
-        }
-
-        visit::walk_foreign_item(self, i)
-    }
-
-    fn visit_ty(&mut self, ty: &'a ast::Ty) {
-        match ty.node {
-            ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_abi(bare_fn_ty.abi, ty.span);
-            }
-            ast::TyKind::Never => {
-                gate_feature_post!(&self, never_type, ty.span,
-                                   "The `!` type is experimental");
-            }
-            _ => {}
-        }
-        visit::walk_ty(self, ty)
-    }
-
-    fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) {
-        if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty {
-            if let ast::TyKind::Never = output_ty.node {
-                // Do nothing.
-            } else {
-                self.visit_ty(output_ty)
-            }
-        }
-    }
-
-    fn visit_expr(&mut self, e: &'a ast::Expr) {
-        match e.node {
-            ast::ExprKind::Box(_) => {
-                gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX);
-            }
-            ast::ExprKind::Type(..) => {
-                // To avoid noise about type ascription in common syntax errors, only emit if it
-                // is the *only* error.
-                if self.context.parse_sess.span_diagnostic.err_count() == 0 {
-                    gate_feature_post!(&self, type_ascription, e.span,
-                                       "type ascription is experimental");
-                }
-            }
-            ast::ExprKind::TryBlock(_) => {
-                gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
-            }
-            ast::ExprKind::Block(_, opt_label) => {
-                if let Some(label) = opt_label {
-                    gate_feature_post!(&self, label_break_value, label.ident.span,
-                                    "labels on blocks are unstable");
-                }
-            }
-            ast::ExprKind::Async(..) => {
-                gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
-            }
-            ast::ExprKind::Await(_) => {
-                gate_feature_post!(&self, async_await, e.span, "async/await is unstable");
-            }
-            _ => {}
-        }
-        visit::walk_expr(self, e)
-    }
-
-    fn visit_arm(&mut self, arm: &'a ast::Arm) {
-        visit::walk_arm(self, arm)
-    }
-
-    fn visit_pat(&mut self, pattern: &'a ast::Pat) {
-        match &pattern.node {
-            PatKind::Slice(pats) => {
-                for pat in &*pats {
-                    let span = pat.span;
-                    let inner_pat = match &pat.node {
-                        PatKind::Ident(.., Some(pat)) => pat,
-                        _ => pat,
-                    };
-                    if inner_pat.is_rest() {
-                        gate_feature_post!(
-                            &self,
-                            slice_patterns,
-                            span,
-                            "subslice patterns are unstable"
-                        );
-                    }
-                }
-            }
-            PatKind::Box(..) => {
-                gate_feature_post!(&self, box_patterns,
-                                  pattern.span,
-                                  "box pattern syntax is experimental");
-            }
-            PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
-                gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
-                                   "exclusive range pattern syntax is experimental");
-            }
-            _ => {}
-        }
-        visit::walk_pat(self, pattern)
-    }
-
-    fn visit_fn(&mut self,
-                fn_kind: FnKind<'a>,
-                fn_decl: &'a ast::FnDecl,
-                span: Span,
-                _node_id: NodeId) {
-        if let Some(header) = fn_kind.header() {
-            // Check for const fn and async fn declarations.
-            if header.asyncness.node.is_async() {
-                gate_feature_post!(&self, async_await, span, "async fn is unstable");
-            }
-
-            // 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);
-        }
-
-        if fn_decl.c_variadic {
-            gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
-        }
-
-        visit::walk_fn(self, fn_kind, fn_decl, span)
-    }
-
-    fn visit_generic_param(&mut self, param: &'a GenericParam) {
-        match param.kind {
-            GenericParamKind::Const { .. } =>
-                gate_feature_post!(&self, const_generics, param.ident.span,
-                    "const generics are unstable"),
-            _ => {}
-        }
-        visit::walk_generic_param(self, param)
-    }
-
-    fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
-        match constraint.kind {
-            AssocTyConstraintKind::Bound { .. } =>
-                gate_feature_post!(&self, associated_type_bounds, constraint.span,
-                    "associated type bounds are unstable"),
-            _ => {}
-        }
-        visit::walk_assoc_ty_constraint(self, constraint)
-    }
-
-    fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
-        match ti.node {
-            ast::TraitItemKind::Method(ref sig, ref block) => {
-                if block.is_none() {
-                    self.check_abi(sig.header.abi, ti.span);
-                }
-                if sig.header.asyncness.node.is_async() {
-                    gate_feature_post!(&self, async_await, ti.span, "async fn is unstable");
-                }
-                if sig.decl.c_variadic {
-                    gate_feature_post!(&self, c_variadic, ti.span,
-                                       "C-variadic functions are unstable");
-                }
-                if sig.header.constness.node == ast::Constness::Const {
-                    gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
-                }
-            }
-            ast::TraitItemKind::Type(_, ref default) => {
-                // We use three if statements instead of something like match guards so that all
-                // of these errors can be emitted if all cases apply.
-                if default.is_some() {
-                    gate_feature_post!(&self, associated_type_defaults, ti.span,
-                                       "associated type defaults are unstable");
-                }
-                if !ti.generics.params.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ti.span,
-                                       "generic associated types are unstable");
-                }
-                if !ti.generics.where_clause.predicates.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ti.span,
-                                       "where clauses on associated types are unstable");
-                }
-            }
-            _ => {}
-        }
-        visit::walk_trait_item(self, ti)
-    }
-
-    fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) {
-        if ii.defaultness == ast::Defaultness::Default {
-            gate_feature_post!(&self, specialization,
-                              ii.span,
-                              "specialization is unstable");
-        }
-
-        match ii.node {
-            ast::ImplItemKind::Method(..) => {}
-            ast::ImplItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    ii.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
-            ast::ImplItemKind::TyAlias(_) => {
-                if !ii.generics.params.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ii.span,
-                                       "generic associated types are unstable");
-                }
-                if !ii.generics.where_clause.predicates.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ii.span,
-                                       "where clauses on associated types are unstable");
-                }
-            }
-            _ => {}
-        }
-        visit::walk_impl_item(self, ii)
-    }
-
-    fn visit_vis(&mut self, vis: &'a ast::Visibility) {
-        if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
-            gate_feature_post!(&self, crate_visibility_modifier, vis.span,
-                               "`crate` visibility modifier is experimental");
-        }
-        visit::walk_vis(self, vis)
-    }
-}
-
-pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
-                    crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
-    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
-        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
-        if let Some(reason) = reason {
-            err.span_note(span, reason);
-        } else {
-            err.span_label(span, "feature has been removed");
-        }
-        err.emit();
-    }
-
-    let mut features = Features::new();
-    let mut edition_enabled_features = FxHashMap::default();
-
-    for &edition in ALL_EDITIONS {
-        if edition <= crate_edition {
-            // The `crate_edition` implies its respective umbrella feature-gate
-            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
-            edition_enabled_features.insert(edition.feature_name(), edition);
-        }
-    }
-
-    for &(name, .., f_edition, set) in ACTIVE_FEATURES {
-        if let Some(f_edition) = f_edition {
-            if f_edition <= crate_edition {
-                set(&mut features, DUMMY_SP);
-                edition_enabled_features.insert(name, crate_edition);
-            }
-        }
-    }
-
-    // Process the edition umbrella feature-gates first, to ensure
-    // `edition_enabled_features` is completed before it's queried.
-    for attr in krate_attrs {
-        if !attr.check_name(sym::feature) {
-            continue
-        }
-
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
-        };
-
-        for mi in list {
-            if !mi.is_word() {
-                continue;
-            }
-
-            let name = mi.name_or_empty();
-
-            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
-                if *edition <= crate_edition {
-                    continue;
-                }
-
-                for &(name, .., f_edition, set) in ACTIVE_FEATURES {
-                    if let Some(f_edition) = f_edition {
-                        if f_edition <= *edition {
-                            // FIXME(Manishearth) there is currently no way to set
-                            // lib features by edition
-                            set(&mut features, DUMMY_SP);
-                            edition_enabled_features.insert(name, *edition);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    for attr in krate_attrs {
-        if !attr.check_name(sym::feature) {
-            continue
-        }
-
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
-        };
-
-        let bad_input = |span| {
-            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
-        };
-
-        for mi in list {
-            let name = match mi.ident() {
-                Some(ident) if mi.is_word() => ident.name,
-                Some(ident) => {
-                    bad_input(mi.span()).span_suggestion(
-                        mi.span(),
-                        "expected just one word",
-                        format!("{}", ident.name),
-                        Applicability::MaybeIncorrect,
-                    ).emit();
-                    continue
-                }
-                None => {
-                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
-                    continue
-                }
-            };
-
-            if let Some(edition) = edition_enabled_features.get(&name) {
-                struct_span_warn!(
-                    span_handler,
-                    mi.span(),
-                    E0705,
-                    "the feature `{}` is included in the Rust {} edition",
-                    name,
-                    edition,
-                ).emit();
-                continue;
-            }
-
-            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
-                // Handled in the separate loop above.
-                continue;
-            }
-
-            let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
-            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
-            if let Some((.., reason)) = removed.or(stable_removed) {
-                feature_removed(span_handler, mi.span(), *reason);
-                continue;
-            }
-
-            if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
-                let since = Some(Symbol::intern(since));
-                features.declared_lang_features.push((name, mi.span(), since));
-                continue;
-            }
-
-            if let Some(allowed) = allow_features.as_ref() {
-                if allowed.iter().find(|f| *f == name.as_str()).is_none() {
-                    span_err!(span_handler, mi.span(), E0725,
-                              "the feature `{}` is not in the list of allowed features",
-                              name);
-                    continue;
-                }
-            }
-
-            if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
-                set(&mut features, mi.span());
-                features.declared_lang_features.push((name, mi.span(), None));
-                continue;
-            }
-
-            features.declared_lib_features.push((name, mi.span()));
-        }
-    }
-
-    features
-}
-
-pub fn check_crate(krate: &ast::Crate,
-                   sess: &ParseSess,
-                   features: &Features,
-                   plugin_attributes: &[(Symbol, AttributeType)],
-                   unstable: UnstableFeatures) {
-    maybe_stage_features(&sess.span_diagnostic, krate, unstable);
-    let ctx = Context {
-        features,
-        parse_sess: sess,
-        plugin_attributes,
-    };
-
-    macro_rules! gate_all {
-        ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); }
-        }
-    }
-
-    gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable");
-    gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental");
-    gate_all!(async_closure_spans, async_closure, "async closures are unstable");
-    gate_all!(yield_spans, generators, "yield syntax is experimental");
-    gate_all!(or_pattern_spans, or_patterns, "or-patterns syntax is experimental");
-
-    let visitor = &mut PostExpansionVisitor {
-        context: &ctx,
-        builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
-    };
-    visit::walk_crate(visitor, krate);
-}
-
-#[derive(Clone, Copy, Hash)]
-pub enum UnstableFeatures {
-    /// Hard errors for unstable features are active, as on beta/stable channels.
-    Disallow,
-    /// Allow features to be activated, as on nightly.
-    Allow,
-    /// Errors are bypassed for bootstrapping. This is required any time
-    /// during the build that feature-related lints are set to warn or above
-    /// because the build turns on warnings-as-errors and uses lots of unstable
-    /// features. As a result, this is always required for building Rust itself.
-    Cheat
-}
-
-impl UnstableFeatures {
-    pub fn from_environment() -> UnstableFeatures {
-        // Whether this is a feature-staged build, i.e., on the beta or stable channel
-        let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
-        // Whether we should enable unstable features for bootstrapping
-        let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
-        match (disable_unstable_features, bootstrap) {
-            (_, true) => UnstableFeatures::Cheat,
-            (true, _) => UnstableFeatures::Disallow,
-            (false, _) => UnstableFeatures::Allow
-        }
-    }
-
-    pub fn is_nightly_build(&self) -> bool {
-        match *self {
-            UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
-            _ => false,
-        }
-    }
-}
-
-fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
-                        unstable: UnstableFeatures) {
-    let allow_features = match unstable {
-        UnstableFeatures::Allow => true,
-        UnstableFeatures::Disallow => false,
-        UnstableFeatures::Cheat => true
-    };
-    if !allow_features {
-        for attr in &krate.attrs {
-            if attr.check_name(sym::feature) {
-                let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
-                span_err!(span_handler, attr.span, E0554,
-                          "`#![feature]` may not be used on the {} release channel",
-                          release_channel);
-            }
-        }
-    }
-}
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
new file mode 100644
index 00000000000..32a0b76d5f0
--- /dev/null
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -0,0 +1,236 @@
+//! List of the accepted feature gates.
+
+use crate::symbol::{Symbol, sym};
+
+macro_rules! declare_features {
+    ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+        /// Those language feature has since been Accepted (it was once Active)
+        pub const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
+        ];
+    }
+}
+
+declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: for testing purposes
+    // -------------------------------------------------------------------------
+
+    // A temporary feature gate used to enable parser extensions needed
+    // to bootstrap fix for #5723.
+    (accepted, issue_5723_bootstrap, "1.0.0", None, None),
+    // These are used to test this portion of the compiler,
+    // they don't actually mean anything.
+    (accepted, test_accepted_feature, "1.0.0", None, None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: for testing purposes
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: accepted features
+    // -------------------------------------------------------------------------
+
+    // Allows using associated `type`s in `trait`s.
+    (accepted, associated_types, "1.0.0", None, None),
+    // Allows using assigning a default type to type parameters in algebraic data type definitions.
+    (accepted, default_type_params, "1.0.0", None, None),
+    // FIXME: explain `globs`.
+    (accepted, globs, "1.0.0", None, None),
+    // Allows `macro_rules!` items.
+    (accepted, macro_rules, "1.0.0", None, None),
+    // Allows use of `&foo[a..b]` as a slicing syntax.
+    (accepted, slicing_syntax, "1.0.0", None, None),
+    // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
+    (accepted, struct_variant, "1.0.0", None, None),
+    // Allows indexing tuples.
+    (accepted, tuple_indexing, "1.0.0", None, None),
+    // Allows the use of `if let` expressions.
+    (accepted, if_let, "1.0.0", None, None),
+    // Allows the use of `while let` expressions.
+    (accepted, while_let, "1.0.0", None, None),
+    // Allows using `#![no_std]`.
+    (accepted, no_std, "1.6.0", None, None),
+    // Allows overloading augmented assignment operations like `a += b`.
+    (accepted, augmented_assignments, "1.8.0", Some(28235), None),
+    // Allows empty structs and enum variants with braces.
+    (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
+    // Allows `#[deprecated]` attribute.
+    (accepted, deprecated, "1.9.0", Some(29935), None),
+    // Allows macros to appear in the type position.
+    (accepted, type_macros, "1.13.0", Some(27245), None),
+    // Allows use of the postfix `?` operator in expressions.
+    (accepted, question_mark, "1.13.0", Some(31436), None),
+    // Allows `..` in tuple (struct) patterns.
+    (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
+    // Allows some increased flexibility in the name resolution rules,
+    // especially around globs and shadowing (RFC 1560).
+    (accepted, item_like_imports, "1.15.0", Some(35120), None),
+    // Allows using `Self` and associated types in struct expressions and patterns.
+    (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
+    // Allows elision of `'static` lifetimes in `static`s and `const`s.
+    (accepted, static_in_const, "1.17.0", Some(35897), None),
+    // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
+    (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
+    // Allows the definition recursive static items.
+    (accepted, static_recursion, "1.17.0", Some(29719), None),
+    // Allows `pub(restricted)` visibilities (RFC 1422).
+    (accepted, pub_restricted, "1.18.0", Some(32409), None),
+    // Allows `#![windows_subsystem]`.
+    (accepted, windows_subsystem, "1.18.0", Some(37499), None),
+    // Allows `break {expr}` with a value inside `loop`s.
+    (accepted, loop_break_value, "1.19.0", Some(37339), None),
+    // Allows numeric fields in struct expressions and patterns.
+    (accepted, relaxed_adts, "1.19.0", Some(35626), None),
+    // Allows coercing non capturing closures to function pointers.
+    (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
+    // Allows attributes on struct literal fields.
+    (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
+    // Allows the definition of associated constants in `trait` or `impl` blocks.
+    (accepted, associated_consts, "1.20.0", Some(29646), None),
+    // Allows usage of the `compile_error!` macro.
+    (accepted, compile_error, "1.20.0", Some(40872), None),
+    // Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
+    (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
+    // Allows `Drop` types in constants (RFC 1440).
+    (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
+    // Allows the sysV64 ABI to be specified on all platforms
+    // instead of just the platforms on which it is the C ABI.
+    (accepted, abi_sysv64, "1.24.0", Some(36167), None),
+    // Allows `repr(align(16))` struct attribute (RFC 1358).
+    (accepted, repr_align, "1.25.0", Some(33626), None),
+    // Allows '|' at beginning of match arms (RFC 1925).
+    (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
+    // Allows nested groups in `use` items (RFC 2128).
+    (accepted, use_nested_groups, "1.25.0", Some(44494), None),
+    // Allows indexing into constant arrays.
+    (accepted, const_indexing, "1.26.0", Some(29947), None),
+    // Allows using `a..=b` and `..=b` as inclusive range syntaxes.
+    (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
+    // Allows `..=` in patterns (RFC 1192).
+    (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
+    // Allows `fn main()` with return types which implements `Termination` (RFC 1937).
+    (accepted, termination_trait, "1.26.0", Some(43301), None),
+    // Allows implementing `Clone` for closures where possible (RFC 2132).
+    (accepted, clone_closures, "1.26.0", Some(44490), None),
+    // Allows implementing `Copy` for closures where possible (RFC 2132).
+    (accepted, copy_closures, "1.26.0", Some(44490), None),
+    // Allows `impl Trait` in function arguments.
+    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
+    // Allows `impl Trait` in function return types.
+    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
+    // Allows using the `u128` and `i128` types.
+    (accepted, i128_type, "1.26.0", Some(35118), None),
+    // Allows default match binding modes (RFC 2005).
+    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
+    // Allows `'_` placeholder lifetimes.
+    (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
+    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
+    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
+    // Allows `cfg(target_feature = "...")`.
+    (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
+    // Allows `#[target_feature(...)]`.
+    (accepted, target_feature, "1.27.0", None, None),
+    // Allows using `dyn Trait` as a syntax for trait objects.
+    (accepted, dyn_trait, "1.27.0", Some(44662), None),
+    // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
+    (accepted, fn_must_use, "1.27.0", Some(43302), None),
+    // Allows use of the `:lifetime` macro fragment specifier.
+    (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
+    // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
+    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
+    // Allows the `#[global_allocator]` attribute.
+    (accepted, global_allocator, "1.28.0", Some(27389), None),
+    // Allows `#[repr(transparent)]` attribute on newtype structs.
+    (accepted, repr_transparent, "1.28.0", Some(43036), None),
+    // Allows procedural macros in `proc-macro` crates.
+    (accepted, proc_macro, "1.29.0", Some(38356), None),
+    // Allows `foo.rs` as an alternative to `foo/mod.rs`.
+    (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
+    // Allows use of the `:vis` macro fragment specifier
+    (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
+    // Allows importing and reexporting macros with `use`,
+    // enables macro modularization in general.
+    (accepted, use_extern_macros, "1.30.0", Some(35896), None),
+    // Allows keywords to be escaped for use as identifiers.
+    (accepted, raw_identifiers, "1.30.0", Some(48589), None),
+    // Allows attributes scoped to tools.
+    (accepted, tool_attributes, "1.30.0", Some(44690), None),
+    // Allows multi-segment paths in attributes and derives.
+    (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
+    // Allows all literals in attribute lists and values of key-value pairs.
+    (accepted, attr_literals, "1.30.0", Some(34981), None),
+    // Allows inferring outlives requirements (RFC 2093).
+    (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
+    // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
+    // This defines the behavior of panics.
+    (accepted, panic_handler, "1.30.0", Some(44489), None),
+    // Allows `#[used]` to preserve symbols (see llvm.used).
+    (accepted, used, "1.30.0", Some(40289), None),
+    // Allows `crate` in paths.
+    (accepted, crate_in_paths, "1.30.0", Some(45477), None),
+    // Allows resolving absolute paths as paths from other crates.
+    (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
+    // Allows access to crate names passed via `--extern` through prelude.
+    (accepted, extern_prelude, "1.30.0", Some(44660), None),
+    // Allows parentheses in patterns.
+    (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
+    // Allows the definition of `const fn` functions.
+    (accepted, min_const_fn, "1.31.0", Some(53555), None),
+    // Allows scoped lints.
+    (accepted, tool_lints, "1.31.0", Some(44690), None),
+    // Allows lifetime elision in `impl` headers. For example:
+    // + `impl<I:Iterator> Iterator for &mut Iterator`
+    // + `impl Debug for Foo<'_>`
+    (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
+    // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
+    (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
+    // Allows use of the `:literal` macro fragment specifier (RFC 1576).
+    (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
+    // Allows use of `?` as the Kleene "at most one" operator in macros.
+    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
+    // Allows `Self` struct constructor (RFC 2302).
+    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
+    // Allows `Self` in type definitions (RFC 2300).
+    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
+    // Allows `use x::y;` to search `x` in the current scope.
+    (accepted, uniform_paths, "1.32.0", Some(53130), None),
+    // Allows integer match exhaustiveness checking (RFC 2591).
+    (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
+    // Allows `use path as _;` and `extern crate c as _;`.
+    (accepted, underscore_imports, "1.33.0", Some(48216), None),
+    // Allows `#[repr(packed(N))]` attribute on structs.
+    (accepted, repr_packed, "1.33.0", Some(33158), None),
+    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
+    (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
+    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
+    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
+    // Allows let bindings, assignments and destructuring in `const` functions and constants.
+    // As long as control flow is not implemented in const eval, `&&` and `||` may not be used
+    // at the same time as let bindings.
+    (accepted, const_let, "1.33.0", Some(48821), None),
+    // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
+    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
+    // Allows top level or-patterns (`p | q`) in `if let` and `while let`.
+    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
+    // Allows `cfg(target_vendor = "...")`.
+    (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
+    // Allows `extern crate self as foo;`.
+    // This puts local crate root into extern prelude under name `foo`.
+    (accepted, extern_crate_self, "1.34.0", Some(56409), None),
+    // Allows arbitrary delimited token streams in non-macro attributes.
+    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
+    // Allows paths to enum variants on type aliases including `Self`.
+    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
+    // Allows using `#[repr(align(X))]` on enums with equivalent semantics
+    // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
+    (accepted, repr_align_enum, "1.37.0", Some(57996), None),
+    // Allows `const _: TYPE = VALUE`.
+    (accepted, underscore_const_names, "1.37.0", Some(54912), None),
+    // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
+    (accepted, async_await, "1.39.0", Some(50547), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: accepted features
+    // -------------------------------------------------------------------------
+);
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
new file mode 100644
index 00000000000..0bff4ed24a4
--- /dev/null
+++ b/src/libsyntax/feature_gate/active.rs
@@ -0,0 +1,522 @@
+//! List of the active feature gates.
+
+use crate::edition::Edition;
+use crate::symbol::{Symbol, sym};
+use syntax_pos::Span;
+
+macro_rules! set {
+    ($field: ident) => {{
+        fn f(features: &mut Features, _: Span) {
+            features.$field = true;
+        }
+        f as fn(&mut Features, Span)
+    }}
+}
+
+macro_rules! declare_features {
+    ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => {
+        /// Represents active features that are currently being implemented or
+        /// currently being considered for addition/removal.
+        pub const ACTIVE_FEATURES:
+            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
+            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
+
+        /// A set of features to be used by later passes.
+        #[derive(Clone)]
+        pub struct Features {
+            /// `#![feature]` attrs for language features, for error reporting
+            pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
+            /// `#![feature]` attrs for non-language (library) features
+            pub declared_lib_features: Vec<(Symbol, Span)>,
+            $(pub $feature: bool),+
+        }
+
+        impl Features {
+            pub fn new() -> Features {
+                Features {
+                    declared_lang_features: Vec::new(),
+                    declared_lib_features: Vec::new(),
+                    $($feature: false),+
+                }
+            }
+
+            pub fn walk_feature_fields<F>(&self, mut f: F)
+                where F: FnMut(&str, bool)
+            {
+                $(f(stringify!($feature), self.$feature);)+
+            }
+        }
+    };
+}
+
+// If you change this, please modify `src/doc/unstable-book` as well.
+//
+// Don't ever remove anything from this list; move them to `removed.rs`.
+//
+// The version numbers here correspond to the version in which the current status
+// was set. This is most important for knowing when a particular feature became
+// stable (active).
+//
+// Note that the features are grouped into internal/user-facing and then
+// sorted by version inside those groups. This is inforced with tidy.
+//
+// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
+// source, so take care when modifying it.
+
+declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: internal feature gates
+    // -------------------------------------------------------------------------
+
+    // no-tracking-issue-start
+
+    // Allows using compiler's own crates.
+    (active, rustc_private, "1.0.0", Some(27812), None),
+
+    // Allows using the `rust-intrinsic`'s "ABI".
+    (active, intrinsics, "1.0.0", None, None),
+
+    // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
+    (active, lang_items, "1.0.0", None, None),
+
+    // Allows using the `#[stable]` and `#[unstable]` attributes.
+    (active, staged_api, "1.0.0", None, None),
+
+    // Allows using `#[allow_internal_unstable]`. This is an
+    // attribute on `macro_rules!` and can't use the attribute handling
+    // below (it has to be checked before expansion possibly makes
+    // macros disappear).
+    (active, allow_internal_unstable, "1.0.0", None, None),
+
+    // Allows using `#[allow_internal_unsafe]`. This is an
+    // attribute on `macro_rules!` and can't use the attribute handling
+    // below (it has to be checked before expansion possibly makes
+    // macros disappear).
+    (active, allow_internal_unsafe, "1.0.0", None, None),
+
+    // Allows using the macros:
+    // + `__diagnostic_used`
+    // + `__register_diagnostic`
+    // +`__build_diagnostic_array`
+    (active, rustc_diagnostic_macros, "1.0.0", None, None),
+
+    // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
+    // lets a function to be `const` when opted into with `#![feature(foo)]`.
+    (active, rustc_const_unstable, "1.0.0", None, None),
+
+    // no-tracking-issue-end
+
+    // Allows using `#[link_name="llvm.*"]`.
+    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
+
+    // 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),
+
+    // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
+    (active, main, "1.0.0", Some(29634), None),
+
+    // Allows using `#[start]` on a function indicating that it is the program entrypoint.
+    (active, start, "1.0.0", Some(29633), None),
+
+    // Allows using the `#[fundamental]` attribute.
+    (active, fundamental, "1.0.0", Some(29635), None),
+
+    // Allows using the `rust-call` ABI.
+    (active, unboxed_closures, "1.0.0", Some(29625), None),
+
+    // Allows using the `#[linkage = ".."]` attribute.
+    (active, linkage, "1.0.0", Some(29603), None),
+
+    // Allows features specific to OIBIT (auto traits).
+    (active, optin_builtin_traits, "1.0.0", Some(13231), None),
+
+    // Allows using `box` in patterns (RFC 469).
+    (active, box_patterns, "1.0.0", Some(29641), None),
+
+    // no-tracking-issue-start
+
+    // Allows using `#[prelude_import]` on glob `use` items.
+    (active, prelude_import, "1.2.0", None, None),
+
+    // no-tracking-issue-end
+
+    // no-tracking-issue-start
+
+    // Allows using `#[omit_gdb_pretty_printer_section]`.
+    (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
+
+    // Allows using the `vectorcall` ABI.
+    (active, abi_vectorcall, "1.7.0", None, None),
+
+    // no-tracking-issue-end
+
+    // Allows using `#[structural_match]` which indicates that a type is structurally matchable.
+    (active, structural_match, "1.8.0", Some(31434), None),
+
+    // Allows using the `may_dangle` attribute (RFC 1327).
+    (active, dropck_eyepatch, "1.10.0", Some(34761), None),
+
+    // Allows using the `#![panic_runtime]` attribute.
+    (active, panic_runtime, "1.10.0", Some(32837), None),
+
+    // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
+    (active, needs_panic_runtime, "1.10.0", Some(32837), None),
+
+    // no-tracking-issue-start
+
+    // Allows identifying the `compiler_builtins` crate.
+    (active, compiler_builtins, "1.13.0", None, None),
+
+    // Allows using the `unadjusted` ABI; perma-unstable.
+    (active, abi_unadjusted, "1.16.0", None, None),
+
+    // Allows identifying crates that contain sanitizer runtimes.
+    (active, sanitizer_runtime, "1.17.0", None, None),
+
+    // Used to identify crates that contain the profiler runtime.
+    (active, profiler_runtime, "1.18.0", None, None),
+
+    // Allows using the `thiscall` ABI.
+    (active, abi_thiscall, "1.19.0", None, None),
+
+    // 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)),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: internal feature gates
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: actual feature gates (target features)
+    // -------------------------------------------------------------------------
+
+    // FIXME: Document these and merge with the list below.
+
+    // Unstable `#[target_feature]` directives.
+    (active, arm_target_feature, "1.27.0", Some(44839), None),
+    (active, aarch64_target_feature, "1.27.0", Some(44839), None),
+    (active, hexagon_target_feature, "1.27.0", Some(44839), None),
+    (active, powerpc_target_feature, "1.27.0", Some(44839), None),
+    (active, mips_target_feature, "1.27.0", Some(44839), None),
+    (active, avx512_target_feature, "1.27.0", Some(44839), None),
+    (active, mmx_target_feature, "1.27.0", Some(44839), None),
+    (active, sse4a_target_feature, "1.27.0", Some(44839), None),
+    (active, tbm_target_feature, "1.27.0", Some(44839), None),
+    (active, wasm_target_feature, "1.30.0", Some(44839), None),
+    (active, adx_target_feature, "1.32.0", Some(44839), None),
+    (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
+    (active, movbe_target_feature, "1.34.0", Some(44839), None),
+    (active, rtm_target_feature, "1.35.0", Some(44839), None),
+    (active, f16c_target_feature, "1.36.0", Some(44839), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: actual feature gates (target features)
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: actual feature gates
+    // -------------------------------------------------------------------------
+
+    // Allows using the `#[link_args]` attribute.
+    (active, link_args, "1.0.0", Some(29596), None),
+
+    // Allows defining identifiers beyond ASCII.
+    (active, non_ascii_idents, "1.0.0", Some(55467), None),
+
+    // Allows using `#[plugin_registrar]` on functions.
+    (active, plugin_registrar, "1.0.0", Some(29597), None),
+
+    // Allows using `#![plugin(myplugin)]`.
+    (active, plugin, "1.0.0", Some(29597), None),
+
+    // Allows using `#[thread_local]` on `static` items.
+    (active, thread_local, "1.0.0", Some(29594), None),
+
+    // 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),
+
+    // Allows using slice patterns.
+    (active, slice_patterns, "1.0.0", Some(62254), None),
+
+    // Allows the definition of `const` functions with some advanced features.
+    (active, const_fn, "1.2.0", Some(57563), None),
+
+    // Allows associated type defaults.
+    (active, associated_type_defaults, "1.2.0", Some(29661), None),
+
+    // Allows `#![no_core]`.
+    (active, no_core, "1.3.0", Some(29639), None),
+
+    // Allows default type parameters to influence type inference.
+    (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
+
+    // Allows `repr(simd)` and importing the various simd intrinsics.
+    (active, repr_simd, "1.4.0", Some(27731), None),
+
+    // Allows `extern "platform-intrinsic" { ... }`.
+    (active, platform_intrinsics, "1.4.0", Some(27731), None),
+
+    // Allows `#[unwind(..)]`.
+    //
+    // Permits specifying whether a function should permit unwinding or abort on unwind.
+    (active, unwind_attributes, "1.4.0", Some(58760), None),
+
+    // Allows `#[no_debug]`.
+    (active, no_debug, "1.5.0", Some(29721), None),
+
+    // Allows attributes on expressions and non-item statements.
+    (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
+
+    // Allows the use of type ascription in expressions.
+    (active, type_ascription, "1.6.0", Some(23416), None),
+
+    // Allows `cfg(target_thread_local)`.
+    (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
+
+    // Allows specialization of implementations (RFC 1210).
+    (active, specialization, "1.7.0", Some(31844), None),
+
+    // Allows using `#[naked]` on functions.
+    (active, naked_functions, "1.9.0", Some(32408), None),
+
+    // Allows `cfg(target_has_atomic = "...")`.
+    (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
+
+    // Allows `X..Y` patterns.
+    (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
+
+    // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
+    (active, never_type, "1.13.0", Some(35121), None),
+
+    // Allows exhaustive pattern matching on types that contain uninhabited types.
+    (active, exhaustive_patterns, "1.13.0", Some(51085), None),
+
+    // Allows untagged unions `union U { ... }`.
+    (active, untagged_unions, "1.13.0", Some(32836), None),
+
+    // Allows `#[link(..., cfg(..))]`.
+    (active, link_cfg, "1.14.0", Some(37406), None),
+
+    // Allows `extern "ptx-*" fn()`.
+    (active, abi_ptx, "1.15.0", Some(38788), None),
+
+    // Allows the `#[repr(i128)]` attribute for enums.
+    (active, repr128, "1.16.0", Some(35118), None),
+
+    // Allows `#[link(kind="static-nobundle"...)]`.
+    (active, static_nobundle, "1.16.0", Some(37403), None),
+
+    // Allows `extern "msp430-interrupt" fn()`.
+    (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
+
+    // Allows declarative macros 2.0 (`macro`).
+    (active, decl_macro, "1.17.0", Some(39412), None),
+
+    // Allows `extern "x86-interrupt" fn()`.
+    (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
+
+    // Allows overlapping impls of marker traits.
+    (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
+
+    // Allows a test to fail without failing the whole suite.
+    (active, allow_fail, "1.19.0", Some(46488), None),
+
+    // Allows unsized tuple coercion.
+    (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
+
+    // Allows defining generators.
+    (active, generators, "1.21.0", Some(43122), None),
+
+    // Allows `#[doc(cfg(...))]`.
+    (active, doc_cfg, "1.21.0", Some(43781), None),
+
+    // Allows `#[doc(masked)]`.
+    (active, doc_masked, "1.21.0", Some(44027), None),
+
+    // Allows `#[doc(spotlight)]`.
+    (active, doc_spotlight, "1.22.0", Some(45040), None),
+
+    // Allows `#[doc(include = "some-file")]`.
+    (active, external_doc, "1.22.0", Some(44732), None),
+
+    // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
+    (active, non_exhaustive, "1.22.0", Some(44109), None),
+
+    // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
+    (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
+
+    // Allows defining `extern type`s.
+    (active, extern_types, "1.23.0", Some(43467), None),
+
+    // Allows trait methods with arbitrary self types.
+    (active, arbitrary_self_types, "1.23.0", Some(44874), None),
+
+    // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
+    (active, in_band_lifetimes, "1.23.0", Some(44524), None),
+
+    // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
+    (active, generic_associated_types, "1.23.0", Some(44265), None),
+
+    // Allows defining `trait X = A + B;` alias items.
+    (active, trait_alias, "1.24.0", Some(41517), None),
+
+    // Allows infering `'static` outlives requirements (RFC 2093).
+    (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
+
+    // Allows macro invocations in `extern {}` blocks.
+    (active, macros_in_extern, "1.27.0", Some(49476), None),
+
+    // Allows accessing fields of unions inside `const` functions.
+    (active, const_fn_union, "1.27.0", Some(51909), None),
+
+    // Allows casting raw pointers to `usize` during const eval.
+    (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
+
+    // Allows dereferencing raw pointers during const eval.
+    (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
+
+    // Allows comparing raw pointers during const eval.
+    (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
+
+    // Allows `#[doc(alias = "...")]`.
+    (active, doc_alias, "1.27.0", Some(50146), None),
+
+    // Allows inconsistent bounds in where clauses.
+    (active, trivial_bounds, "1.28.0", Some(48214), None),
+
+    // Allows `'a: { break 'a; }`.
+    (active, label_break_value, "1.28.0", Some(48594), None),
+
+    // Allows using `#[doc(keyword = "...")]`.
+    (active, doc_keyword, "1.28.0", Some(51315), None),
+
+    // Allows reinterpretation of the bits of a value of one type as another type during const eval.
+    (active, const_transmute, "1.29.0", Some(53605), None),
+
+    // Allows using `try {...}` expressions.
+    (active, try_blocks, "1.29.0", Some(31436), None),
+
+    // Allows defining an `#[alloc_error_handler]`.
+    (active, alloc_error_handler, "1.29.0", Some(51540), None),
+
+    // Allows using the `amdgpu-kernel` ABI.
+    (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
+
+    // Allows panicking during const eval (producing compile-time errors).
+    (active, const_panic, "1.30.0", Some(51999), None),
+
+    // Allows `#[marker]` on certain traits allowing overlapping implementations.
+    (active, marker_trait_attr, "1.30.0", Some(29864), None),
+
+    // Allows macro invocations on modules expressions and statements and
+    // procedural macros to expand to non-items.
+    (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
+
+    // Allows unsized rvalues at arguments and parameters.
+    (active, unsized_locals, "1.30.0", Some(48055), None),
+
+    // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
+    (active, custom_test_frameworks, "1.30.0", Some(50297), None),
+
+    // Allows non-builtin attributes in inner attribute position.
+    (active, custom_inner_attributes, "1.30.0", Some(54726), None),
+
+    // Allows mixing bind-by-move in patterns and references to those identifiers in guards.
+    (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
+
+    // Allows `impl Trait` in bindings (`let`, `const`, `static`).
+    (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
+
+    // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
+    (active, lint_reasons, "1.31.0", Some(54503), None),
+
+    // 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),
+
+    // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
+    (active, const_generics, "1.34.0", Some(44580), None),
+
+    // Allows using `#[optimize(X)]`.
+    (active, optimize_attribute, "1.34.0", Some(54882), None),
+
+    // Allows using C-variadics.
+    (active, c_variadic, "1.34.0", Some(44930), None),
+
+    // Allows the user of associated type bounds.
+    (active, associated_type_bounds, "1.34.0", Some(52662), None),
+
+    // Attributes on formal function params.
+    (active, param_attrs, "1.36.0", Some(60406), None),
+
+    // Allows calling constructor functions in `const fn`.
+    (active, const_constructor, "1.37.0", Some(61456), None),
+
+    // Allows `if/while p && let q = r && ...` chains.
+    (active, let_chains, "1.37.0", Some(53667), None),
+
+    // Allows #[repr(transparent)] on enums (RFC 2645).
+    (active, transparent_enums, "1.37.0", Some(60405), None),
+
+    // Allows #[repr(transparent)] on unions (RFC 2645).
+    (active, transparent_unions, "1.37.0", Some(60405), None),
+
+    // Allows explicit discriminants on non-unit enum variants.
+    (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
+
+    // Allows `impl Trait` with multiple unrelated lifetimes.
+    (active, member_constraints, "1.37.0", Some(61977), None),
+
+    // Allows `async || body` closures.
+    (active, async_closure, "1.37.0", Some(62290), None),
+
+    // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
+    (active, cfg_doctest, "1.37.0", Some(62210), None),
+
+    // Allows `[x; N]` where `x` is a constant (RFC 2203).
+    (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
+
+    // Allows `impl Trait` to be used inside type aliases (RFC 2515).
+    (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
+
+    // Allows the use of or-patterns, e.g. `0 | 1`.
+    (active, or_patterns, "1.38.0", Some(54883), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: actual feature gates
+    // -------------------------------------------------------------------------
+);
+
+/// Some features are known to be incomplete and using them is likely to have
+/// unanticipated results, such as compiler crashes. We warn the user about these
+/// to alert them.
+pub const INCOMPLETE_FEATURES: &[Symbol] = &[
+    sym::impl_trait_in_bindings,
+    sym::generic_associated_types,
+    sym::const_generics,
+    sym::or_patterns,
+    sym::let_chains,
+];
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
new file mode 100644
index 00000000000..b934f2e7f64
--- /dev/null
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -0,0 +1,562 @@
+//! Built-in attributes and `cfg` flag gating.
+
+use AttributeType::*;
+use AttributeGate::*;
+
+use super::check::{emit_feature_err, GateIssue};
+use super::check::{Stability, EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABLE};
+use super::active::Features;
+
+use crate::ast;
+use crate::attr::AttributeTemplate;
+use crate::symbol::{Symbol, sym};
+use crate::parse::ParseSess;
+
+use syntax_pos::Span;
+use rustc_data_structures::fx::FxHashMap;
+use lazy_static::lazy_static;
+
+type GateFn = fn(&Features) -> bool;
+
+macro_rules! cfg_fn {
+    ($field: ident) => {
+        (|features| { features.$field }) as GateFn
+    }
+}
+
+/// `cfg(...)`'s that are feature gated.
+const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[
+    // (name in cfg, feature, function to check if the feature is enabled)
+    (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
+    (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
+    (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
+    (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
+];
+
+#[derive(Debug)]
+pub struct GatedCfg {
+    span: Span,
+    index: usize,
+}
+
+impl GatedCfg {
+    pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
+        GATED_CFGS.iter()
+                  .position(|info| cfg.check_name(info.0))
+                  .map(|idx| {
+                      GatedCfg {
+                          span: cfg.span,
+                          index: idx
+                      }
+                  })
+    }
+
+    pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
+        let (cfg, feature, has_feature) = GATED_CFGS[self.index];
+        if !has_feature(features) && !self.span.allows_unstable(feature) {
+            let explain = format!("`cfg({})` is experimental and subject to change", cfg);
+            emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain);
+        }
+    }
+}
+
+// If you change this, please modify `src/doc/unstable-book` as well. You must
+// move that documentation into the relevant place in the other docs, and
+// remove the chapter on the flag.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum AttributeType {
+    /// Normal, builtin attribute that is consumed
+    /// by the compiler before the unused_attribute check
+    Normal,
+
+    /// Builtin attribute that may not be consumed by the compiler
+    /// before the unused_attribute check. These attributes
+    /// will be ignored by the unused_attribute lint
+    Whitelisted,
+
+    /// Builtin attribute that is only allowed at the crate level
+    CrateLevel,
+}
+
+pub enum AttributeGate {
+    /// Is gated by a given feature gate, reason
+    /// and function to check if enabled
+    Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
+
+    /// Ungated attribute, can be used on all release channels
+    Ungated,
+}
+
+// fn() is not Debug
+impl std::fmt::Debug for AttributeGate {
+    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match *self {
+            Self::Gated(ref stab, name, expl, _) =>
+                write!(fmt, "Gated({:?}, {}, {})", stab, name, expl),
+            Self::Ungated => write!(fmt, "Ungated")
+        }
+    }
+}
+
+impl AttributeGate {
+    fn is_deprecated(&self) -> bool {
+        match *self {
+            Self::Gated(Stability::Deprecated(_, _), ..) => true,
+            _ => false,
+        }
+    }
+}
+
+/// A convenience macro for constructing attribute templates.
+/// E.g., `template!(Word, List: "description")` means that the attribute
+/// supports forms `#[attr]` and `#[attr(description)]`.
+macro_rules! template {
+    (Word) => { template!(@ true, None, None) };
+    (List: $descr: expr) => { template!(@ false, Some($descr), None) };
+    (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
+    (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
+    (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
+    (List: $descr1: expr, NameValueStr: $descr2: expr) => {
+        template!(@ false, Some($descr1), Some($descr2))
+    };
+    (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
+        template!(@ true, Some($descr1), Some($descr2))
+    };
+    (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
+        word: $word, list: $list, name_value_str: $name_value_str
+    } };
+}
+
+macro_rules! ungated {
+    ($attr:ident, $typ:expr, $tpl:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl, Ungated)
+    };
+}
+
+macro_rules! gated {
+    ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)))
+    };
+    ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)))
+    };
+}
+
+macro_rules! rustc_attr {
+    (TEST, $attr:ident, $typ:expr, $tpl:expr $(,)?) => {
+        rustc_attr!(
+            $attr, $typ, $tpl,
+            concat!("the `#[", stringify!($attr), "]` attribute is just used for rustc unit tests \
+                and will never be stable",
+            ),
+        )
+    };
+    ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl,
+         Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)))
+    };
+}
+
+macro_rules! experimental {
+    ($attr:ident) => {
+        concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature")
+    }
+}
+
+const IMPL_DETAIL: &str = "internal implementation detail";
+const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
+
+pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
+
+/// Attributes that have a special meaning to rustc or rustdoc
+pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
+    // ==========================================================================
+    // Stable attributes:
+    // ==========================================================================
+
+    // Condtional compilation:
+    ungated!(cfg, Normal, template!(List: "predicate")),
+    ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")),
+
+    // Testing:
+    ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")),
+    ungated!(
+        should_panic, Normal,
+        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
+    ),
+    // FIXME(Centril): This can be used on stable but shouldn't.
+    ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")),
+
+    // Macros:
+    ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
+    ungated!(automatically_derived, Normal, template!(Word)),
+    // FIXME(#14407)
+    ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
+    ungated!(macro_escape, Normal, template!(Word)), // Deprecated synonym for `macro_use`.
+    ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")),
+    ungated!(proc_macro, Normal, template!(Word)),
+    ungated!(
+        proc_macro_derive, Normal,
+        template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
+    ),
+    ungated!(proc_macro_attribute, Normal, template!(Word)),
+
+    // Lints:
+    ungated!(warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")),
+    // FIXME(#14407)
+    ungated!(
+        deprecated, Normal,
+        template!(
+            Word,
+            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
+            NameValueStr: "reason"
+        ),
+    ),
+
+    // Crate properties:
+    ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")),
+    ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")),
+    ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")),
+
+    // ABI, linking, symbols, and FFI
+    ungated!(
+        link, Whitelisted,
+        template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#),
+    ),
+    ungated!(link_name, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(no_link, Normal, template!(Word)),
+    ungated!(repr, Normal, template!(List: "C, packed, ...")),
+    ungated!(export_name, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(link_section, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(no_mangle, Whitelisted, template!(Word)),
+    ungated!(used, Whitelisted, template!(Word)),
+
+    // Limits:
+    ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")),
+    ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")),
+
+    // Entry point:
+    ungated!(main, Normal, template!(Word)),
+    ungated!(start, Normal, template!(Word)),
+    ungated!(no_start, CrateLevel, template!(Word)),
+    ungated!(no_main, CrateLevel, template!(Word)),
+
+    // Modules, prelude, and resolution:
+    ungated!(path, Normal, template!(NameValueStr: "file")),
+    ungated!(no_std, CrateLevel, template!(Word)),
+    ungated!(no_implicit_prelude, Normal, template!(Word)),
+
+    // Runtime
+    ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")),
+    ungated!(panic_handler, Normal, template!(Word)), // RFC 2070
+
+    // Code generation:
+    ungated!(inline, Whitelisted, template!(Word, List: "always|never")),
+    ungated!(cold, Whitelisted, template!(Word)),
+    ungated!(no_builtins, Whitelisted, template!(Word)),
+    ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)),
+
+    // FIXME: #14408 whitelist docs since rustdoc looks at them
+    ungated!(doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string")),
+
+    // ==========================================================================
+    // Unstable attributes:
+    // ==========================================================================
+
+    // Linking:
+    gated!(naked, Whitelisted, template!(Word), naked_functions, experimental!(naked)),
+    gated!(
+        link_args, Normal, template!(NameValueStr: "args"),
+        "the `link_args` attribute is experimental and not portable across platforms, \
+        it is recommended to use `#[link(name = \"foo\")] instead",
+    ),
+
+    // Plugins:
+    ungated!(plugin_registrar, Normal, template!(Word)),
+    gated!(
+        plugin, CrateLevel, template!(List: "name|name(args)"),
+        "compiler plugins are experimental and possibly buggy",
+    ),
+
+    // Testing:
+    gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)),
+    gated!(
+        test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks,
+        "custom test frameworks are an unstable feature",
+    ),
+
+    // RFC #2008
+    gated!(non_exhaustive, Whitelisted, template!(Word), experimental!(non_exhaustive)),
+    // RFC #1268
+    gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)),
+    gated!(
+        thread_local, Whitelisted, template!(Word),
+        "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
+    ),
+    gated!(no_core, CrateLevel, template!(Word), experimental!(no_core)),
+    // RFC 2412
+    gated!(
+        optimize, Whitelisted, template!(List: "size|speed"), optimize_attribute,
+        experimental!(optimize),
+    ),
+
+    gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
+
+    // ==========================================================================
+    // Internal attributes: Stability, deprecation, and unsafe:
+    // ==========================================================================
+
+    ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")),
+    // FIXME(#14407) -- only looked at on-demand so we can't
+    // guarantee they'll have already been checked.
+    ungated!(
+        rustc_deprecated, Whitelisted,
+        template!(List: r#"since = "version", reason = "...""#)
+    ),
+    // FIXME(#14407)
+    ungated!(stable, Whitelisted, template!(List: r#"feature = "name", since = "version""#)),
+    // FIXME(#14407)
+    ungated!(
+        unstable, Whitelisted,
+        template!(List: r#"feature = "name", reason = "...", issue = "N""#),
+    ),
+    gated!(
+        rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
+        "the `#[rustc_const_unstable]` attribute is an internal feature",
+    ),
+    gated!(
+        allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
+        EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
+    ),
+    gated!(allow_internal_unsafe, Normal, template!(Word), EXPLAIN_ALLOW_INTERNAL_UNSAFE),
+
+    // ==========================================================================
+    // Internal attributes: Type system related:
+    // ==========================================================================
+
+    gated!(fundamental, Whitelisted, template!(Word), experimental!(fundamental)),
+    gated!(
+        // RFC #1445.
+        structural_match, Whitelisted, template!(Word),
+        "the semantics of constant patterns is not yet settled",
+    ),
+    gated!(
+        may_dangle, Normal, template!(Word), dropck_eyepatch,
+        "`may_dangle` has unstable semantics and may be removed in the future",
+    ),
+
+    // ==========================================================================
+    // Internal attributes: Runtime related:
+    // ==========================================================================
+
+    rustc_attr!(rustc_allocator, Whitelisted, template!(Word), IMPL_DETAIL),
+    rustc_attr!(rustc_allocator_nounwind, Whitelisted, template!(Word), IMPL_DETAIL),
+    gated!(alloc_error_handler, Normal, template!(Word), experimental!(alloc_error_handler)),
+    gated!(
+        default_lib_allocator, Whitelisted, template!(Word), allocator_internals,
+        experimental!(default_lib_allocator),
+    ),
+    gated!(
+        needs_allocator, Normal, template!(Word), allocator_internals,
+        experimental!(needs_allocator),
+    ),
+    gated!(panic_runtime, Whitelisted, template!(Word), experimental!(panic_runtime)),
+    gated!(needs_panic_runtime, Whitelisted, template!(Word), experimental!(needs_panic_runtime)),
+    gated!(
+        unwind, Whitelisted, template!(List: "allowed|aborts"), unwind_attributes,
+        experimental!(unwind),
+    ),
+    gated!(
+        compiler_builtins, Whitelisted, template!(Word),
+        "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
+        which contains compiler-rt intrinsics and will never be stable",
+    ),
+    gated!(
+        sanitizer_runtime, Whitelisted, template!(Word),
+        "the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime \
+        of a sanitizer and will never be stable",
+    ),
+    gated!(
+        profiler_runtime, Whitelisted, template!(Word),
+        "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
+        which contains the profiler runtime and will never be stable",
+    ),
+
+    // ==========================================================================
+    // Internal attributes, Linkage:
+    // ==========================================================================
+
+    gated!(
+        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),
+
+    // ==========================================================================
+    // 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_macro_transparency, Whitelisted,
+        template!(NameValueStr: "transparent|semitransparent|opaque"),
+        "used internally for testing macro hygiene",
+    ),
+
+    // ==========================================================================
+    // Internal attributes, Diagnostics related:
+    // ==========================================================================
+
+    gated!(
+        rustc_on_unimplemented, Whitelisted,
+        template!(
+            List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
+            NameValueStr: "message"
+        ),
+        on_unimplemented,
+        experimental!(rustc_on_unimplemented),
+    ),
+    // Whitelists "identity-like" conversion methods to suggest on type mismatch.
+    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+
+    // ==========================================================================
+    // Internal attributes, Const related:
+    // ==========================================================================
+
+    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),
+
+    // ==========================================================================
+    // Internal attributes, Layout related:
+    // ==========================================================================
+
+    rustc_attr!(
+        rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
+        "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
+    ),
+    rustc_attr!(
+        rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
+        "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
+    ),
+    rustc_attr!(
+        rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
+        "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
+    ),
+
+    // ==========================================================================
+    // Internal attributes, Misc:
+    // ==========================================================================
+
+    gated!(
+        lang, Normal, template!(NameValueStr: "name"), lang_items,
+        "language items are subject to change",
+    ),
+    (
+        sym::no_debug, Whitelisted, template!(Word),
+        Gated(
+            Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
+            sym::no_debug,
+            "the `#[no_debug]` attribute was an experimental feature that has been \
+            deprecated due to lack of demand",
+            cfg_fn!(no_debug)
+        )
+    ),
+    gated!(
+        // Used in resolve:
+        prelude_import, Whitelisted, template!(Word),
+        "`#[prelude_import]` is for use by rustc only",
+    ),
+    gated!(
+        rustc_paren_sugar, Normal, template!(Word), unboxed_closures,
+        "unboxed_closures are still evolving",
+    ),
+    rustc_attr!(
+        rustc_inherit_overflow_checks, Whitelisted, template!(Word),
+        "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
+        overflow checking behavior of several libcore functions that are inlined \
+        across crates and will never be stable",
+    ),
+    rustc_attr!(
+        rustc_test_marker, Normal, template!(Word),
+        "the `#[rustc_test_marker]` attribute is used internally to track tests",
+    ),
+
+    // ==========================================================================
+    // Internal attributes, Testing:
+    // ==========================================================================
+
+    rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
+    rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
+    rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),
+    rustc_attr!(
+        TEST, rustc_dirty, Whitelisted,
+        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
+    ),
+    rustc_attr!(
+        TEST, rustc_clean, Whitelisted,
+        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
+    ),
+    rustc_attr!(
+        TEST, rustc_partition_reused, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...""#),
+    ),
+    rustc_attr!(
+        TEST, rustc_partition_codegened, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...""#),
+    ),
+    rustc_attr!(
+        TEST, rustc_expected_cgu_reuse, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...", kind = "...""#),
+    ),
+    rustc_attr!(TEST, rustc_synthetic, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_symbol_name, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_def_path, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_mir, Whitelisted, template!(List: "arg1, arg2, ...")),
+    rustc_attr!(TEST, rustc_dump_program_clauses, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_env_program_clauses, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_object_lifetime_default, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)),
+    gated!(
+        omit_gdb_pretty_printer_section, Whitelisted, template!(Word),
+        "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
+    ),
+];
+
+pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> {
+    BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect()
+}
+
+pub fn is_builtin_attr_name(name: ast::Name) -> bool {
+    BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
+}
+
+pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
+    attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).is_some()
+}
+
+lazy_static! {
+    pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = {
+        let mut map = FxHashMap::default();
+        for attr in BUILTIN_ATTRIBUTES.iter() {
+            if map.insert(attr.0, attr).is_some() {
+                panic!("duplicate builtin attribute `{}`", attr.0);
+            }
+        }
+        map
+    };
+}
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
new file mode 100644
index 00000000000..d82b287b6fb
--- /dev/null
+++ b/src/libsyntax/feature_gate/check.rs
@@ -0,0 +1,951 @@
+use super::active::{ACTIVE_FEATURES, Features};
+use super::accepted::ACCEPTED_FEATURES;
+use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
+use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
+
+use crate::ast::{
+    self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
+    PatKind, RangeEnd,
+};
+use crate::attr::{self, check_builtin_attribute};
+use crate::source_map::Spanned;
+use crate::edition::{ALL_EDITIONS, Edition};
+use crate::visit::{self, FnKind, Visitor};
+use crate::parse::{token, ParseSess};
+use crate::parse::parser::Parser;
+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;
+
+#[derive(Copy, Clone, Debug)]
+pub enum Stability {
+    Unstable,
+    // First argument is tracking issue link; second argument is an optional
+    // help message, which defaults to "remove this attribute"
+    Deprecated(&'static str, Option<&'static str>),
+}
+
+struct Context<'a> {
+    features: &'a Features,
+    parse_sess: &'a ParseSess,
+    plugin_attributes: &'a [(Symbol, AttributeType)],
+}
+
+macro_rules! gate_feature_fn {
+    ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
+        let (cx, has_feature, span,
+             name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
+        let has_feature: bool = has_feature(&$cx.features);
+        debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
+        if !has_feature && !span.allows_unstable($name) {
+            leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level)
+                .emit();
+        }
+    }}
+}
+
+macro_rules! gate_feature {
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
+        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
+                         sym::$feature, $explain, GateStrength::Hard)
+    };
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
+        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
+                         sym::$feature, $explain, $level)
+    };
+}
+
+impl<'a> Context<'a> {
+    fn check_attribute(
+        &self,
+        attr: &ast::Attribute,
+        attr_info: Option<&BuiltinAttribute>,
+        is_macro: bool
+    ) {
+        debug!("check_attribute(attr = {:?})", attr);
+        if let Some(&(name, ty, _template, ref gateage)) = attr_info {
+            if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage {
+                if !attr.span.allows_unstable(name) {
+                    gate_feature_fn!(
+                        self, has_feature, attr.span, name, desc, GateStrength::Hard
+                    );
+                }
+            } else if name == sym::doc {
+                if let Some(content) = attr.meta_item_list() {
+                    if content.iter().any(|c| c.check_name(sym::include)) {
+                        gate_feature!(self, external_doc, attr.span,
+                            "`#[doc(include = \"...\")]` is experimental"
+                        );
+                    }
+                }
+            }
+            debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
+            return;
+        } else {
+            for segment in &attr.path.segments {
+                if segment.ident.as_str().starts_with("rustc") {
+                    let msg = "attributes starting with `rustc` are \
+                               reserved for use by the `rustc` compiler";
+                    gate_feature!(self, rustc_attrs, segment.ident.span, msg);
+                }
+            }
+        }
+        for &(n, ty) in self.plugin_attributes {
+            if attr.path == n {
+                // Plugins can't gate attributes, so we don't check for it
+                // unlike the code above; we only use this loop to
+                // short-circuit to avoid the checks below.
+                debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty);
+                return;
+            }
+        }
+        if !is_macro && !attr::is_known(attr) {
+            // Only run the custom attribute lint during regular feature gate
+            // checking. Macro gating runs before the plugin attributes are
+            // registered, so we skip this in that case.
+            let msg = format!("the attribute `{}` is currently unknown to the compiler and \
+                               may have meaning added to it in the future", attr.path);
+            gate_feature!(self, custom_attribute, attr.span, &msg);
+        }
+    }
+}
+
+pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
+    let cx = Context { features, parse_sess, plugin_attributes: &[] };
+    cx.check_attribute(
+        attr,
+        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)),
+        true
+    );
+}
+
+fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
+    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
+        let issue = info.2;
+        // FIXME (#28244): enforce that active features have issue numbers
+        // assert!(issue.is_some())
+        issue
+    } else {
+        // search in Accepted, Removed, or Stable Removed features
+        let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
+            .find(|t| t.0 == feature);
+        match found {
+            Some(&(_, _, issue, _)) => issue,
+            None => panic!("Feature `{}` is not declared anywhere", feature),
+        }
+    }
+}
+
+pub enum GateIssue {
+    Language,
+    Library(Option<u32>)
+}
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum GateStrength {
+    /// A hard error. (Most feature gates should use this.)
+    Hard,
+    /// Only a warning. (Use this only as backwards-compatibility demands.)
+    Soft,
+}
+
+pub fn emit_feature_err(
+    sess: &ParseSess,
+    feature: Symbol,
+    span: Span,
+    issue: GateIssue,
+    explain: &str,
+) {
+    feature_err(sess, feature, span, issue, explain).emit();
+}
+
+pub fn feature_err<'a, S: Into<MultiSpan>>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: S,
+    issue: GateIssue,
+    explain: &str,
+) -> DiagnosticBuilder<'a> {
+    leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
+}
+
+fn leveled_feature_err<'a, S: Into<MultiSpan>>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: S,
+    issue: GateIssue,
+    explain: &str,
+    level: GateStrength,
+) -> DiagnosticBuilder<'a> {
+    let diag = &sess.span_diagnostic;
+
+    let issue = match issue {
+        GateIssue::Language => find_lang_feature_issue(feature),
+        GateIssue::Library(lib) => lib,
+    };
+
+    let mut err = match level {
+        GateStrength::Hard => {
+            diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658))
+        }
+        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,
+            ));
+        }
+    }
+
+    // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
+    if sess.unstable_features.is_nightly_build() {
+        err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
+    }
+
+    // If we're on stable and only emitting a "soft" warning, add a note to
+    // clarify that the feature isn't "on" (rather than being on but
+    // warning-worthy).
+    if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
+        err.help("a nightly build of the compiler is required to enable this feature");
+    }
+
+    err
+
+}
+
+const EXPLAIN_BOX_SYNTAX: &str =
+    "box expression syntax is experimental; you can call `Box::new` instead";
+
+pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
+    "attributes on expressions are experimental";
+
+pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
+    "allow_internal_unstable side-steps feature gating and stability checks";
+pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
+    "allow_internal_unsafe side-steps the unsafe_code lint";
+
+pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
+    "unsized tuple coercion is not stable enough for use and is subject to change";
+
+struct PostExpansionVisitor<'a> {
+    context: &'a Context<'a>,
+    builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
+}
+
+macro_rules! gate_feature_post {
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
+        let (cx, span) = ($cx, $span);
+        if !span.allows_unstable(sym::$feature) {
+            gate_feature!(cx.context, $feature, span, $explain)
+        }
+    }};
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
+        let (cx, span) = ($cx, $span);
+        if !span.allows_unstable(sym::$feature) {
+            gate_feature!(cx.context, $feature, span, $explain, $level)
+        }
+    }}
+}
+
+impl<'a> PostExpansionVisitor<'a> {
+    fn check_abi(&self, abi: Abi, span: Span) {
+        match abi {
+            Abi::RustIntrinsic => {
+                gate_feature_post!(&self, intrinsics, span,
+                                   "intrinsics are subject to change");
+            },
+            Abi::PlatformIntrinsic => {
+                gate_feature_post!(&self, platform_intrinsics, span,
+                                   "platform intrinsics are experimental and possibly buggy");
+            },
+            Abi::Vectorcall => {
+                gate_feature_post!(&self, abi_vectorcall, span,
+                                   "vectorcall is experimental and subject to change");
+            },
+            Abi::Thiscall => {
+                gate_feature_post!(&self, abi_thiscall, span,
+                                   "thiscall is experimental and subject to change");
+            },
+            Abi::RustCall => {
+                gate_feature_post!(&self, unboxed_closures, span,
+                                   "rust-call ABI is subject to change");
+            },
+            Abi::PtxKernel => {
+                gate_feature_post!(&self, abi_ptx, span,
+                                   "PTX ABIs are experimental and subject to change");
+            },
+            Abi::Unadjusted => {
+                gate_feature_post!(&self, abi_unadjusted, span,
+                                   "unadjusted ABI is an implementation detail and perma-unstable");
+            },
+            Abi::Msp430Interrupt => {
+                gate_feature_post!(&self, abi_msp430_interrupt, span,
+                                   "msp430-interrupt ABI is experimental and subject to change");
+            },
+            Abi::X86Interrupt => {
+                gate_feature_post!(&self, abi_x86_interrupt, span,
+                                   "x86-interrupt ABI is experimental and subject to change");
+            },
+            Abi::AmdGpuKernel => {
+                gate_feature_post!(&self, abi_amdgpu_kernel, span,
+                                   "amdgpu-kernel 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 => {}
+        }
+    }
+}
+
+impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
+    fn visit_attribute(&mut self, attr: &ast::Attribute) {
+        let attr_info = attr.ident().and_then(|ident| {
+            self.builtin_attributes.get(&ident.name).map(|a| *a)
+        });
+
+        // Check for gated attributes.
+        self.context.check_attribute(attr, attr_info, false);
+
+        if attr.check_name(sym::doc) {
+            if let Some(content) = attr.meta_item_list() {
+                if content.len() == 1 && content[0].check_name(sym::cfg) {
+                    gate_feature_post!(&self, doc_cfg, attr.span,
+                        "`#[doc(cfg(...))]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::masked)) {
+                    gate_feature_post!(&self, doc_masked, attr.span,
+                        "`#[doc(masked)]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
+                    gate_feature_post!(&self, doc_spotlight, attr.span,
+                        "`#[doc(spotlight)]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::alias)) {
+                    gate_feature_post!(&self, doc_alias, attr.span,
+                        "`#[doc(alias = \"...\")]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::keyword)) {
+                    gate_feature_post!(&self, doc_keyword, attr.span,
+                        "`#[doc(keyword = \"...\")]` is experimental"
+                    );
+                }
+            }
+        }
+
+        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.context.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.context.parse_sess).map_err(|mut err| err.emit()).ok();
+                }
+            }
+        }
+    }
+
+    fn visit_name(&mut self, sp: Span, name: ast::Name) {
+        if !name.as_str().is_ascii() {
+            gate_feature_post!(
+                &self,
+                non_ascii_idents,
+                self.context.parse_sess.source_map().def_span(sp),
+                "non-ascii idents are not fully supported"
+            );
+        }
+    }
+
+    fn visit_item(&mut self, i: &'a ast::Item) {
+        match i.node {
+            ast::ItemKind::ForeignMod(ref foreign_module) => {
+                self.check_abi(foreign_module.abi, i.span);
+            }
+
+            ast::ItemKind::Fn(..) => {
+                if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
+                    gate_feature_post!(&self, plugin_registrar, i.span,
+                                       "compiler plugins are experimental and possibly buggy");
+                }
+                if attr::contains_name(&i.attrs[..], sym::start) {
+                    gate_feature_post!(&self, start, i.span,
+                                      "a `#[start]` function is an experimental \
+                                       feature whose signature may change \
+                                       over time");
+                }
+                if attr::contains_name(&i.attrs[..], sym::main) {
+                    gate_feature_post!(&self, main, i.span,
+                                       "declaration of a non-standard `#[main]` \
+                                        function may change over time, for now \
+                                        a top-level `fn main()` is required");
+                }
+            }
+
+            ast::ItemKind::Struct(..) => {
+                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
+                    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+                        if item.check_name(sym::simd) {
+                            gate_feature_post!(&self, repr_simd, attr.span,
+                                               "SIMD types are experimental and possibly buggy");
+                        }
+                    }
+                }
+            }
+
+            ast::ItemKind::Enum(ast::EnumDef{ref variants, ..}, ..) => {
+                for variant in variants {
+                    match (&variant.data, &variant.disr_expr) {
+                        (ast::VariantData::Unit(..), _) => {},
+                        (_, Some(disr_expr)) =>
+                            gate_feature_post!(
+                                &self,
+                                arbitrary_enum_discriminant,
+                                disr_expr.value.span,
+                                "discriminants on non-unit variants are experimental"),
+                        _ => {},
+                    }
+                }
+
+                let has_feature = self.context.features.arbitrary_enum_discriminant;
+                if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
+                    Parser::maybe_report_invalid_custom_discriminants(
+                        self.context.parse_sess,
+                        &variants,
+                    );
+                }
+            }
+
+            ast::ItemKind::Impl(_, polarity, defaultness, ..) => {
+                if polarity == ast::ImplPolarity::Negative {
+                    gate_feature_post!(&self, optin_builtin_traits,
+                                       i.span,
+                                       "negative trait bounds are not yet fully implemented; \
+                                        use marker types for now");
+                }
+
+                if let ast::Defaultness::Default = defaultness {
+                    gate_feature_post!(&self, specialization,
+                                       i.span,
+                                       "specialization is unstable");
+                }
+            }
+
+            ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
+                gate_feature_post!(&self, optin_builtin_traits,
+                                   i.span,
+                                   "auto traits are experimental and possibly buggy");
+            }
+
+            ast::ItemKind::TraitAlias(..) => {
+                gate_feature_post!(
+                    &self,
+                    trait_alias,
+                    i.span,
+                    "trait aliases are experimental"
+                );
+            }
+
+            ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => {
+                let msg = "`macro` is experimental";
+                gate_feature_post!(&self, decl_macro, i.span, msg);
+            }
+
+            ast::ItemKind::OpaqueTy(..) => {
+                gate_feature_post!(
+                    &self,
+                    type_alias_impl_trait,
+                    i.span,
+                    "`impl Trait` in type aliases is unstable"
+                );
+            }
+
+            _ => {}
+        }
+
+        visit::walk_item(self, i);
+    }
+
+    fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
+        match i.node {
+            ast::ForeignItemKind::Fn(..) |
+            ast::ForeignItemKind::Static(..) => {
+                let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
+                let links_to_llvm = match link_name {
+                    Some(val) => val.as_str().starts_with("llvm."),
+                    _ => false
+                };
+                if links_to_llvm {
+                    gate_feature_post!(&self, link_llvm_intrinsics, i.span,
+                                       "linking to LLVM intrinsics is experimental");
+                }
+            }
+            ast::ForeignItemKind::Ty => {
+                    gate_feature_post!(&self, extern_types, i.span,
+                                       "extern types are experimental");
+            }
+            ast::ForeignItemKind::Macro(..) => {}
+        }
+
+        visit::walk_foreign_item(self, i)
+    }
+
+    fn visit_ty(&mut self, ty: &'a ast::Ty) {
+        match ty.node {
+            ast::TyKind::BareFn(ref bare_fn_ty) => {
+                self.check_abi(bare_fn_ty.abi, ty.span);
+            }
+            ast::TyKind::Never => {
+                gate_feature_post!(&self, never_type, ty.span,
+                                   "The `!` type is experimental");
+            }
+            _ => {}
+        }
+        visit::walk_ty(self, ty)
+    }
+
+    fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) {
+        if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty {
+            if let ast::TyKind::Never = output_ty.node {
+                // Do nothing.
+            } else {
+                self.visit_ty(output_ty)
+            }
+        }
+    }
+
+    fn visit_expr(&mut self, e: &'a ast::Expr) {
+        match e.node {
+            ast::ExprKind::Box(_) => {
+                gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX);
+            }
+            ast::ExprKind::Type(..) => {
+                // To avoid noise about type ascription in common syntax errors, only emit if it
+                // is the *only* error.
+                if self.context.parse_sess.span_diagnostic.err_count() == 0 {
+                    gate_feature_post!(&self, type_ascription, e.span,
+                                       "type ascription is experimental");
+                }
+            }
+            ast::ExprKind::TryBlock(_) => {
+                gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
+            }
+            ast::ExprKind::Block(_, opt_label) => {
+                if let Some(label) = opt_label {
+                    gate_feature_post!(&self, label_break_value, label.ident.span,
+                                    "labels on blocks are unstable");
+                }
+            }
+            _ => {}
+        }
+        visit::walk_expr(self, e)
+    }
+
+    fn visit_arm(&mut self, arm: &'a ast::Arm) {
+        visit::walk_arm(self, arm)
+    }
+
+    fn visit_pat(&mut self, pattern: &'a ast::Pat) {
+        match &pattern.node {
+            PatKind::Slice(pats) => {
+                for pat in &*pats {
+                    let span = pat.span;
+                    let inner_pat = match &pat.node {
+                        PatKind::Ident(.., Some(pat)) => pat,
+                        _ => pat,
+                    };
+                    if inner_pat.is_rest() {
+                        gate_feature_post!(
+                            &self,
+                            slice_patterns,
+                            span,
+                            "subslice patterns are unstable"
+                        );
+                    }
+                }
+            }
+            PatKind::Box(..) => {
+                gate_feature_post!(&self, box_patterns,
+                                  pattern.span,
+                                  "box pattern syntax is experimental");
+            }
+            PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
+                gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
+                                   "exclusive range pattern syntax is experimental");
+            }
+            _ => {}
+        }
+        visit::walk_pat(self, pattern)
+    }
+
+    fn visit_fn(&mut self,
+                fn_kind: FnKind<'a>,
+                fn_decl: &'a ast::FnDecl,
+                span: Span,
+                _node_id: NodeId) {
+        if let Some(header) = fn_kind.header() {
+            // 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);
+        }
+
+        if fn_decl.c_variadic {
+            gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
+        }
+
+        visit::walk_fn(self, fn_kind, fn_decl, span)
+    }
+
+    fn visit_generic_param(&mut self, param: &'a GenericParam) {
+        match param.kind {
+            GenericParamKind::Const { .. } =>
+                gate_feature_post!(&self, const_generics, param.ident.span,
+                    "const generics are unstable"),
+            _ => {}
+        }
+        visit::walk_generic_param(self, param)
+    }
+
+    fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
+        match constraint.kind {
+            AssocTyConstraintKind::Bound { .. } =>
+                gate_feature_post!(&self, associated_type_bounds, constraint.span,
+                    "associated type bounds are unstable"),
+            _ => {}
+        }
+        visit::walk_assoc_ty_constraint(self, constraint)
+    }
+
+    fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
+        match ti.node {
+            ast::TraitItemKind::Method(ref sig, ref block) => {
+                if block.is_none() {
+                    self.check_abi(sig.header.abi, ti.span);
+                }
+                if sig.decl.c_variadic {
+                    gate_feature_post!(&self, c_variadic, ti.span,
+                                       "C-variadic functions are unstable");
+                }
+                if sig.header.constness.node == ast::Constness::Const {
+                    gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
+                }
+            }
+            ast::TraitItemKind::Type(_, ref default) => {
+                // We use three if statements instead of something like match guards so that all
+                // of these errors can be emitted if all cases apply.
+                if default.is_some() {
+                    gate_feature_post!(&self, associated_type_defaults, ti.span,
+                                       "associated type defaults are unstable");
+                }
+                if !ti.generics.params.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ti.span,
+                                       "generic associated types are unstable");
+                }
+                if !ti.generics.where_clause.predicates.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ti.span,
+                                       "where clauses on associated types are unstable");
+                }
+            }
+            _ => {}
+        }
+        visit::walk_trait_item(self, ti)
+    }
+
+    fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) {
+        if ii.defaultness == ast::Defaultness::Default {
+            gate_feature_post!(&self, specialization,
+                              ii.span,
+                              "specialization is unstable");
+        }
+
+        match ii.node {
+            ast::ImplItemKind::Method(..) => {}
+            ast::ImplItemKind::OpaqueTy(..) => {
+                gate_feature_post!(
+                    &self,
+                    type_alias_impl_trait,
+                    ii.span,
+                    "`impl Trait` in type aliases is unstable"
+                );
+            }
+            ast::ImplItemKind::TyAlias(_) => {
+                if !ii.generics.params.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ii.span,
+                                       "generic associated types are unstable");
+                }
+                if !ii.generics.where_clause.predicates.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ii.span,
+                                       "where clauses on associated types are unstable");
+                }
+            }
+            _ => {}
+        }
+        visit::walk_impl_item(self, ii)
+    }
+
+    fn visit_vis(&mut self, vis: &'a ast::Visibility) {
+        if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
+            gate_feature_post!(&self, crate_visibility_modifier, vis.span,
+                               "`crate` visibility modifier is experimental");
+        }
+        visit::walk_vis(self, vis)
+    }
+}
+
+pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
+                    crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
+    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
+        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
+        if let Some(reason) = reason {
+            err.span_note(span, reason);
+        } else {
+            err.span_label(span, "feature has been removed");
+        }
+        err.emit();
+    }
+
+    let mut features = Features::new();
+    let mut edition_enabled_features = FxHashMap::default();
+
+    for &edition in ALL_EDITIONS {
+        if edition <= crate_edition {
+            // The `crate_edition` implies its respective umbrella feature-gate
+            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
+            edition_enabled_features.insert(edition.feature_name(), edition);
+        }
+    }
+
+    for &(name, .., f_edition, set) in ACTIVE_FEATURES {
+        if let Some(f_edition) = f_edition {
+            if f_edition <= crate_edition {
+                set(&mut features, DUMMY_SP);
+                edition_enabled_features.insert(name, crate_edition);
+            }
+        }
+    }
+
+    // Process the edition umbrella feature-gates first, to ensure
+    // `edition_enabled_features` is completed before it's queried.
+    for attr in krate_attrs {
+        if !attr.check_name(sym::feature) {
+            continue
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => continue,
+        };
+
+        for mi in list {
+            if !mi.is_word() {
+                continue;
+            }
+
+            let name = mi.name_or_empty();
+
+            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
+                if *edition <= crate_edition {
+                    continue;
+                }
+
+                for &(name, .., f_edition, set) in ACTIVE_FEATURES {
+                    if let Some(f_edition) = f_edition {
+                        if f_edition <= *edition {
+                            // FIXME(Manishearth) there is currently no way to set
+                            // lib features by edition
+                            set(&mut features, DUMMY_SP);
+                            edition_enabled_features.insert(name, *edition);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    for attr in krate_attrs {
+        if !attr.check_name(sym::feature) {
+            continue
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => continue,
+        };
+
+        let bad_input = |span| {
+            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
+        };
+
+        for mi in list {
+            let name = match mi.ident() {
+                Some(ident) if mi.is_word() => ident.name,
+                Some(ident) => {
+                    bad_input(mi.span()).span_suggestion(
+                        mi.span(),
+                        "expected just one word",
+                        format!("{}", ident.name),
+                        Applicability::MaybeIncorrect,
+                    ).emit();
+                    continue
+                }
+                None => {
+                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
+                    continue
+                }
+            };
+
+            if let Some(edition) = edition_enabled_features.get(&name) {
+                struct_span_warn!(
+                    span_handler,
+                    mi.span(),
+                    E0705,
+                    "the feature `{}` is included in the Rust {} edition",
+                    name,
+                    edition,
+                ).emit();
+                continue;
+            }
+
+            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
+                // Handled in the separate loop above.
+                continue;
+            }
+
+            let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
+            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
+            if let Some((.., reason)) = removed.or(stable_removed) {
+                feature_removed(span_handler, mi.span(), *reason);
+                continue;
+            }
+
+            if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
+                let since = Some(Symbol::intern(since));
+                features.declared_lang_features.push((name, mi.span(), since));
+                continue;
+            }
+
+            if let Some(allowed) = allow_features.as_ref() {
+                if allowed.iter().find(|f| *f == name.as_str()).is_none() {
+                    span_err!(span_handler, mi.span(), E0725,
+                              "the feature `{}` is not in the list of allowed features",
+                              name);
+                    continue;
+                }
+            }
+
+            if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
+                set(&mut features, mi.span());
+                features.declared_lang_features.push((name, mi.span(), None));
+                continue;
+            }
+
+            features.declared_lib_features.push((name, mi.span()));
+        }
+    }
+
+    features
+}
+
+pub fn check_crate(krate: &ast::Crate,
+                   sess: &ParseSess,
+                   features: &Features,
+                   plugin_attributes: &[(Symbol, AttributeType)],
+                   unstable: UnstableFeatures) {
+    maybe_stage_features(&sess.span_diagnostic, krate, unstable);
+    let ctx = Context {
+        features,
+        parse_sess: sess,
+        plugin_attributes,
+    };
+
+    macro_rules! gate_all {
+        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
+        ($spans:ident, $gate:ident, $msg:literal) => {
+            for span in &*sess.gated_spans.$spans.borrow() {
+                gate_feature!(&ctx, $gate, *span, $msg);
+            }
+        }
+    }
+
+    gate_all!(param_attrs, "attributes on function parameters are unstable");
+    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!(or_patterns, "or-patterns syntax is experimental");
+
+    let visitor = &mut PostExpansionVisitor {
+        context: &ctx,
+        builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
+    };
+    visit::walk_crate(visitor, krate);
+}
+
+#[derive(Clone, Copy, Hash)]
+pub enum UnstableFeatures {
+    /// Hard errors for unstable features are active, as on beta/stable channels.
+    Disallow,
+    /// Allow features to be activated, as on nightly.
+    Allow,
+    /// Errors are bypassed for bootstrapping. This is required any time
+    /// during the build that feature-related lints are set to warn or above
+    /// because the build turns on warnings-as-errors and uses lots of unstable
+    /// features. As a result, this is always required for building Rust itself.
+    Cheat
+}
+
+impl UnstableFeatures {
+    pub fn from_environment() -> UnstableFeatures {
+        // Whether this is a feature-staged build, i.e., on the beta or stable channel
+        let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
+        // Whether we should enable unstable features for bootstrapping
+        let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
+        match (disable_unstable_features, bootstrap) {
+            (_, true) => UnstableFeatures::Cheat,
+            (true, _) => UnstableFeatures::Disallow,
+            (false, _) => UnstableFeatures::Allow
+        }
+    }
+
+    pub fn is_nightly_build(&self) -> bool {
+        match *self {
+            UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
+            _ => false,
+        }
+    }
+}
+
+fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, unstable: UnstableFeatures) {
+    let allow_features = match unstable {
+        UnstableFeatures::Allow => true,
+        UnstableFeatures::Disallow => false,
+        UnstableFeatures::Cheat => true
+    };
+    if !allow_features {
+        for attr in &krate.attrs {
+            if attr.check_name(sym::feature) {
+                let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
+                span_err!(span_handler, attr.span, E0554,
+                          "`#![feature]` may not be used on the {} release channel",
+                          release_channel);
+            }
+        }
+    }
+}
diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs
new file mode 100644
index 00000000000..97793bca1f5
--- /dev/null
+++ b/src/libsyntax/feature_gate/mod.rs
@@ -0,0 +1,31 @@
+//! # Feature gating
+//!
+//! This module implements the gating necessary for preventing certain compiler
+//! features from being used by default. This module will crawl a pre-expanded
+//! AST to ensure that there are no features which are used that are not
+//! enabled.
+//!
+//! Features are enabled in programs via the crate-level attributes of
+//! `#![feature(...)]` with a comma-separated list of features.
+//!
+//! For the purpose of future feature-tracking, once code for detection of feature
+//! gate usage is added, *do not remove it again* even once the feature
+//! becomes stable.
+
+mod accepted;
+mod removed;
+mod active;
+mod builtin_attrs;
+mod check;
+
+pub use active::{Features, INCOMPLETE_FEATURES};
+pub use builtin_attrs::{
+    AttributeGate, AttributeType, GatedCfg,
+    BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
+    deprecated_attributes, is_builtin_attr,  is_builtin_attr_name,
+};
+pub use check::{
+    check_attribute, check_crate, get_features, feature_err, emit_feature_err,
+    Stability, GateIssue, UnstableFeatures,
+    EXPLAIN_STMT_ATTR_SYNTAX, EXPLAIN_UNSIZED_TUPLE_COERCION,
+};
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
new file mode 100644
index 00000000000..6ebfeb29f67
--- /dev/null
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -0,0 +1,82 @@
+//! List of the removed feature gates.
+
+use crate::symbol::{Symbol, sym};
+
+macro_rules! declare_features {
+    ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
+        /// Represents unstable features which have since been removed (it was once Active)
+        pub const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, $reason)),+
+        ];
+    };
+
+    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+        /// Represents stable features which have since been removed (it was once Accepted)
+        pub const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
+        ];
+    };
+}
+
+declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: removed features
+    // -------------------------------------------------------------------------
+
+    (removed, import_shadowing, "1.0.0", None, None, None),
+    (removed, managed_boxes, "1.0.0", None, None, None),
+    // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
+    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
+    (removed, reflect, "1.0.0", Some(27749), None, None),
+    // A way to temporarily opt out of opt in copy. This will *never* be accepted.
+    (removed, opt_out_copy, "1.0.0", None, None, None),
+    (removed, quad_precision_float, "1.0.0", None, None, None),
+    (removed, struct_inherit, "1.0.0", None, None, None),
+    (removed, test_removed_feature, "1.0.0", None, None, None),
+    (removed, visible_private_types, "1.0.0", None, None, None),
+    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
+    // Allows using items which are missing stability attributes
+    (removed, unmarked_api, "1.0.0", None, None, None),
+    (removed, allocator, "1.0.0", None, None, None),
+    (removed, simd, "1.0.0", Some(27731), None,
+     Some("removed in favor of `#[repr(simd)]`")),
+    (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
+     Some("merged into `#![feature(slice_patterns)]`")),
+    (removed, macro_reexport, "1.0.0", Some(29638), None,
+     Some("subsumed by `pub use`")),
+    (removed, pushpop_unsafe, "1.2.0", None, None, None),
+    (removed, needs_allocator, "1.4.0", Some(27389), None,
+     Some("subsumed by `#![feature(allocator_internals)]`")),
+    (removed, proc_macro_mod, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_expr, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_non_items, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_gen, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, panic_implementation, "1.28.0", Some(44489), None,
+     Some("subsumed by `#[panic_handler]`")),
+    // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
+    (removed, custom_derive, "1.32.0", Some(29644), None,
+     Some("subsumed by `#[proc_macro_derive]`")),
+    // Paths of the form: `extern::foo::bar`
+    (removed, extern_in_paths, "1.33.0", Some(55600), None,
+     Some("subsumed by `::foo::bar` paths")),
+    (removed, quote, "1.33.0", Some(29601), None, None),
+    // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
+    (removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
+    (removed, await_macro, "1.38.0", Some(50547), None,
+     Some("subsumed by `.await` syntax")),
+    // Allows defining `existential type`s.
+    (removed, existential_type, "1.38.0", Some(63063), None,
+     Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: removed features
+    // -------------------------------------------------------------------------
+);
+
+declare_features! (
+    (stable_removed, no_stack_check, "1.0.0", None, None),
+);
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 8ac48d8d74a..1741932c1b8 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -124,7 +124,6 @@ pub mod diagnostics {
     #[macro_use]
     pub mod macros;
     pub mod plugin;
-    pub mod metadata;
 }
 
 // N.B., this module needs to be declared first so diagnostics are
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index a42da112360..c703058e795 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -21,9 +21,8 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
 impl<'a> Parser<'a> {
     crate fn parse_arg_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let attrs = self.parse_outer_attributes()?;
-        attrs.iter().for_each(|a|
-            self.sess.param_attr_spans.borrow_mut().push(a.span)
-        );
+        self.sess.gated_spans.param_attrs.borrow_mut()
+            .extend(attrs.iter().map(|a| a.span));
         Ok(attrs)
     }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b1f3612a839..b1af4806e2d 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -39,6 +39,22 @@ crate mod unescape_error_reporting;
 
 pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 
+/// Collected spans during parsing for places where a certain feature was
+/// used and should be feature gated accordingly in `check_crate`.
+#[derive(Default)]
+pub struct GatedSpans {
+    /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`.
+    pub param_attrs: Lock<Vec<Span>>,
+    /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
+    pub let_chains: Lock<Vec<Span>>,
+    /// Spans collected for gating `async_closure`, e.g. `async || ..`.
+    pub async_closure: Lock<Vec<Span>>,
+    /// Spans collected for gating `yield e?` expressions (`generators` gate).
+    pub yields: Lock<Vec<Span>>,
+    /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
+    pub or_patterns: Lock<Vec<Span>>,
+}
+
 /// Info about a parsing session.
 pub struct ParseSess {
     pub span_diagnostic: Handler,
@@ -58,16 +74,8 @@ pub struct ParseSess {
     /// operation token that followed it, but that the parser cannot identify without further
     /// analysis.
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
-    pub param_attr_spans: Lock<Vec<Span>>,
-    // Places where `let` exprs were used and should be feature gated according to `let_chains`.
-    pub let_chains_spans: Lock<Vec<Span>>,
-    // Places where `async || ..` exprs were used and should be feature gated.
-    pub async_closure_spans: Lock<Vec<Span>>,
-    // Places where `yield e?` exprs were used and should be feature gated.
-    pub yield_spans: Lock<Vec<Span>>,
     pub injected_crate_name: Once<Symbol>,
-    // Places where or-patterns e.g. `Some(Foo | Bar)` were used and should be feature gated.
-    pub or_pattern_spans: Lock<Vec<Span>>,
+    pub gated_spans: GatedSpans,
 }
 
 impl ParseSess {
@@ -93,12 +101,8 @@ impl ParseSess {
             buffered_lints: Lock::new(vec![]),
             edition: ExpnId::root().expn_data().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
-            param_attr_spans: Lock::new(Vec::new()),
-            let_chains_spans: Lock::new(Vec::new()),
-            async_closure_spans: Lock::new(Vec::new()),
-            yield_spans: Lock::new(Vec::new()),
             injected_crate_name: Once::new(),
-            or_pattern_spans: Lock::new(Vec::new()),
+            gated_spans: GatedSpans::default(),
         }
     }
 
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index ccc6bd15067..5da9b75d53b 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -999,7 +999,7 @@ impl<'a> Parser<'a> {
                     }
 
                     let span = lo.to(hi);
-                    self.sess.yield_spans.borrow_mut().push(span);
+                    self.sess.gated_spans.yields.borrow_mut().push(span);
                 } else if self.eat_keyword(kw::Let) {
                     return self.parse_let_expr(attrs);
                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
@@ -1111,7 +1111,7 @@ impl<'a> Parser<'a> {
         };
         if asyncness.is_async() {
             // Feature gate `async ||` closures.
-            self.sess.async_closure_spans.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
         }
 
         let capture_clause = self.parse_capture_clause();
@@ -1234,7 +1234,7 @@ impl<'a> Parser<'a> {
 
         if let ExprKind::Let(..) = cond.node {
             // Remove the last feature gating of a `let` expression since it's stable.
-            let last = self.sess.let_chains_spans.borrow_mut().pop();
+            let last = self.sess.gated_spans.let_chains.borrow_mut().pop();
             debug_assert_eq!(cond.span, last.unwrap());
         }
 
@@ -1252,7 +1252,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.let_chains_spans.borrow_mut().push(span);
+        self.sess.gated_spans.let_chains.borrow_mut().push(span);
         Ok(self.mk_expr(span, ExprKind::Let(pats, expr), attrs))
     }
 
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 72819c99660..03d7e922123 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -825,6 +825,7 @@ impl<'a> Parser<'a> {
             self.is_keyword_ahead(1, &[
                 kw::Impl,
                 kw::Const,
+                kw::Async,
                 kw::Fn,
                 kw::Unsafe,
                 kw::Extern,
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index fd458aec743..8cfa6abbe62 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -123,7 +123,7 @@ impl<'a> Parser<'a> {
 
         let or_pattern_span = lo.to(self.prev_span);
 
-        self.sess.or_pattern_spans.borrow_mut().push(or_pattern_span);
+        self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
 
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
     }
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 09a1b93c7bb..0d9f3769ce9 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -19,7 +19,7 @@ use crate::parse::Directory;
 use crate::parse::token::{self, DelimToken, Token, TokenKind};
 use crate::print::pprust;
 
-use syntax_pos::{BytePos, ExpnId, Span, DUMMY_SP};
+use syntax_pos::{BytePos, Span, DUMMY_SP};
 #[cfg(target_arch = "x86_64")]
 use rustc_data_structures::static_assert_size;
 use rustc_data_structures::sync::Lrc;
@@ -547,11 +547,4 @@ impl DelimSpan {
     pub fn entire(self) -> Span {
         self.open.with_hi(self.close.hi())
     }
-
-    pub fn apply_mark(self, expn_id: ExpnId) -> Self {
-        DelimSpan {
-            open: self.open.apply_mark(expn_id),
-            close: self.close.apply_mark(expn_id),
-        }
-    }
 }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 644a44f1989..28f907441d8 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -63,7 +63,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
     MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprKind::InlineAsm(P(inline_asm)),
-        span: sp.with_ctxt(cx.backtrace()),
+        span: cx.with_legacy_ctxt(sp),
         attrs: ThinVec::new(),
     }))
 }
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index 6301283460a..84583d0e5ec 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -23,7 +23,7 @@ pub fn expand_assert<'cx>(
         }
     };
 
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
     let panic_call = Mac {
         path: Path::from_ident(Ident::new(sym::panic, sp)),
         tts: custom_message.unwrap_or_else(|| {
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 0e52c1af908..21cee8ae1cb 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -16,7 +16,7 @@ pub fn expand_cfg(
     sp: Span,
     tts: &[tokenstream::TokenTree],
 ) -> Box<dyn base::MacResult + 'static> {
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
 
     match parse_cfg(cx, sp, tts) {
         Ok(cfg) => {
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index 4cd17531a45..ffa5154ca0c 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -59,6 +59,6 @@ pub fn expand_syntax_ext(
     } else if has_errors {
         return DummyResult::any(sp);
     }
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
 }
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 8184fc44267..96677072d1b 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -39,7 +39,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
         }
     }
 
-    let ident = ast::Ident::new(Symbol::intern(&res_str), sp.apply_mark(cx.current_expansion.id));
+    let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_legacy_ctxt(sp));
 
     struct ConcatIdentsResult { ident: ast::Ident }
 
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index d030ea4a56e..4dd0ecfebef 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -112,7 +112,7 @@ fn cs_clone_shallow(name: &str,
                         ty: P<ast::Ty>, span: Span, helper_name: &str) {
         // Generate statement `let _: helper_name<ty>;`,
         // set the expn ID so we can use the unstable struct.
-        let span = span.with_ctxt(cx.backtrace());
+        let span = cx.with_def_site_ctxt(span);
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 54027c600b4..32ab47969ad 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -53,7 +53,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>,
                         ty: P<ast::Ty>, span: Span, helper_name: &str) {
         // Generate statement `let _: helper_name<ty>;`,
         // set the expn ID so we can use the unstable struct.
-        let span = span.with_ctxt(cx.backtrace());
+        let span = cx.with_def_site_ctxt(span);
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 44153541048..781645a574e 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -60,7 +60,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
     };
 
     // We want to make sure we have the ctxt set so that we can use unstable methods
-    let span = span.with_ctxt(cx.backtrace());
+    let span = cx.with_def_site_ctxt(span);
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
     let builder = Ident::from_str_and_span("debug_trait_builder", span);
     let builder_expr = cx.expr_ident(span, builder.clone());
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 7fcf036fc81..cb1c7b21fee 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -85,7 +85,7 @@ impl<'a> Path<'a> {
             PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
             PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
             PathKind::Std => {
-                let def_site = DUMMY_SP.apply_mark(cx.current_expansion.id);
+                let def_site = cx.with_def_site_ctxt(DUMMY_SP);
                 idents.insert(0, Ident::new(kw::DollarCrate, def_site));
                 cx.path_all(span, false, idents, params, Vec::new())
             }
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index da68eea0c50..60b6eba7a4b 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -48,6 +48,9 @@ impl MultiItemModifier for BuiltinDerive {
               meta_item: &MetaItem,
               item: Annotatable)
               -> Vec<Annotatable> {
+        // FIXME: Built-in derives often forget to give spans contexts,
+        // so we are doing it here in a centralized way.
+        let span = ecx.with_def_site_ctxt(span);
         let mut items = Vec::new();
         (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
         items
@@ -60,7 +63,7 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
                   intrinsic: &str,
                   args: Vec<P<ast::Expr>>)
                   -> P<ast::Expr> {
-    let span = span.with_ctxt(cx.backtrace());
+    let span = cx.with_def_site_ctxt(span);
     let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]);
     let call = cx.expr_call_global(span, path, args);
 
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 9834130fa23..6343d218de8 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -20,7 +20,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
         Some(v) => v,
     };
 
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
             let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 83764205a19..47394c02b41 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -12,7 +12,7 @@ use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
 use syntax::tokenstream;
-use syntax_pos::{MultiSpan, Span, DUMMY_SP};
+use syntax_pos::{MultiSpan, Span};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use std::borrow::Cow;
@@ -666,8 +666,7 @@ impl<'a, 'b> Context<'a, 'b> {
         // passed to this function.
         for (i, e) in self.args.into_iter().enumerate() {
             let name = names_pos[i];
-            let span =
-                DUMMY_SP.with_ctxt(e.span.ctxt().apply_mark(self.ecx.current_expansion.id));
+            let span = self.ecx.with_def_site_ctxt(e.span);
             pats.push(self.ecx.pat_ident(span, name));
             for ref arg_ty in self.arg_unique_types[i].iter() {
                 locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
@@ -745,7 +744,7 @@ impl<'a, 'b> Context<'a, 'b> {
         ty: &ArgumentType,
         arg: ast::Ident,
     ) -> P<ast::Expr> {
-        sp = sp.apply_mark(ecx.current_expansion.id);
+        sp = ecx.with_def_site_ctxt(sp);
         let arg = ecx.expr_ident(sp, arg);
         let trait_ = match *ty {
             Placeholder(ref tyname) => {
@@ -798,7 +797,7 @@ fn expand_format_args_impl<'cx>(
     tts: &[tokenstream::TokenTree],
     nl: bool,
 ) -> Box<dyn base::MacResult + 'cx> {
-    sp = sp.apply_mark(ecx.current_expansion.id);
+    sp = ecx.with_def_site_ctxt(sp);
     match parse_args(ecx, sp, tts) {
         Ok((efmt, args, names)) => {
             MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl))
@@ -842,7 +841,7 @@ pub fn expand_preparsed_format_args(
     let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
 
     let mut macsp = ecx.call_site();
-    macsp = macsp.with_ctxt(ecx.backtrace());
+    macsp = ecx.with_def_site_ctxt(macsp);
 
     let msg = "format argument must be a string literal";
     let fmt_sp = efmt.span;
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index d2121abe3b4..97b8087ad15 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -3,7 +3,6 @@ use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident};
 use syntax::attr::check_builtin_macro_attribute;
 use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
 use syntax::ext::base::{Annotatable, ExtCtxt};
-use syntax::ext::hygiene::SyntaxContext;
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
@@ -29,7 +28,7 @@ pub fn expand(
     };
 
     // Generate a bunch of new items using the AllocFnFactory
-    let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
+    let span = ecx.with_legacy_ctxt(item.span);
     let f = AllocFnFactory {
         span,
         kind: AllocatorKind::Global,
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 73ebeaec454..a8b61593db7 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 id: ast::DUMMY_NODE_ID,
                 node: ast::ItemKind::GlobalAsm(P(global_asm)),
                 vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                span: sp.with_ctxt(cx.backtrace()),
+                span: cx.with_legacy_ctxt(sp),
                 tokens: None,
             })])
         }
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 08582e714cc..5fd87d3a0e5 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -4,7 +4,6 @@
 use syntax::ast;
 use syntax::attr::{self, check_builtin_macro_attribute};
 use syntax::ext::base::*;
-use syntax::ext::hygiene::SyntaxContext;
 use syntax::print::pprust;
 use syntax::source_map::respan;
 use syntax::symbol::{Symbol, sym};
@@ -29,7 +28,7 @@ pub fn expand_test_case(
 
     if !ecx.ecfg.should_test { return vec![]; }
 
-    let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
+    let sp = ecx.with_legacy_ctxt(attr_sp);
     let mut item = anno_item.expect_item();
     item = item.map(|mut item| {
         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
@@ -93,8 +92,7 @@ pub fn expand_test_or_bench(
         return vec![Annotatable::Item(item)];
     }
 
-    let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id);
-    let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt));
+    let (sp, attr_sp) = (cx.with_legacy_ctxt(item.span), cx.with_legacy_ctxt(attr_sp));
 
     // Gensym "test" so we can extern crate without conflicting with any local names
     let test_id = cx.ident_of("test").gensym();
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index ebfb0764fa2..733f6f04490 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -119,18 +119,6 @@ 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)))
     }
-
-    // Used for enabling some compatibility fallback in resolve.
-    #[inline]
-    pub fn looks_like_proc_macro_derive(self) -> bool {
-        HygieneData::with(|data| {
-            let expn_data = data.expn_data(self);
-            if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind {
-                return expn_data.default_transparency == Transparency::Opaque;
-            }
-            false
-        })
-    }
 }
 
 #[derive(Debug)]
@@ -195,24 +183,25 @@ impl HygieneData {
         self.syntax_context_data[ctxt.0 as usize].outer_expn
     }
 
-    fn outer_transparency(&self, ctxt: SyntaxContext) -> Transparency {
-        self.syntax_context_data[ctxt.0 as usize].outer_transparency
+    fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
+        let data = &self.syntax_context_data[ctxt.0 as usize];
+        (data.outer_expn, data.outer_transparency)
     }
 
     fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
         self.syntax_context_data[ctxt.0 as usize].parent
     }
 
-    fn remove_mark(&self, ctxt: &mut SyntaxContext) -> ExpnId {
-        let outer_expn = self.outer_expn(*ctxt);
+    fn remove_mark(&self, ctxt: &mut SyntaxContext) -> (ExpnId, Transparency) {
+        let outer_mark = self.outer_mark(*ctxt);
         *ctxt = self.parent_ctxt(*ctxt);
-        outer_expn
+        outer_mark
     }
 
     fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
         let mut marks = Vec::new();
         while ctxt != SyntaxContext::root() {
-            marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt)));
+            marks.push(self.outer_mark(ctxt));
             ctxt = self.parent_ctxt(ctxt);
         }
         marks.reverse();
@@ -229,20 +218,14 @@ impl HygieneData {
     fn adjust(&self, ctxt: &mut SyntaxContext, expn_id: ExpnId) -> Option<ExpnId> {
         let mut scope = None;
         while !self.is_descendant_of(expn_id, self.outer_expn(*ctxt)) {
-            scope = Some(self.remove_mark(ctxt));
+            scope = Some(self.remove_mark(ctxt).0);
         }
         scope
     }
 
-    fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
-        assert_ne!(expn_id, ExpnId::root());
-        self.apply_mark_with_transparency(
-            ctxt, expn_id, self.expn_data(expn_id).default_transparency
-        )
-    }
-
-    fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId,
-                                    transparency: Transparency) -> SyntaxContext {
+    fn apply_mark(
+        &mut self, ctxt: SyntaxContext, expn_id: ExpnId, transparency: Transparency
+    ) -> SyntaxContext {
         assert_ne!(expn_id, ExpnId::root());
         if transparency == Transparency::Opaque {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
@@ -376,15 +359,9 @@ impl SyntaxContext {
         SyntaxContext(raw)
     }
 
-    /// Extend a syntax context with a given expansion and default transparency for that expansion.
-    pub fn apply_mark(self, expn_id: ExpnId) -> SyntaxContext {
-        HygieneData::with(|data| data.apply_mark(self, expn_id))
-    }
-
     /// Extend a syntax context with a given expansion and transparency.
-    pub fn apply_mark_with_transparency(self, expn_id: ExpnId, transparency: Transparency)
-                                        -> SyntaxContext {
-        HygieneData::with(|data| data.apply_mark_with_transparency(self, expn_id, transparency))
+    pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
+        HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
     }
 
     /// Pulls a single mark off of the syntax context. This effectively moves the
@@ -404,7 +381,7 @@ impl SyntaxContext {
     /// invocation of f that created g1.
     /// Returns the mark that was removed.
     pub fn remove_mark(&mut self) -> ExpnId {
-        HygieneData::with(|data| data.remove_mark(self))
+        HygieneData::with(|data| data.remove_mark(self).0)
     }
 
     pub fn marks(self) -> Vec<(ExpnId, Transparency)> {
@@ -477,8 +454,8 @@ impl SyntaxContext {
             let mut scope = None;
             let mut glob_ctxt = data.modern(glob_span.ctxt());
             while !data.is_descendant_of(expn_id, data.outer_expn(glob_ctxt)) {
-                scope = Some(data.remove_mark(&mut glob_ctxt));
-                if data.remove_mark(self) != scope.unwrap() {
+                scope = Some(data.remove_mark(&mut glob_ctxt).0);
+                if data.remove_mark(self).0 != scope.unwrap() {
                     return None;
                 }
             }
@@ -509,9 +486,9 @@ impl SyntaxContext {
                 marks.push(data.remove_mark(&mut glob_ctxt));
             }
 
-            let scope = marks.last().cloned();
-            while let Some(mark) = marks.pop() {
-                *self = data.apply_mark(*self, mark);
+            let scope = marks.last().map(|mark| mark.0);
+            while let Some((expn_id, transparency)) = marks.pop() {
+                *self = data.apply_mark(*self, expn_id, transparency);
             }
             Some(scope)
         })
@@ -547,13 +524,11 @@ impl SyntaxContext {
         HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
     }
 
-    /// `ctxt.outer_expn_with_data()` is equivalent to but faster than
-    /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`.
     #[inline]
-    pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) {
+    pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
         HygieneData::with(|data| {
-            let outer = data.outer_expn(self);
-            (outer, data.expn_data(outer).clone())
+            let (expn_id, transparency) = data.outer_mark(self);
+            (expn_id, transparency, data.expn_data(expn_id).clone())
         })
     }
 
@@ -575,9 +550,15 @@ impl Span {
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
     pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
+        self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
+    }
+
+    pub fn fresh_expansion_with_transparency(
+        self, expn_data: ExpnData, transparency: Transparency
+    ) -> Span {
         HygieneData::with(|data| {
             let expn_id = data.fresh_expn(Some(expn_data));
-            self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
+            self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id, transparency))
         })
     }
 }
@@ -609,8 +590,6 @@ pub struct ExpnData {
     /// The span of the macro definition (possibly dummy).
     /// This span serves only informational purpose and is not used for resolution.
     pub def_site: Span,
-    /// Transparency used by `apply_mark` for the expansion with this expansion data by default.
-    pub default_transparency: Transparency,
     /// List of #[unstable]/feature-gated features that the macro is allowed to use
     /// internally without forcing the whole crate to opt-in
     /// to them.
@@ -633,7 +612,6 @@ impl ExpnData {
             parent: ExpnId::root(),
             call_site,
             def_site: DUMMY_SP,
-            default_transparency: Transparency::SemiTransparent,
             allow_internal_unstable: None,
             allow_internal_unsafe: false,
             local_inner_macros: false,
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index a17cd7625fb..3d8bfc77a89 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -22,6 +22,7 @@ pub mod edition;
 use edition::Edition;
 pub mod hygiene;
 pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind};
+use hygiene::Transparency;
 
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -512,10 +513,17 @@ impl Span {
                   span.ctxt)
     }
 
+    /// Produces a span with the same location as `self` and context produced by a macro with the
+    /// given ID and transparency, assuming that macro was defined directly and not produced by
+    /// some other macro (which is the case for built-in and procedural macros).
+    pub fn with_ctxt_from_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
+        self.with_ctxt(SyntaxContext::root().apply_mark(expn_id, transparency))
+    }
+
     #[inline]
-    pub fn apply_mark(self, mark: ExpnId) -> Span {
+    pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
         let span = self.data();
-        span.with_ctxt(span.ctxt.apply_mark(mark))
+        span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency))
     }
 
     #[inline]
diff --git a/src/libterm/Cargo.toml b/src/libterm/Cargo.toml
index 4eba9a9d79c..2931e0bda95 100644
--- a/src/libterm/Cargo.toml
+++ b/src/libterm/Cargo.toml
@@ -5,6 +5,8 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "term"
 path = "lib.rs"
-crate-type = ["dylib", "rlib"]
+
+[dependencies]
+core = { path = "../libcore" }
+std = { path = "../libstd" }
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index a72e4c70502..170fbb984cf 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -10,8 +10,22 @@ path = "lib.rs"
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-getopts = "0.2.19"
+getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
 term = { path = "../libterm" }
+std = { path = "../libstd" }
+core = { path = "../libcore" }
+libc = { version = "0.2", default-features = false }
+panic_unwind = { path = "../libpanic_unwind" }
+panic_abort = { path = "../libpanic_abort" }
 
 # not actually used but needed to always have proc_macro in the sysroot
 proc_macro = { path = "../libproc_macro" }
+
+# Forward features to the `std` crate as necessary
+[features]
+backtrace = ["std/backtrace"]
+compiler-builtins-c = ["std/compiler-builtins-c"]
+llvm-libunwind = ["std/llvm-libunwind"]
+panic-unwind = ["std/panic_unwind"]
+panic_immediate_abort = ["std/panic_immediate_abort"]
+profiler = ["std/profiler"]
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index ef66c4df99d..5e0f19fe553 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -965,12 +965,11 @@ fn use_color(opts: &TestOpts) -> bool {
 
 #[cfg(any(
     target_os = "cloudabi",
-    target_os = "redox",
     all(target_arch = "wasm32", not(target_os = "emscripten")),
     all(target_vendor = "fortanix", target_env = "sgx")
 ))]
 fn stdout_isatty() -> bool {
-    // FIXME: Implement isatty on Redox and SGX
+    // FIXME: Implement isatty on SGX
     false
 }
 #[cfg(unix)]
@@ -1193,15 +1192,15 @@ fn get_concurrency() -> usize {
         }
     }
 
-    #[cfg(target_os = "redox")]
+    #[cfg(target_os = "vxworks")]
     fn num_cpus() -> usize {
-        // FIXME: Implement num_cpus on Redox
+        // FIXME: Implement num_cpus on vxWorks
         1
     }
 
-    #[cfg(target_os = "vxworks")]
+    #[cfg(target_os = "redox")]
     fn num_cpus() -> usize {
-        // FIXME: Implement num_cpus on vxWorks
+        // FIXME: Implement num_cpus on Redox
         1
     }
 
@@ -1221,7 +1220,7 @@ fn get_concurrency() -> usize {
         target_os = "ios",
         target_os = "linux",
         target_os = "macos",
-        target_os = "solaris"
+        target_os = "solaris",
     ))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
diff --git a/src/test/codegen/integer-cmp.rs b/src/test/codegen/integer-cmp.rs
new file mode 100644
index 00000000000..1373b12e372
--- /dev/null
+++ b/src/test/codegen/integer-cmp.rs
@@ -0,0 +1,28 @@
+// This is test for more optimal Ord implementation for integers.
+// See <https://github.com/rust-lang/rust/issues/63758> for more info.
+
+// compile-flags: -C opt-level=3
+
+#![crate_type = "lib"]
+
+use std::cmp::Ordering;
+
+// CHECK-LABEL: @cmp_signed
+#[no_mangle]
+pub fn cmp_signed(a: i64, b: i64) -> Ordering {
+// CHECK: icmp slt
+// CHECK: icmp sgt
+// CHECK: zext i1
+// CHECK: select i1
+    a.cmp(&b)
+}
+
+// CHECK-LABEL: @cmp_unsigned
+#[no_mangle]
+pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
+// CHECK: icmp ult
+// CHECK: icmp ugt
+// CHECK: zext i1
+// CHECK: select i1
+    a.cmp(&b)
+}
diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs
index 7f99ca724cf..7aadc8a0954 100644
--- a/src/test/codegen/issue-45222.rs
+++ b/src/test/codegen/issue-45222.rs
@@ -5,7 +5,6 @@
 
 // verify that LLVM recognizes a loop involving 0..=n and will const-fold it.
 
-//------------------------------------------------------------------------------
 // Example from original issue #45222
 
 fn foo2(n: u64) -> u64 {
@@ -25,7 +24,6 @@ pub fn check_foo2() -> u64 {
     foo2(100000)
 }
 
-//------------------------------------------------------------------------------
 // Simplified example of #45222
 
 fn triangle_inc(n: u64) -> u64 {
@@ -43,7 +41,6 @@ pub fn check_triangle_inc() -> u64 {
     triangle_inc(100000)
 }
 
-//------------------------------------------------------------------------------
 // Demo in #48012
 
 fn foo3r(n: u64) -> u64 {
diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs
index d859cbef39f..50d3657d417 100644
--- a/src/test/incremental/hashes/call_expressions.rs
+++ b/src/test/incremental/hashes/call_expressions.rs
@@ -18,7 +18,7 @@ fn callee1(_x: u32, _y: i64) {}
 fn callee2(_x: u32, _y: i64) {}
 
 
-// Change Callee (Function) ----------------------------------------------------
+// Change Callee (Function)
 #[cfg(cfail1)]
 pub fn change_callee_function() {
     callee1(1, 2)
@@ -33,7 +33,7 @@ pub fn change_callee_function() {
 
 
 
-// Change Argument (Function) --------------------------------------------------
+// Change Argument (Function)
 #[cfg(cfail1)]
 pub fn change_argument_function() {
     callee1(1, 2)
@@ -48,7 +48,7 @@ pub fn change_argument_function() {
 
 
 
-// Change Callee Indirectly (Function) -----------------------------------------
+// Change Callee Indirectly (Function)
 mod change_callee_indirectly_function {
     #[cfg(cfail1)]
     use super::callee1 as callee;
@@ -73,7 +73,7 @@ impl Struct {
     fn method2(&self, _x: char, _y: bool) {}
 }
 
-// Change Callee (Method) ------------------------------------------------------
+// Change Callee (Method)
 #[cfg(cfail1)]
 pub fn change_callee_method() {
     let s = Struct;
@@ -90,7 +90,7 @@ pub fn change_callee_method() {
 
 
 
-// Change Argument (Method) ----------------------------------------------------
+// Change Argument (Method)
 #[cfg(cfail1)]
 pub fn change_argument_method() {
     let s = Struct;
@@ -107,7 +107,7 @@ pub fn change_argument_method() {
 
 
 
-// Change Callee (Method, UFCS) ------------------------------------------------
+// Change Callee (Method, UFCS)
 #[cfg(cfail1)]
 pub fn change_ufcs_callee_method() {
     let s = Struct;
@@ -124,7 +124,7 @@ pub fn change_ufcs_callee_method() {
 
 
 
-// Change Argument (Method, UFCS) ----------------------------------------------
+// Change Argument (Method, UFCS)
 #[cfg(cfail1)]
 pub fn change_argument_method_ufcs() {
     let s = Struct;
@@ -141,7 +141,7 @@ pub fn change_argument_method_ufcs() {
 
 
 
-// Change To UFCS --------------------------------------------------------------
+// Change To UFCS
 #[cfg(cfail1)]
 pub fn change_to_ufcs() {
     let s = Struct;
@@ -164,7 +164,7 @@ impl Struct2 {
     fn method1(&self, _x: char, _y: bool) {}
 }
 
-// Change UFCS Callee Indirectly -----------------------------------------------
+// Change UFCS Callee Indirectly
 pub mod change_ufcs_callee_indirectly {
     #[cfg(cfail1)]
     use super::Struct as Struct;
diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs
index 24ab6b8e184..08693560d0b 100644
--- a/src/test/incremental/hashes/closure_expressions.rs
+++ b/src/test/incremental/hashes/closure_expressions.rs
@@ -14,7 +14,7 @@
 #![crate_type="rlib"]
 
 
-// Change closure body ---------------------------------------------------------
+// Change closure body
 #[cfg(cfail1)]
 pub fn change_closure_body() {
     let _ = || 1u32;
@@ -29,7 +29,7 @@ pub fn change_closure_body() {
 
 
 
-// Add parameter ---------------------------------------------------------------
+// Add parameter
 #[cfg(cfail1)]
 pub fn add_parameter() {
     let x = 0u32;
@@ -46,7 +46,7 @@ pub fn add_parameter() {
 
 
 
-// Change parameter pattern ----------------------------------------------------
+// Change parameter pattern
 #[cfg(cfail1)]
 pub fn change_parameter_pattern() {
     let _ = |x: (u32,)| x;
@@ -61,7 +61,7 @@ pub fn change_parameter_pattern() {
 
 
 
-// Add `move` to closure -------------------------------------------------------
+// Add `move` to closure
 #[cfg(cfail1)]
 pub fn add_move() {
     let _ = || 1;
@@ -76,7 +76,7 @@ pub fn add_move() {
 
 
 
-// Add type ascription to parameter --------------------------------------------
+// Add type ascription to parameter
 #[cfg(cfail1)]
 pub fn add_type_ascription_to_parameter() {
     let closure = |x| x + 1u32;
@@ -93,7 +93,7 @@ pub fn add_type_ascription_to_parameter() {
 
 
 
-// Change parameter type -------------------------------------------------------
+// Change parameter type
 #[cfg(cfail1)]
 pub fn change_parameter_type() {
     let closure = |x: u32| (x as u64) + 1;
diff --git a/src/test/incremental/hashes/consts.rs b/src/test/incremental/hashes/consts.rs
index 8e713a1d992..3d2eed89636 100644
--- a/src/test/incremental/hashes/consts.rs
+++ b/src/test/incremental/hashes/consts.rs
@@ -14,7 +14,7 @@
 #![crate_type="rlib"]
 
 
-// Change const visibility ---------------------------------------------------
+// Change const visibility
 #[cfg(cfail1)]
 const CONST_VISIBILITY: u8 = 0;
 
@@ -24,7 +24,7 @@ const CONST_VISIBILITY: u8 = 0;
 pub const CONST_VISIBILITY: u8 = 0;
 
 
-// Change type from i32 to u32 ------------------------------------------------
+// Change type from i32 to u32
 #[cfg(cfail1)]
 const CONST_CHANGE_TYPE_1: i32 = 0;
 
@@ -34,7 +34,7 @@ const CONST_CHANGE_TYPE_1: i32 = 0;
 const CONST_CHANGE_TYPE_1: u32 = 0;
 
 
-// Change type from Option<u32> to Option<u64> --------------------------------
+// Change type from Option<u32> to Option<u64>
 #[cfg(cfail1)]
 const CONST_CHANGE_TYPE_2: Option<u32> = None;
 
@@ -44,7 +44,7 @@ const CONST_CHANGE_TYPE_2: Option<u32> = None;
 const CONST_CHANGE_TYPE_2: Option<u64> = None;
 
 
-// Change value between simple literals ---------------------------------------
+// Change value between simple literals
 #[rustc_clean(cfg="cfail2", except="HirBody")]
 #[rustc_clean(cfg="cfail3")]
 const CONST_CHANGE_VALUE_1: i16 = {
@@ -56,7 +56,7 @@ const CONST_CHANGE_VALUE_1: i16 = {
 };
 
 
-// Change value between expressions -------------------------------------------
+// Change value between expressions
 #[rustc_clean(cfg="cfail2", except="HirBody")]
 #[rustc_clean(cfg="cfail3")]
 const CONST_CHANGE_VALUE_2: i16 = {
@@ -88,7 +88,7 @@ const CONST_CHANGE_VALUE_4: i16 = {
 };
 
 
-// Change type indirectly -----------------------------------------------------
+// Change type indirectly
 struct ReferencedType1;
 struct ReferencedType2;
 
diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs
index b84c393573b..4b73f1371f8 100644
--- a/src/test/incremental/hashes/if_expressions.rs
+++ b/src/test/incremental/hashes/if_expressions.rs
@@ -14,7 +14,7 @@
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
-// Change condition (if) -------------------------------------------------------
+// Change condition (if)
 #[cfg(cfail1)]
 pub fn change_condition(x: bool) -> u32 {
     if x {
@@ -35,7 +35,7 @@ pub fn change_condition(x: bool) -> u32 {
     return 0
 }
 
-// Change then branch (if) -----------------------------------------------------
+// Change then branch (if)
 #[cfg(cfail1)]
 pub fn change_then_branch(x: bool) -> u32 {
     if x {
@@ -58,7 +58,7 @@ pub fn change_then_branch(x: bool) -> u32 {
 
 
 
-// Change else branch (if) -----------------------------------------------------
+// Change else branch (if)
 #[cfg(cfail1)]
 pub fn change_else_branch(x: bool) -> u32 {
     if x {
@@ -81,7 +81,7 @@ pub fn change_else_branch(x: bool) -> u32 {
 
 
 
-// Add else branch (if) --------------------------------------------------------
+// Add else branch (if)
 #[cfg(cfail1)]
 pub fn add_else_branch(x: bool) -> u32 {
     let mut ret = 1;
@@ -109,7 +109,7 @@ pub fn add_else_branch(x: bool) -> u32 {
 
 
 
-// Change condition (if let) ---------------------------------------------------
+// Change condition (if let)
 #[cfg(cfail1)]
 pub fn change_condition_if_let(x: Option<u32>) -> u32 {
     if let Some(_x) = x {
@@ -132,7 +132,7 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 {
 
 
 
-// Change then branch (if let) -------------------------------------------------
+// Change then branch (if let)
 #[cfg(cfail1)]
 pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
@@ -155,7 +155,7 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 {
 
 
 
-// Change else branch (if let) -------------------------------------------------
+// Change else branch (if let)
 #[cfg(cfail1)]
 pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
     if let Some(x) = x {
@@ -178,7 +178,7 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 {
 
 
 
-// Add else branch (if let) ----------------------------------------------------
+// Add else branch (if let)
 #[cfg(cfail1)]
 pub fn add_else_branch_if_let(x: Option<u32>) -> u32 {
     let mut ret = 1;
diff --git a/src/test/incremental/hashes/indexing_expressions.rs b/src/test/incremental/hashes/indexing_expressions.rs
index 4d39ed68701..08cf19d7760 100644
--- a/src/test/incremental/hashes/indexing_expressions.rs
+++ b/src/test/incremental/hashes/indexing_expressions.rs
@@ -13,7 +13,7 @@
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 
-// Change simple index ---------------------------------------------------------
+// Change simple index
 #[cfg(cfail1)]
 fn change_simple_index(slice: &[u32]) -> u32 {
     slice[3]
@@ -30,7 +30,7 @@ fn change_simple_index(slice: &[u32]) -> u32 {
 
 
 
-// Change lower bound ----------------------------------------------------------
+// Change lower bound
 #[cfg(cfail1)]
 fn change_lower_bound(slice: &[u32]) -> &[u32] {
     &slice[3..5]
@@ -47,7 +47,7 @@ fn change_lower_bound(slice: &[u32]) -> &[u32] {
 
 
 
-// Change upper bound ----------------------------------------------------------
+// Change upper bound
 #[cfg(cfail1)]
 fn change_upper_bound(slice: &[u32]) -> &[u32] {
     &slice[3..5]
@@ -64,7 +64,7 @@ fn change_upper_bound(slice: &[u32]) -> &[u32] {
 
 
 
-// Add lower bound -------------------------------------------------------------
+// Add lower bound
 #[cfg(cfail1)]
 fn add_lower_bound(slice: &[u32]) -> &[u32] {
     &slice[..4]
@@ -81,7 +81,7 @@ fn add_lower_bound(slice: &[u32]) -> &[u32] {
 
 
 
-// Add upper bound -------------------------------------------------------------
+// Add upper bound
 #[cfg(cfail1)]
 fn add_upper_bound(slice: &[u32]) -> &[u32] {
     &slice[3..]
@@ -98,7 +98,7 @@ fn add_upper_bound(slice: &[u32]) -> &[u32] {
 
 
 
-// Change mutability -----------------------------------------------------------
+// Change mutability
 #[cfg(cfail1)]
 fn change_mutability(slice: &mut [u32]) -> u32 {
     (&mut slice[3..5])[0]
@@ -115,7 +115,7 @@ fn change_mutability(slice: &mut [u32]) -> u32 {
 
 
 
-// Exclusive to inclusive range ------------------------------------------------
+// Exclusive to inclusive range
 #[cfg(cfail1)]
 fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] {
     &slice[3..7]
diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs
index deb1c45a528..c50ee73d714 100644
--- a/src/test/incremental/hashes/inline_asm.rs
+++ b/src/test/incremental/hashes/inline_asm.rs
@@ -16,7 +16,7 @@
 
 
 
-// Change template -------------------------------------------------------------
+// Change template
 #[cfg(cfail1)]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_template(a: i32) -> i32 {
@@ -51,7 +51,7 @@ pub fn change_template(a: i32) -> i32 {
 
 
 
-// Change output -------------------------------------------------------------
+// Change output
 #[cfg(cfail1)]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_output(a: i32) -> i32 {
@@ -88,7 +88,7 @@ pub fn change_output(a: i32) -> i32 {
 
 
 
-// Change input -------------------------------------------------------------
+// Change input
 #[cfg(cfail1)]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input(_a: i32, _b: i32) -> i32 {
@@ -123,7 +123,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 {
 
 
 
-// Change input constraint -----------------------------------------------------
+// Change input constraint
 #[cfg(cfail1)]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
@@ -158,7 +158,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 {
 
 
 
-// Change clobber --------------------------------------------------------------
+// Change clobber
 #[cfg(cfail1)]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_clobber(_a: i32) -> i32 {
@@ -193,7 +193,7 @@ pub fn change_clobber(_a: i32) -> i32 {
 
 
 
-// Change options --------------------------------------------------------------
+// Change options
 #[cfg(cfail1)]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 pub fn change_options(_a: i32) -> i32 {
diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs
index 6222d948c98..a2222db4c59 100644
--- a/src/test/incremental/hashes/loop_expressions.rs
+++ b/src/test/incremental/hashes/loop_expressions.rs
@@ -14,7 +14,7 @@
 #![crate_type="rlib"]
 
 
-// Change loop body ------------------------------------------------------------
+// Change loop body
 #[cfg(cfail1)]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -37,7 +37,7 @@ pub fn change_loop_body() {
 
 
 
-// Add break -------------------------------------------------------------------
+// Add break
 #[cfg(cfail1)]
 pub fn add_break() {
     let mut _x = 0;
@@ -59,7 +59,7 @@ pub fn add_break() {
 
 
 
-// Add loop label --------------------------------------------------------------
+// Add loop label
 #[cfg(cfail1)]
 pub fn add_loop_label() {
     let mut _x = 0;
@@ -82,7 +82,7 @@ pub fn add_loop_label() {
 
 
 
-// Add loop label to break -----------------------------------------------------
+// Add loop label to break
 #[cfg(cfail1)]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
@@ -105,7 +105,7 @@ pub fn add_loop_label_to_break() {
 
 
 
-// Change break label ----------------------------------------------------------
+// Change break label
 #[cfg(cfail1)]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -132,7 +132,7 @@ pub fn change_break_label() {
 
 
 
-// Add loop label to continue --------------------------------------------------
+// Add loop label to continue
 #[cfg(cfail1)]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
@@ -155,7 +155,7 @@ pub fn add_loop_label_to_continue() {
 
 
 
-// Change continue label ----------------------------------------------------------
+// Change continue label
 #[cfg(cfail1)]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -182,7 +182,7 @@ pub fn change_continue_label() {
 
 
 
-// Change continue to break ----------------------------------------------------
+// Change continue to break
 #[cfg(cfail1)]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs
index b370fcce8ef..70b0a5ab78c 100644
--- a/src/test/incremental/hashes/panic_exprs.rs
+++ b/src/test/incremental/hashes/panic_exprs.rs
@@ -17,7 +17,7 @@
 #![crate_type="rlib"]
 
 
-// Indexing expression ---------------------------------------------------------
+// Indexing expression
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn indexing(slice: &[u8]) -> u8 {
@@ -32,7 +32,7 @@ pub fn indexing(slice: &[u8]) -> u8 {
 }
 
 
-// Arithmetic overflow plus ----------------------------------------------------
+// Arithmetic overflow plus
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_plus(val: i32) -> i32 {
@@ -47,7 +47,7 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 {
 }
 
 
-// Arithmetic overflow minus ----------------------------------------------------
+// Arithmetic overflow minus
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_minus(val: i32) -> i32 {
@@ -62,7 +62,7 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 {
 }
 
 
-// Arithmetic overflow mult ----------------------------------------------------
+// Arithmetic overflow mult
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_mult(val: i32) -> i32 {
@@ -77,7 +77,7 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 {
 }
 
 
-// Arithmetic overflow negation ------------------------------------------------
+// Arithmetic overflow negation
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn arithmetic_overflow_negation(val: i32) -> i32 {
@@ -92,7 +92,7 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 {
 }
 
 
-// Division by zero ------------------------------------------------------------
+// Division by zero
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn division_by_zero(val: i32) -> i32 {
@@ -106,7 +106,7 @@ pub fn division_by_zero(val: i32) -> i32 {
     }
 }
 
-// Division by zero ------------------------------------------------------------
+// Division by zero
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn mod_by_zero(val: i32) -> i32 {
@@ -121,7 +121,7 @@ pub fn mod_by_zero(val: i32) -> i32 {
 }
 
 
-// shift left ------------------------------------------------------------------
+// shift left
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn shift_left(val: i32, shift: usize) -> i32 {
@@ -136,7 +136,7 @@ pub fn shift_left(val: i32, shift: usize) -> i32 {
 }
 
 
-// shift right ------------------------------------------------------------------
+// shift right
 #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn shift_right(val: i32, shift: usize) -> i32 {
diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs
index 6f74e0fdbc0..d70ebb08b71 100644
--- a/src/test/incremental/hashes/statics.rs
+++ b/src/test/incremental/hashes/statics.rs
@@ -16,7 +16,7 @@
 #![crate_type="rlib"]
 
 
-// Change static visibility ---------------------------------------------------
+// Change static visibility
 #[cfg(cfail1)]
 static STATIC_VISIBILITY: u8 = 0;
 
@@ -26,7 +26,7 @@ static STATIC_VISIBILITY: u8 = 0;
 pub static STATIC_VISIBILITY: u8 = 0;
 
 
-// Change static mutability ---------------------------------------------------
+// Change static mutability
 #[cfg(cfail1)]
 static STATIC_MUTABILITY: u8 = 0;
 
@@ -36,7 +36,7 @@ static STATIC_MUTABILITY: u8 = 0;
 static mut STATIC_MUTABILITY: u8 = 0;
 
 
-// Add linkage attribute ------------------------------------------------------
+// Add linkage attribute
 #[cfg(cfail1)]
 static STATIC_LINKAGE: u8 = 0;
 
@@ -47,7 +47,7 @@ static STATIC_LINKAGE: u8 = 0;
 static STATIC_LINKAGE: u8 = 0;
 
 
-// Add no_mangle attribute ----------------------------------------------------
+// Add no_mangle attribute
 #[cfg(cfail1)]
 static STATIC_NO_MANGLE: u8 = 0;
 
@@ -58,7 +58,7 @@ static STATIC_NO_MANGLE: u8 = 0;
 static STATIC_NO_MANGLE: u8 = 0;
 
 
-// Add thread_local attribute -------------------------------------------------
+// Add thread_local attribute
 #[cfg(cfail1)]
 static STATIC_THREAD_LOCAL: u8 = 0;
 
@@ -69,7 +69,7 @@ static STATIC_THREAD_LOCAL: u8 = 0;
 static STATIC_THREAD_LOCAL: u8 = 0;
 
 
-// Change type from i16 to u64 ------------------------------------------------
+// Change type from i16 to u64
 #[cfg(cfail1)]
 static STATIC_CHANGE_TYPE_1: i16 = 0;
 
@@ -79,7 +79,7 @@ static STATIC_CHANGE_TYPE_1: i16 = 0;
 static STATIC_CHANGE_TYPE_1: u64 = 0;
 
 
-// Change type from Option<i8> to Option<u16> ---------------------------------
+// Change type from Option<i8> to Option<u16>
 #[cfg(cfail1)]
 static STATIC_CHANGE_TYPE_2: Option<i8> = None;
 
@@ -89,7 +89,7 @@ static STATIC_CHANGE_TYPE_2: Option<i8> = None;
 static STATIC_CHANGE_TYPE_2: Option<u16> = None;
 
 
-// Change value between simple literals ---------------------------------------
+// Change value between simple literals
 #[rustc_clean(cfg="cfail2", except="HirBody")]
 #[rustc_clean(cfg="cfail3")]
 static STATIC_CHANGE_VALUE_1: i16 = {
@@ -101,7 +101,7 @@ static STATIC_CHANGE_VALUE_1: i16 = {
 };
 
 
-// Change value between expressions -------------------------------------------
+// Change value between expressions
 #[rustc_clean(cfg="cfail2", except="HirBody")]
 #[rustc_clean(cfg="cfail3")]
 static STATIC_CHANGE_VALUE_2: i16 = {
@@ -133,7 +133,7 @@ static STATIC_CHANGE_VALUE_4: i16 = {
 };
 
 
-// Change type indirectly -----------------------------------------------------
+// Change type indirectly
 struct ReferencedType1;
 struct ReferencedType2;
 
diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs
index b708b99eabc..456d5e74751 100644
--- a/src/test/incremental/hashes/struct_constructors.rs
+++ b/src/test/incremental/hashes/struct_constructors.rs
@@ -20,7 +20,7 @@ pub struct RegularStruct {
     z: i16,
 }
 
-// Change field value (regular struct) -----------------------------------------
+// Change field value (regular struct)
 #[cfg(cfail1)]
 pub fn change_field_value_regular_struct() -> RegularStruct {
     RegularStruct {
@@ -43,7 +43,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct {
 
 
 
-// Change field order (regular struct) -----------------------------------------
+// Change field order (regular struct)
 #[cfg(cfail1)]
 pub fn change_field_order_regular_struct() -> RegularStruct {
     RegularStruct {
@@ -66,7 +66,7 @@ pub fn change_field_order_regular_struct() -> RegularStruct {
 
 
 
-// Add field (regular struct) --------------------------------------------------
+// Add field (regular struct)
 #[cfg(cfail1)]
 pub fn add_field_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
@@ -100,7 +100,7 @@ pub fn add_field_regular_struct() -> RegularStruct {
 
 
 
-// Change field label (regular struct) -----------------------------------------
+// Change field label (regular struct)
 #[cfg(cfail1)]
 pub fn change_field_label_regular_struct() -> RegularStruct {
     let struct1 = RegularStruct {
@@ -141,7 +141,7 @@ pub struct RegularStruct2 {
     z: i8,
 }
 
-// Change constructor path (regular struct) ------------------------------------
+// Change constructor path (regular struct)
 #[cfg(cfail1)]
 pub fn change_constructor_path_regular_struct() {
     let _ = RegularStruct {
@@ -164,7 +164,7 @@ pub fn change_constructor_path_regular_struct() {
 
 
 
-// Change constructor path indirectly (regular struct) -------------------------
+// Change constructor path indirectly (regular struct)
 pub mod change_constructor_path_indirectly_regular_struct {
     #[cfg(cfail1)]
     use super::RegularStruct as Struct;
@@ -189,7 +189,7 @@ pub mod change_constructor_path_indirectly_regular_struct {
 
 pub struct TupleStruct(i32, i64, i16);
 
-// Change field value (tuple struct) -------------------------------------------
+// Change field value (tuple struct)
 #[cfg(cfail1)]
 pub fn change_field_value_tuple_struct() -> TupleStruct {
     TupleStruct(0, 1, 2)
@@ -206,7 +206,7 @@ pub fn change_field_value_tuple_struct() -> TupleStruct {
 
 pub struct TupleStruct2(u16, u16, u16);
 
-// Change constructor path (tuple struct) --------------------------------------
+// Change constructor path (tuple struct)
 #[cfg(cfail1)]
 pub fn change_constructor_path_tuple_struct() {
     let _ = TupleStruct(0, 1, 2);
@@ -221,7 +221,7 @@ pub fn change_constructor_path_tuple_struct() {
 
 
 
-// Change constructor path indirectly (tuple struct) ---------------------------
+// Change constructor path indirectly (tuple struct)
 pub mod change_constructor_path_indirectly_tuple_struct {
     #[cfg(cfail1)]
     use super::TupleStruct as Struct;
diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs
index 30b4e306820..81ff99533fc 100644
--- a/src/test/incremental/hashes/trait_defs.rs
+++ b/src/test/incremental/hashes/trait_defs.rs
@@ -21,7 +21,7 @@
 #![feature(intrinsics)]
 
 
-// Change trait visibility --------------------------------------------------------
+// Change trait visibility
 #[cfg(cfail1)]
 trait TraitVisibility { }
 
@@ -32,7 +32,7 @@ pub trait TraitVisibility { }
 
 
 
-// Change trait unsafety ----------------------------------------------------------
+// Change trait unsafety
 #[cfg(cfail1)]
 trait TraitUnsafety { }
 
@@ -43,7 +43,7 @@ unsafe trait TraitUnsafety { }
 
 
 
-// Add method ---------------------------------------------------------------------
+// Add method
 #[cfg(cfail1)]
 trait TraitAddMethod {
 }
@@ -57,7 +57,7 @@ pub trait TraitAddMethod {
 
 
 
-// Change name of method ----------------------------------------------------------
+// Change name of method
 #[cfg(cfail1)]
 trait TraitChangeMethodName {
     fn method();
@@ -72,7 +72,7 @@ trait TraitChangeMethodName {
 
 
 
-// Add return type to method ------------------------------------------------------
+// Add return type to method
 #[cfg(cfail1)]
 trait TraitAddReturnType {
     fn method();
@@ -89,7 +89,7 @@ trait TraitAddReturnType {
 
 
 
-// Change return type of method ---------------------------------------------------
+// Change return type of method
 #[cfg(cfail1)]
 trait TraitChangeReturnType {
     fn method() -> u32;
@@ -106,7 +106,7 @@ trait TraitChangeReturnType {
 
 
 
-// Add parameter to method --------------------------------------------------------
+// Add parameter to method
 #[cfg(cfail1)]
 trait TraitAddParameterToMethod {
     fn method();
@@ -123,7 +123,7 @@ trait TraitAddParameterToMethod {
 
 
 
-// Change name of method parameter ------------------------------------------------
+// Change name of method parameter
 #[cfg(cfail1)]
 trait TraitChangeMethodParameterName {
     fn method(a: u32);
@@ -148,7 +148,7 @@ trait TraitChangeMethodParameterName {
 
 
 
-// Change type of method parameter (i32 => i64) -----------------------------------
+// Change type of method parameter (i32 => i64)
 #[cfg(cfail1)]
 trait TraitChangeMethodParameterType {
     fn method(a: i32);
@@ -165,7 +165,7 @@ trait TraitChangeMethodParameterType {
 
 
 
-// Change type of method parameter (&i32 => &mut i32) -----------------------------
+// Change type of method parameter (&i32 => &mut i32)
 #[cfg(cfail1)]
 trait TraitChangeMethodParameterTypeRef {
     fn method(a: &i32);
@@ -182,7 +182,7 @@ trait TraitChangeMethodParameterTypeRef {
 
 
 
-// Change order of method parameters ----------------------------------------------
+// Change order of method parameters
 #[cfg(cfail1)]
 trait TraitChangeMethodParametersOrder {
     fn method(a: i32, b: i64);
@@ -199,7 +199,7 @@ trait TraitChangeMethodParametersOrder {
 
 
 
-// Add default implementation to method -------------------------------------------
+// Add default implementation to method
 #[cfg(cfail1)]
 trait TraitAddMethodAutoImplementation {
     fn method();
@@ -216,7 +216,7 @@ trait TraitAddMethodAutoImplementation {
 
 
 
-// Change order of methods --------------------------------------------------------
+// Change order of methods
 #[cfg(cfail1)]
 trait TraitChangeOrderOfMethods {
     fn method0();
@@ -233,7 +233,7 @@ trait TraitChangeOrderOfMethods {
 
 
 
-// Change mode of self parameter --------------------------------------------------
+// Change mode of self parameter
 #[cfg(cfail1)]
 trait TraitChangeModeSelfRefToMut {
     fn method(&self);
@@ -284,7 +284,7 @@ trait TraitChangeModeSelfOwnToRef {
 
 
 
-// Add unsafe modifier to method --------------------------------------------------
+// Add unsafe modifier to method
 #[cfg(cfail1)]
 trait TraitAddUnsafeModifier {
     fn method();
@@ -301,7 +301,7 @@ trait TraitAddUnsafeModifier {
 
 
 
-// Add extern modifier to method --------------------------------------------------
+// Add extern modifier to method
 #[cfg(cfail1)]
 trait TraitAddExternModifier {
     fn method();
@@ -318,7 +318,7 @@ trait TraitAddExternModifier {
 
 
 
-// Change extern "C" to extern "rust-intrinsic" -----------------------------------
+// Change extern "C" to extern "rust-intrinsic"
 #[cfg(cfail1)]
 trait TraitChangeExternCToRustIntrinsic {
     extern "C" fn method();
@@ -335,7 +335,7 @@ trait TraitChangeExternCToRustIntrinsic {
 
 
 
-// Add type parameter to method ---------------------------------------------------
+// Add type parameter to method
 #[cfg(cfail1)]
 trait TraitAddTypeParameterToMethod {
     fn method();
@@ -352,7 +352,7 @@ trait TraitAddTypeParameterToMethod {
 
 
 
-// Add lifetime parameter to method -----------------------------------------------
+// Add lifetime parameter to method
 #[cfg(cfail1)]
 trait TraitAddLifetimeParameterToMethod {
     fn method();
@@ -373,7 +373,7 @@ trait TraitAddLifetimeParameterToMethod {
 trait ReferencedTrait0 { }
 trait ReferencedTrait1 { }
 
-// Add trait bound to method type parameter ---------------------------------------
+// Add trait bound to method type parameter
 #[cfg(cfail1)]
 trait TraitAddTraitBoundToMethodTypeParameter {
     fn method<T>();
@@ -390,7 +390,7 @@ trait TraitAddTraitBoundToMethodTypeParameter {
 
 
 
-// Add builtin bound to method type parameter -------------------------------------
+// Add builtin bound to method type parameter
 #[cfg(cfail1)]
 trait TraitAddBuiltinBoundToMethodTypeParameter {
     fn method<T>();
@@ -407,7 +407,7 @@ trait TraitAddBuiltinBoundToMethodTypeParameter {
 
 
 
-// Add lifetime bound to method lifetime parameter ------------------------------------
+// Add lifetime bound to method lifetime parameter
 #[cfg(cfail1)]
 trait TraitAddLifetimeBoundToMethodLifetimeParameter {
     fn method<'a, 'b>(a: &'a u32, b: &'b u32);
@@ -424,7 +424,7 @@ trait TraitAddLifetimeBoundToMethodLifetimeParameter {
 
 
 
-// Add second trait bound to method type parameter --------------------------------
+// Add second trait bound to method type parameter
 #[cfg(cfail1)]
 trait TraitAddSecondTraitBoundToMethodTypeParameter {
     fn method<T: ReferencedTrait0>();
@@ -441,7 +441,7 @@ trait TraitAddSecondTraitBoundToMethodTypeParameter {
 
 
 
-// Add second builtin bound to method type parameter ------------------------------
+// Add second builtin bound to method type parameter
 #[cfg(cfail1)]
 trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
     fn method<T: Sized>();
@@ -458,7 +458,7 @@ trait TraitAddSecondBuiltinBoundToMethodTypeParameter {
 
 
 
-// Add second lifetime bound to method lifetime parameter -----------------------------
+// Add second lifetime bound to method lifetime parameter
 #[cfg(cfail1)]
 trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
     fn method<'a, 'b, 'c: 'a>(a: &'a u32, b: &'b u32, c: &'c u32);
@@ -475,7 +475,7 @@ trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter {
 
 
 
-// Add associated type ------------------------------------------------------------
+// Add associated type
 #[cfg(cfail1)]
 trait TraitAddAssociatedType {
 
@@ -495,7 +495,7 @@ trait TraitAddAssociatedType {
 
 
 
-// Add trait bound to associated type ---------------------------------------------
+// Add trait bound to associated type
 #[cfg(cfail1)]
 trait TraitAddTraitBoundToAssociatedType {
     type Associated;
@@ -519,7 +519,7 @@ trait TraitAddTraitBoundToAssociatedType {
 
 
 
-// Add lifetime bound to associated type ------------------------------------------
+// Add lifetime bound to associated type
 #[cfg(cfail1)]
 trait TraitAddLifetimeBoundToAssociatedType<'a> {
     type Associated;
@@ -540,7 +540,7 @@ trait TraitAddLifetimeBoundToAssociatedType<'a> {
 
 
 
-// Add default to associated type -------------------------------------------------
+// Add default to associated type
 #[cfg(cfail1)]
 trait TraitAddDefaultToAssociatedType {
     type Associated;
@@ -561,7 +561,7 @@ trait TraitAddDefaultToAssociatedType {
 
 
 
-// Add associated constant --------------------------------------------------------
+// Add associated constant
 #[cfg(cfail1)]
 trait TraitAddAssociatedConstant {
     fn method();
@@ -578,7 +578,7 @@ trait TraitAddAssociatedConstant {
 
 
 
-// Add initializer to associated constant -----------------------------------------
+// Add initializer to associated constant
 #[cfg(cfail1)]
 trait TraitAddInitializerToAssociatedConstant {
     const Value: u32;
@@ -601,7 +601,7 @@ trait TraitAddInitializerToAssociatedConstant {
 
 
 
-// Change type of associated constant ---------------------------------------------
+// Change type of associated constant
 #[cfg(cfail1)]
 trait TraitChangeTypeOfAssociatedConstant {
     const Value: u32;
@@ -624,7 +624,7 @@ trait TraitChangeTypeOfAssociatedConstant {
 
 
 
-// Add super trait ----------------------------------------------------------------
+// Add super trait
 #[cfg(cfail1)]
 trait TraitAddSuperTrait { }
 
@@ -635,7 +635,7 @@ trait TraitAddSuperTrait : ReferencedTrait0 { }
 
 
 
-// Add builtin bound (Send or Copy) -----------------------------------------------
+// Add builtin bound (Send or Copy)
 #[cfg(cfail1)]
 trait TraitAddBuiltiBound { }
 
@@ -646,7 +646,7 @@ trait TraitAddBuiltiBound : Send { }
 
 
 
-// Add 'static lifetime bound to trait --------------------------------------------
+// Add 'static lifetime bound to trait
 #[cfg(cfail1)]
 trait TraitAddStaticLifetimeBound { }
 
@@ -657,7 +657,7 @@ trait TraitAddStaticLifetimeBound : 'static { }
 
 
 
-// Add super trait as second bound ------------------------------------------------
+// Add super trait as second bound
 #[cfg(cfail1)]
 trait TraitAddTraitAsSecondBound : ReferencedTrait0 { }
 
@@ -676,7 +676,7 @@ trait TraitAddTraitAsSecondBoundFromBuiltin : Send + ReferencedTrait0 { }
 
 
 
-// Add builtin bound as second bound ----------------------------------------------
+// Add builtin bound as second bound
 #[cfg(cfail1)]
 trait TraitAddBuiltinBoundAsSecondBound : ReferencedTrait0 { }
 
@@ -695,7 +695,7 @@ trait TraitAddBuiltinBoundAsSecondBoundFromBuiltin: Send + Copy { }
 
 
 
-// Add 'static bounds as second bound ---------------------------------------------
+// Add 'static bounds as second bound
 #[cfg(cfail1)]
 trait TraitAddStaticBoundAsSecondBound : ReferencedTrait0 { }
 
@@ -714,7 +714,7 @@ trait TraitAddStaticBoundAsSecondBoundFromBuiltin : Send + 'static { }
 
 
 
-// Add type parameter to trait ----------------------------------------------------
+// Add type parameter to trait
 #[cfg(cfail1)]
 trait TraitAddTypeParameterToTrait { }
 
@@ -725,7 +725,7 @@ trait TraitAddTypeParameterToTrait<T> { }
 
 
 
-// Add lifetime parameter to trait ------------------------------------------------
+// Add lifetime parameter to trait
 #[cfg(cfail1)]
 trait TraitAddLifetimeParameterToTrait { }
 
@@ -736,7 +736,7 @@ trait TraitAddLifetimeParameterToTrait<'a> { }
 
 
 
-// Add trait bound to type parameter of trait -------------------------------------
+// Add trait bound to type parameter of trait
 #[cfg(cfail1)]
 trait TraitAddTraitBoundToTypeParameterOfTrait<T> { }
 
@@ -747,7 +747,7 @@ trait TraitAddTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
 
 
 
-// Add lifetime bound to type parameter of trait ----------------------------------
+// Add lifetime bound to type parameter of trait
 #[cfg(cfail1)]
 trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T> { }
 
@@ -758,7 +758,7 @@ trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T: 'a> { }
 
 
 
-// Add lifetime bound to lifetime parameter of trait ------------------------------
+// Add lifetime bound to lifetime parameter of trait
 #[cfg(cfail1)]
 trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a, 'b> { }
 
@@ -769,7 +769,7 @@ trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b> { }
 
 
 
-// Add builtin bound to type parameter of trait -----------------------------------
+// Add builtin bound to type parameter of trait
 #[cfg(cfail1)]
 trait TraitAddBuiltinBoundToTypeParameterOfTrait<T> { }
 
@@ -780,7 +780,7 @@ trait TraitAddBuiltinBoundToTypeParameterOfTrait<T: Send> { }
 
 
 
-// Add second type parameter to trait ---------------------------------------------
+// Add second type parameter to trait
 #[cfg(cfail1)]
 trait TraitAddSecondTypeParameterToTrait<T> { }
 
@@ -791,7 +791,7 @@ trait TraitAddSecondTypeParameterToTrait<T, S> { }
 
 
 
-// Add second lifetime parameter to trait -----------------------------------------
+// Add second lifetime parameter to trait
 #[cfg(cfail1)]
 trait TraitAddSecondLifetimeParameterToTrait<'a> { }
 
@@ -802,7 +802,7 @@ trait TraitAddSecondLifetimeParameterToTrait<'a, 'b> { }
 
 
 
-// Add second trait bound to type parameter of trait ------------------------------
+// Add second trait bound to type parameter of trait
 #[cfg(cfail1)]
 trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { }
 
@@ -813,7 +813,7 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0 + Refer
 
 
 
-// Add second lifetime bound to type parameter of trait ---------------------------
+// Add second lifetime bound to type parameter of trait
 #[cfg(cfail1)]
 trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a> { }
 
@@ -824,7 +824,7 @@ trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a + 'b> { }
 
 
 
-// Add second lifetime bound to lifetime parameter of trait------------------------
+// Add second lifetime bound to lifetime parameter of trait
 #[cfg(cfail1)]
 trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b, 'c> { }
 
@@ -835,7 +835,7 @@ trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b + 'c, 'b, 'c>
 
 
 
-// Add second builtin bound to type parameter of trait ----------------------------
+// Add second builtin bound to type parameter of trait
 #[cfg(cfail1)]
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send> { }
 
@@ -846,13 +846,12 @@ trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send + Sync> { }
 
 
 
-// --------------------------------------------------------------------------------
 struct ReferenceType0 {}
 struct ReferenceType1 {}
 
 
 
-// Add trait bound to type parameter of trait in where clause----------------------
+// Add trait bound to type parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> { }
 
@@ -863,7 +862,7 @@ trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0
 
 
 
-// Add lifetime bound to type parameter of trait in where clause-------------------
+// Add lifetime bound to type parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> { }
 
@@ -874,7 +873,7 @@ trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> where T: 'a { }
 
 
 
-// Add lifetime bound to lifetime parameter of trait in where clause---------------
+// Add lifetime bound to lifetime parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> { }
 
@@ -885,7 +884,7 @@ trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> where 'a: 'b
 
 
 
-// Add builtin bound to type parameter of trait in where clause--------------------
+// Add builtin bound to type parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> { }
 
@@ -896,7 +895,7 @@ trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
 
 
 
-// Add second trait bound to type parameter of trait in where clause---------------
+// Add second trait bound to type parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 { }
 
@@ -908,7 +907,7 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T>
 
 
 
-// Add second lifetime bound to type parameter of trait in where clause------------
+// Add second lifetime bound to type parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a { }
 
@@ -919,7 +918,7 @@ trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T:
 
 
 
-// Add second lifetime bound to lifetime parameter of trait in where clause--------
+// Add second lifetime bound to lifetime parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> where 'a: 'b { }
 
@@ -930,7 +929,7 @@ trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> whe
 
 
 
-// Add second builtin bound to type parameter of trait in where clause-------------
+// Add second builtin bound to type parameter of trait in where clause
 #[cfg(cfail1)]
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
 
@@ -940,7 +939,7 @@ trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { }
 trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send + Sync { }
 
 
-// Change return type of method indirectly by modifying a use statement------------
+// Change return type of method indirectly by modifying a use statement
 mod change_return_type_of_method_indirectly_use {
     #[cfg(cfail1)]
     use super::ReferenceType0 as ReturnType;
@@ -958,7 +957,7 @@ mod change_return_type_of_method_indirectly_use {
 
 
 
-// Change type of method parameter indirectly by modifying a use statement---------
+// Change type of method parameter indirectly by modifying a use statement
 mod change_method_parameter_type_indirectly_by_use {
     #[cfg(cfail1)]
     use super::ReferenceType0 as ArgType;
diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs
index 39b28ec1906..da3c957741f 100644
--- a/src/test/incremental/hashes/while_let_loops.rs
+++ b/src/test/incremental/hashes/while_let_loops.rs
@@ -14,7 +14,7 @@
 #![crate_type="rlib"]
 
 
-// Change loop body ------------------------------------------------------------
+// Change loop body
 #[cfg(cfail1)]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -37,7 +37,7 @@ pub fn change_loop_body() {
 
 
 
-// Change loop body ------------------------------------------------------------
+// Change loop body
 #[cfg(cfail1)]
 pub fn change_loop_condition() {
     let mut _x = 0;
@@ -60,7 +60,7 @@ pub fn change_loop_condition() {
 
 
 
-// Add break -------------------------------------------------------------------
+// Add break
 #[cfg(cfail1)]
 pub fn add_break() {
     let mut _x = 0;
@@ -82,7 +82,7 @@ pub fn add_break() {
 
 
 
-// Add loop label --------------------------------------------------------------
+// Add loop label
 #[cfg(cfail1)]
 pub fn add_loop_label() {
     let mut _x = 0;
@@ -105,7 +105,7 @@ pub fn add_loop_label() {
 
 
 
-// Add loop label to break -----------------------------------------------------
+// Add loop label to break
 #[cfg(cfail1)]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
@@ -128,7 +128,7 @@ pub fn add_loop_label_to_break() {
 
 
 
-// Change break label ----------------------------------------------------------
+// Change break label
 #[cfg(cfail1)]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -155,7 +155,7 @@ pub fn change_break_label() {
 
 
 
-// Add loop label to continue --------------------------------------------------
+// Add loop label to continue
 #[cfg(cfail1)]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
@@ -178,7 +178,7 @@ pub fn add_loop_label_to_continue() {
 
 
 
-// Change continue label ----------------------------------------------------------
+// Change continue label
 #[cfg(cfail1)]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -205,7 +205,7 @@ pub fn change_continue_label() {
 
 
 
-// Change continue to break ----------------------------------------------------
+// Change continue to break
 #[cfg(cfail1)]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs
index 06072185469..3be42e7a4ee 100644
--- a/src/test/incremental/hashes/while_loops.rs
+++ b/src/test/incremental/hashes/while_loops.rs
@@ -14,7 +14,7 @@
 #![crate_type="rlib"]
 
 
-// Change loop body ------------------------------------------------------------
+// Change loop body
 #[cfg(cfail1)]
 pub fn change_loop_body() {
     let mut _x = 0;
@@ -37,7 +37,7 @@ pub fn change_loop_body() {
 
 
 
-// Change loop body ------------------------------------------------------------
+// Change loop body
 #[cfg(cfail1)]
 pub fn change_loop_condition() {
     let mut _x = 0;
@@ -60,7 +60,7 @@ pub fn change_loop_condition() {
 
 
 
-// Add break -------------------------------------------------------------------
+// Add break
 #[cfg(cfail1)]
 pub fn add_break() {
     let mut _x = 0;
@@ -82,7 +82,7 @@ pub fn add_break() {
 
 
 
-// Add loop label --------------------------------------------------------------
+// Add loop label
 #[cfg(cfail1)]
 pub fn add_loop_label() {
     let mut _x = 0;
@@ -105,7 +105,7 @@ pub fn add_loop_label() {
 
 
 
-// Add loop label to break -----------------------------------------------------
+// Add loop label to break
 #[cfg(cfail1)]
 pub fn add_loop_label_to_break() {
     let mut _x = 0;
@@ -128,7 +128,7 @@ pub fn add_loop_label_to_break() {
 
 
 
-// Change break label ----------------------------------------------------------
+// Change break label
 #[cfg(cfail1)]
 pub fn change_break_label() {
     let mut _x = 0;
@@ -155,7 +155,7 @@ pub fn change_break_label() {
 
 
 
-// Add loop label to continue --------------------------------------------------
+// Add loop label to continue
 #[cfg(cfail1)]
 pub fn add_loop_label_to_continue() {
     let mut _x = 0;
@@ -178,7 +178,7 @@ pub fn add_loop_label_to_continue() {
 
 
 
-// Change continue label ----------------------------------------------------------
+// Change continue label
 #[cfg(cfail1)]
 pub fn change_continue_label() {
     let mut _x = 0;
@@ -205,7 +205,7 @@ pub fn change_continue_label() {
 
 
 
-// Change continue to break ----------------------------------------------------
+// Change continue to break
 #[cfg(cfail1)]
 pub fn change_continue_to_break() {
     let mut _x = 0;
diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs
index 7384f7027d1..5f9708a3972 100644
--- a/src/test/rustdoc/async-fn.rs
+++ b/src/test/rustdoc/async-fn.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 // @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>'
 pub async fn foo() -> Option<Foo> {
     None
diff --git a/src/test/rustdoc/async-move-doctest.rs b/src/test/rustdoc/async-move-doctest.rs
index 42723132782..2ba61388c9e 100644
--- a/src/test/rustdoc/async-move-doctest.rs
+++ b/src/test/rustdoc/async-move-doctest.rs
@@ -1,13 +1,11 @@
 // compile-flags:--test
 // edition:2018
 
-// prior to setting the default edition for the doctest pre-parser, this doctest would fail due to
-// a fatal parsing error
+// Prior to setting the default edition for the doctest pre-parser,
+// this doctest would fail due to a fatal parsing error.
 // see https://github.com/rust-lang/rust/issues/59313
 
 //! ```
-//! #![feature(async_await)]
-//!
 //! fn foo() {
 //!     drop(async move {});
 //! }
diff --git a/src/test/rustdoc/edition-flag.rs b/src/test/rustdoc/edition-flag.rs
index 5571245f28d..ddbc2be651d 100644
--- a/src/test/rustdoc/edition-flag.rs
+++ b/src/test/rustdoc/edition-flag.rs
@@ -1,10 +1,7 @@
 // compile-flags:--test -Z unstable-options
 // edition:2018
 
-#![feature(async_await)]
-
 /// ```rust
-/// #![feature(async_await)]
 /// fn main() {
 ///     let _ = async { };
 /// }
diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs
index 2696aea5e89..959f4a2babb 100644
--- a/src/test/ui/array-break-length.rs
+++ b/src/test/ui/array-break-length.rs
@@ -1,11 +1,11 @@
 fn main() {
     loop {
-        |_: [_; break]| {} //~ ERROR: `break` outside of loop
+        |_: [_; break]| {} //~ ERROR: `break` outside of a loop
         //~^ ERROR mismatched types
     }
 
     loop {
-        |_: [_; continue]| {} //~ ERROR: `continue` outside of loop
+        |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop
         //~^ ERROR mismatched types
     }
 }
diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr
index 0e0dc8f623e..45f529bafe7 100644
--- a/src/test/ui/array-break-length.stderr
+++ b/src/test/ui/array-break-length.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/array-break-length.rs:3:17
    |
 LL |         |_: [_; break]| {}
-   |                 ^^^^^ cannot break outside of a loop
+   |                 ^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/array-break-length.rs:8:17
    |
 LL |         |_: [_; continue]| {}
-   |                 ^^^^^^^^ cannot break outside of a loop
+   |                 ^^^^^^^^ cannot `continue` outside of a loop
 
 error[E0308]: mismatched types
   --> $DIR/array-break-length.rs:3:9
diff --git a/src/test/ui/async-await/argument-patterns.rs b/src/test/ui/async-await/argument-patterns.rs
index 3750c2bcb70..0e42f48b835 100644
--- a/src/test/ui/async-await/argument-patterns.rs
+++ b/src/test/ui/async-await/argument-patterns.rs
@@ -3,7 +3,6 @@
 
 #![allow(unused_variables)]
 #![deny(unused_mut)]
-#![feature(async_await)]
 
 type A = Vec<u32>;
 
diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs
index 8a15eb8c573..bf8bf0bcce0 100644
--- a/src/test/ui/async-await/async-await.rs
+++ b/src/test/ui/async-await/async-await.rs
@@ -3,8 +3,6 @@
 // edition:2018
 // aux-build:arc_wake.rs
 
-#![feature(async_await)]
-
 extern crate arc_wake;
 
 use std::pin::Pin;
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
index 4ddcdcac822..753a4e49155 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
@@ -6,8 +6,6 @@
 // edition:2018
 // ignore-tidy-linelength
 
-#![feature(async_await)]
-
 fn main() {}
 
 use core::future::Future;
@@ -32,14 +30,14 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
 
 fn no_break_in_async_block() {
     async {
-        break 0u8; //~ ERROR `break` inside of an async block
+        break 0u8; //~ ERROR `break` inside of an `async` block
     };
 }
 
 fn no_break_in_async_block_even_with_outer_loop() {
     loop {
         async {
-            break 0u8; //~ ERROR `break` inside of an async block
+            break 0u8; //~ ERROR `break` inside of an `async` block
         };
     }
 }
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index a0a5ac63d84..c36caa5586f 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -1,17 +1,25 @@
-error[E0267]: `break` inside of an async block
-  --> $DIR/async-block-control-flow-static-semantics.rs:35:9
+error[E0267]: `break` inside of an `async` block
+  --> $DIR/async-block-control-flow-static-semantics.rs:33:9
    |
-LL |         break 0u8;
-   |         ^^^^^^^^^ cannot break inside of an async block
+LL |       async {
+   |  ___________-
+LL | |         break 0u8;
+   | |         ^^^^^^^^^ cannot `break` inside of an `async` block
+LL | |     };
+   | |_____- enclosing `async` block
 
-error[E0267]: `break` inside of an async block
-  --> $DIR/async-block-control-flow-static-semantics.rs:42:13
+error[E0267]: `break` inside of an `async` block
+  --> $DIR/async-block-control-flow-static-semantics.rs:40:13
    |
-LL |             break 0u8;
-   |             ^^^^^^^^^ cannot break inside of an async block
+LL |           async {
+   |  _______________-
+LL | |             break 0u8;
+   | |             ^^^^^^^^^ cannot `break` inside of an `async` block
+LL | |         };
+   | |_________- enclosing `async` block
 
 error[E0308]: mismatched types
-  --> $DIR/async-block-control-flow-static-semantics.rs:15:43
+  --> $DIR/async-block-control-flow-static-semantics.rs:13:43
    |
 LL | fn return_targets_async_block_not_fn() -> u8 {
    |    ---------------------------------      ^^ expected u8, found ()
@@ -22,7 +30,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
               found type `()`
 
 error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
-  --> $DIR/async-block-control-flow-static-semantics.rs:20:39
+  --> $DIR/async-block-control-flow-static-semantics.rs:18:39
    |
 LL |     let _: &dyn Future<Output = ()> = &block;
    |                                       ^^^^^^ expected u8, found ()
@@ -32,7 +40,7 @@ LL |     let _: &dyn Future<Output = ()> = &block;
    = note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
 
 error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
-  --> $DIR/async-block-control-flow-static-semantics.rs:29:39
+  --> $DIR/async-block-control-flow-static-semantics.rs:27:39
    |
 LL |     let _: &dyn Future<Output = ()> = &block;
    |                                       ^^^^^^ expected u8, found ()
@@ -42,7 +50,7 @@ LL |     let _: &dyn Future<Output = ()> = &block;
    = note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
 
 error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == u8`
-  --> $DIR/async-block-control-flow-static-semantics.rs:24:55
+  --> $DIR/async-block-control-flow-static-semantics.rs:22:55
    |
 LL | async fn return_targets_async_block_not_async_fn() -> u8 {
    |                                                       ^^ expected (), found u8
@@ -52,7 +60,7 @@ LL | async fn return_targets_async_block_not_async_fn() -> u8 {
    = note: the return type of a function must have a statically known size
 
 error[E0308]: mismatched types
-  --> $DIR/async-block-control-flow-static-semantics.rs:50:44
+  --> $DIR/async-block-control-flow-static-semantics.rs:48:44
    |
 LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
    |    ----------------------------------      ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
@@ -63,7 +71,7 @@ LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
               found type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/async-block-control-flow-static-semantics.rs:59:50
+  --> $DIR/async-block-control-flow-static-semantics.rs:57:50
    |
 LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
    |    ----------------------------------------      ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
diff --git a/src/test/ui/async-await/async-closure-matches-expr.rs b/src/test/ui/async-await/async-closure-matches-expr.rs
index 1c192a4d1d8..d82fbcdc550 100644
--- a/src/test/ui/async-await/async-closure-matches-expr.rs
+++ b/src/test/ui/async-await/async-closure-matches-expr.rs
@@ -1,7 +1,7 @@
 // build-pass
 // edition:2018
 
-#![feature(async_await, async_closure)]
+#![feature(async_closure)]
 
 macro_rules! match_expr {
     ($x:expr) => {}
diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs
index 925b54b3985..9a24bd8c954 100644
--- a/src/test/ui/async-await/async-closure.rs
+++ b/src/test/ui/async-await/async-closure.rs
@@ -3,7 +3,7 @@
 // edition:2018
 // aux-build:arc_wake.rs
 
-#![feature(async_await, async_closure)]
+#![feature(async_closure)]
 
 extern crate arc_wake;
 
diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs
index d362348a3fd..dec3ac0f685 100644
--- a/src/test/ui/async-await/async-error-span.rs
+++ b/src/test/ui/async-await/async-error-span.rs
@@ -1,7 +1,6 @@
 // edition:2018
-#![feature(async_await)]
 
-// Regression test for issue #62382
+// Regression test for issue #62382.
 
 use std::future::Future;
 
diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr
index bd8966b9c7d..47441f5e4ef 100644
--- a/src/test/ui/async-await/async-error-span.stderr
+++ b/src/test/ui/async-await/async-error-span.stderr
@@ -1,11 +1,11 @@
 error[E0698]: type inside `async` object must be known in this context
-  --> $DIR/async-error-span.rs:13:9
+  --> $DIR/async-error-span.rs:12:9
    |
 LL |     let a;
    |         ^ cannot infer type
    |
 note: the type is part of the `async` object because of this `await`
-  --> $DIR/async-error-span.rs:14:5
+  --> $DIR/async-error-span.rs:13:5
    |
 LL |     get_future().await;
    |     ^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs b/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs
index 1cbc5133a07..1c369fd7415 100644
--- a/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs
+++ b/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs
@@ -6,8 +6,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 struct Foo<'a>(&'a u8);
 
 impl Foo<'_> {
diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs
index 612c1e29d82..1f1bf4250ea 100644
--- a/src/test/ui/async-await/async-fn-nonsend.rs
+++ b/src/test/ui/async-await/async-fn-nonsend.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 use std::{
     cell::RefCell,
     fmt::Debug,
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 7776a36a28f..6b4fff2dc68 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:52:5
+  --> $DIR/async-fn-nonsend.rs:50:5
    |
 LL |     assert_send(local_dropped_before_await());
    |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -7,18 +7,18 @@ LL |     assert_send(local_dropped_before_await());
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `impl std::fmt::Debug`
    = note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:49:1
+  --> $DIR/async-fn-nonsend.rs:47:1
    |
 LL | fn assert_send(_: impl Send) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:54:5
+  --> $DIR/async-fn-nonsend.rs:52:5
    |
 LL |     assert_send(non_send_temporary_in_match());
    |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -26,18 +26,18 @@ LL |     assert_send(non_send_temporary_in_match());
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `impl std::fmt::Debug`
    = note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:49:1
+  --> $DIR/async-fn-nonsend.rs:47:1
    |
 LL | fn assert_send(_: impl Send) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:56:5
+  --> $DIR/async-fn-nonsend.rs:54:5
    |
 LL |     assert_send(non_sync_with_method_call());
    |     ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely
@@ -47,18 +47,18 @@ LL |     assert_send(non_sync_with_method_call());
    = note: required because it appears within the type `std::fmt::Formatter<'_>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
    = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:49:1
+  --> $DIR/async-fn-nonsend.rs:47:1
    |
 LL | fn assert_send(_: impl Send) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
-  --> $DIR/async-fn-nonsend.rs:56:5
+  --> $DIR/async-fn-nonsend.rs:54:5
    |
 LL |     assert_send(non_sync_with_method_call());
    |     ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
@@ -72,12 +72,12 @@ LL |     assert_send(non_sync_with_method_call());
    = note: required because it appears within the type `std::fmt::Formatter<'_>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
    = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:49:1
+  --> $DIR/async-fn-nonsend.rs:47:1
    |
 LL | fn assert_send(_: impl Send) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/async-await/async-fn-path-elision.rs b/src/test/ui/async-await/async-fn-path-elision.rs
index 447e40dddd9..3f1f51c20ca 100644
--- a/src/test/ui/async-await/async-fn-path-elision.rs
+++ b/src/test/ui/async-await/async-fn-path-elision.rs
@@ -1,8 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-#![allow(dead_code)]
-
 struct HasLifetime<'a>(&'a bool);
 
 async fn error(lt: HasLifetime) { //~ ERROR implicit elided lifetime not allowed here
diff --git a/src/test/ui/async-await/async-fn-path-elision.stderr b/src/test/ui/async-await/async-fn-path-elision.stderr
index 3b311baba01..9694742200e 100644
--- a/src/test/ui/async-await/async-fn-path-elision.stderr
+++ b/src/test/ui/async-await/async-fn-path-elision.stderr
@@ -1,5 +1,5 @@
 error[E0726]: implicit elided lifetime not allowed here
-  --> $DIR/async-fn-path-elision.rs:8:20
+  --> $DIR/async-fn-path-elision.rs:5:20
    |
 LL | async fn error(lt: HasLifetime) {
    |                    ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
diff --git a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs
index 5e1b8c6280b..35d9cb15540 100644
--- a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs
+++ b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 use std::{
     cell::RefCell,
     fmt::Debug,
diff --git a/src/test/ui/async-await/async-fn-size-moved-locals.rs b/src/test/ui/async-await/async-fn-size-moved-locals.rs
index 30b59d037d5..3ffcbb58595 100644
--- a/src/test/ui/async-await/async-fn-size-moved-locals.rs
+++ b/src/test/ui/async-await/async-fn-size-moved-locals.rs
@@ -12,8 +12,6 @@
 
 // edition:2018
 
-#![feature(async_await)]
-
 use std::future::Future;
 use std::pin::Pin;
 use std::task::{Context, Poll};
diff --git a/src/test/ui/async-await/async-fn-size.rs b/src/test/ui/async-await/async-fn-size.rs
index c6b2ed13b0a..b5c94ecb716 100644
--- a/src/test/ui/async-await/async-fn-size.rs
+++ b/src/test/ui/async-await/async-fn-size.rs
@@ -2,8 +2,6 @@
 // aux-build:arc_wake.rs
 // edition:2018
 
-#![feature(async_await)]
-
 extern crate arc_wake;
 
 use std::pin::Pin;
diff --git a/src/test/ui/async-await/async-matches-expr.rs b/src/test/ui/async-await/async-matches-expr.rs
index a6f0211e41f..299faa0587b 100644
--- a/src/test/ui/async-await/async-matches-expr.rs
+++ b/src/test/ui/async-await/async-matches-expr.rs
@@ -1,8 +1,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 macro_rules! match_expr {
     ($x:expr) => {}
 }
diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs
index cb9156dcc6e..ccc1b8553f0 100644
--- a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs
+++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 struct S;
 
 impl S {
diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr
index d22413beecb..c95fe173488 100644
--- a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr
+++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr
@@ -1,5 +1,5 @@
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:12:5
    |
 LL |     S::f();
    |     ^^^^^^ call to unsafe function
@@ -7,7 +7,7 @@ LL |     S::f();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/async-unsafe-fn-call-in-safe.rs:15:5
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:13:5
    |
 LL |     f();
    |     ^^^ call to unsafe function
@@ -15,7 +15,7 @@ LL |     f();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/async-unsafe-fn-call-in-safe.rs:19:5
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:17:5
    |
 LL |     S::f();
    |     ^^^^^^ call to unsafe function
@@ -23,7 +23,7 @@ LL |     S::f();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/async-unsafe-fn-call-in-safe.rs:20:5
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:18:5
    |
 LL |     f();
    |     ^^^ call to unsafe function
diff --git a/src/test/ui/async-await/async-with-closure.rs b/src/test/ui/async-await/async-with-closure.rs
index f7dc874affd..0b225526675 100644
--- a/src/test/ui/async-await/async-with-closure.rs
+++ b/src/test/ui/async-await/async-with-closure.rs
@@ -1,8 +1,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 trait MyClosure {
     type Args;
 }
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs
index 422a5a6394f..a3a20cb97e1 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs
+++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs
@@ -1,4 +1,3 @@
-#![feature(async_await)]
 #![allow(non_camel_case_types)]
 #![deny(keyword_idents)]
 
diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
index 8af0110169e..f1a22cda51b 100644
--- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
+++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr
@@ -1,11 +1,11 @@
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:6:13
+  --> $DIR/2015-edition-error-various-positions.rs:5:13
    |
 LL |     pub mod await {
    |             ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
    |
 note: lint level defined here
-  --> $DIR/2015-edition-error-various-positions.rs:3:9
+  --> $DIR/2015-edition-error-various-positions.rs:2:9
    |
 LL | #![deny(keyword_idents)]
    |         ^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL | #![deny(keyword_idents)]
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:8:20
+  --> $DIR/2015-edition-error-various-positions.rs:7:20
    |
 LL |         pub struct await;
    |                    ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -22,7 +22,7 @@ LL |         pub struct await;
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:12:16
+  --> $DIR/2015-edition-error-various-positions.rs:11:16
    |
 LL | use outer_mod::await::await;
    |                ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -31,7 +31,7 @@ LL | use outer_mod::await::await;
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:12:23
+  --> $DIR/2015-edition-error-various-positions.rs:11:23
    |
 LL | use outer_mod::await::await;
    |                       ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -40,7 +40,7 @@ LL | use outer_mod::await::await;
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:17:14
+  --> $DIR/2015-edition-error-various-positions.rs:16:14
    |
 LL | struct Foo { await: () }
    |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -49,7 +49,7 @@ LL | struct Foo { await: () }
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:21:15
+  --> $DIR/2015-edition-error-various-positions.rs:20:15
    |
 LL | impl Foo { fn await() {} }
    |               ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -58,7 +58,7 @@ LL | impl Foo { fn await() {} }
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:25:14
+  --> $DIR/2015-edition-error-various-positions.rs:24:14
    |
 LL | macro_rules! await {
    |              ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -67,7 +67,7 @@ LL | macro_rules! await {
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:32:5
+  --> $DIR/2015-edition-error-various-positions.rs:31:5
    |
 LL |     await!();
    |     ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -76,7 +76,7 @@ LL |     await!();
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:35:11
+  --> $DIR/2015-edition-error-various-positions.rs:34:11
    |
 LL |     match await { await => {} }
    |           ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
@@ -85,7 +85,7 @@ LL |     match await { await => {} }
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
 error: `await` is a keyword in the 2018 edition
-  --> $DIR/2015-edition-error-various-positions.rs:35:19
+  --> $DIR/2015-edition-error-various-positions.rs:34:19
    |
 LL |     match await { await => {} }
    |                   ^^^^^ help: you can use a raw identifier to stay compatible: `r#await`
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
index 92f3210ac89..5d85b0a243e 100644
--- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
+++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs
@@ -1,7 +1,6 @@
 // edition:2018
 
 #![allow(non_camel_case_types)]
-#![feature(async_await)]
 
 mod outer_mod {
     pub mod await { //~ ERROR expected identifier, found reserved keyword `await`
diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
index c4b82b29f02..05f28d0a5b2 100644
--- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
+++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:7:13
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:6:13
    |
 LL |     pub mod await {
    |             ^^^^^ expected identifier, found reserved keyword
@@ -9,7 +9,7 @@ LL |     pub mod r#await {
    |             ^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:8:20
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:7:20
    |
 LL |         pub struct await;
    |                    ^^^^^ expected identifier, found reserved keyword
@@ -19,7 +19,7 @@ LL |         pub struct r#await;
    |                    ^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:22
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:10:22
    |
 LL | use self::outer_mod::await::await;
    |                      ^^^^^ expected identifier, found reserved keyword
@@ -29,7 +29,7 @@ LL | use self::outer_mod::r#await::await;
    |                      ^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:11:29
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:10:29
    |
 LL | use self::outer_mod::await::await;
    |                             ^^^^^ expected identifier, found reserved keyword
@@ -39,7 +39,7 @@ LL | use self::outer_mod::await::r#await;
    |                             ^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:14:14
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:13:14
    |
 LL | struct Foo { await: () }
    |              ^^^^^ expected identifier, found reserved keyword
@@ -49,7 +49,7 @@ LL | struct Foo { r#await: () }
    |              ^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:17:15
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:16:15
    |
 LL | impl Foo { fn await() {} }
    |               ^^^^^ expected identifier, found reserved keyword
@@ -59,7 +59,7 @@ LL | impl Foo { fn r#await() {} }
    |               ^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/2018-edition-error-in-non-macro-position.rs:20:14
+  --> $DIR/2018-edition-error-in-non-macro-position.rs:19:14
    |
 LL | macro_rules! await {
    |              ^^^^^ expected identifier, found reserved keyword
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
index 25da337c587..22bcbb1064d 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 async fn bar() -> Result<(), ()> {
     Ok(())
 }
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 db86d3d5d03..7caa9f26bc2 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
@@ -1,119 +1,119 @@
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:10:13
+  --> $DIR/incorrect-syntax-suggestions.rs:8:13
    |
 LL |     let _ = await bar();
    |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:14:13
+  --> $DIR/incorrect-syntax-suggestions.rs:12:13
    |
 LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:18:13
+  --> $DIR/incorrect-syntax-suggestions.rs:16:13
    |
 LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:23:13
+  --> $DIR/incorrect-syntax-suggestions.rs:21:13
    |
 LL |     let _ = await { bar() };
    |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:27:13
+  --> $DIR/incorrect-syntax-suggestions.rs:25:13
    |
 LL |     let _ = await(bar());
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:31:13
+  --> $DIR/incorrect-syntax-suggestions.rs:29:13
    |
 LL |     let _ = await { bar() }?;
    |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:35:14
+  --> $DIR/incorrect-syntax-suggestions.rs:33:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:39:24
+  --> $DIR/incorrect-syntax-suggestions.rs:37:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:43:24
+  --> $DIR/incorrect-syntax-suggestions.rs:41:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:55:13
+  --> $DIR/incorrect-syntax-suggestions.rs:53:13
    |
 LL |     let _ = await bar();
    |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:60:13
+  --> $DIR/incorrect-syntax-suggestions.rs:58:13
    |
 LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:65:13
+  --> $DIR/incorrect-syntax-suggestions.rs:63:13
    |
 LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:70:14
+  --> $DIR/incorrect-syntax-suggestions.rs:68:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:75:24
+  --> $DIR/incorrect-syntax-suggestions.rs:73:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:80:24
+  --> $DIR/incorrect-syntax-suggestions.rs:78:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:108:13
+  --> $DIR/incorrect-syntax-suggestions.rs:106:13
    |
 LL |     let _ = await!(bar());
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:112:13
+  --> $DIR/incorrect-syntax-suggestions.rs:110:13
    |
 LL |     let _ = await!(bar())?;
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:117:17
+  --> $DIR/incorrect-syntax-suggestions.rs:115:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:125:17
+  --> $DIR/incorrect-syntax-suggestions.rs:123:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: expected expression, found `=>`
-  --> $DIR/incorrect-syntax-suggestions.rs:133:25
+  --> $DIR/incorrect-syntax-suggestions.rs:131:25
    |
 LL |     match await { await => () }
    |                   ----- ^^ expected expression
@@ -121,13 +121,13 @@ LL |     match await { await => () }
    |                   while parsing this incorrect await expression
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:133:11
+  --> $DIR/incorrect-syntax-suggestions.rs:131:11
    |
 LL |     match await { await => () }
    |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
 
 error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/incorrect-syntax-suggestions.rs:136:1
+  --> $DIR/incorrect-syntax-suggestions.rs:134:1
    |
 LL |     match await { await => () }
    |     -----                      - expected one of `.`, `?`, `{`, or an operator here
@@ -138,7 +138,7 @@ LL | }
    | ^ unexpected token
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:55:13
+  --> $DIR/incorrect-syntax-suggestions.rs:53:13
    |
 LL | fn foo9() -> Result<(), ()> {
    |    ---- this is not `async`
@@ -146,7 +146,7 @@ LL |     let _ = await bar();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:60:13
+  --> $DIR/incorrect-syntax-suggestions.rs:58:13
    |
 LL | fn foo10() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -154,7 +154,7 @@ LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:65:13
+  --> $DIR/incorrect-syntax-suggestions.rs:63:13
    |
 LL | fn foo11() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -162,7 +162,7 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:70:14
+  --> $DIR/incorrect-syntax-suggestions.rs:68:14
    |
 LL | fn foo12() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -170,7 +170,7 @@ LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:75:13
+  --> $DIR/incorrect-syntax-suggestions.rs:73:13
    |
 LL | fn foo13() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -178,7 +178,7 @@ LL |     let _ = bar().await();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:80:13
+  --> $DIR/incorrect-syntax-suggestions.rs:78:13
    |
 LL | fn foo14() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -186,7 +186,7 @@ LL |     let _ = bar().await()?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:85:13
+  --> $DIR/incorrect-syntax-suggestions.rs:83:13
    |
 LL | fn foo15() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -194,7 +194,7 @@ LL |     let _ = bar().await;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:89:13
+  --> $DIR/incorrect-syntax-suggestions.rs:87:13
    |
 LL | fn foo16() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -202,7 +202,7 @@ LL |     let _ = bar().await?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:94:17
+  --> $DIR/incorrect-syntax-suggestions.rs:92:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -210,7 +210,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:101:17
+  --> $DIR/incorrect-syntax-suggestions.rs:99:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
@@ -218,7 +218,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:117:17
+  --> $DIR/incorrect-syntax-suggestions.rs:115:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -226,7 +226,7 @@ LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:125:17
+  --> $DIR/incorrect-syntax-suggestions.rs:123:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
@@ -234,7 +234,7 @@ LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/incorrect-syntax-suggestions.rs:18:19
+  --> $DIR/incorrect-syntax-suggestions.rs:16:19
    |
 LL |     let _ = await bar()?;
    |                   ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
diff --git a/src/test/ui/async-await/await-unsize.rs b/src/test/ui/async-await/await-unsize.rs
index d5e21257f4f..aa09d4bdf08 100644
--- a/src/test/ui/async-await/await-unsize.rs
+++ b/src/test/ui/async-await/await-unsize.rs
@@ -3,8 +3,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 async fn make_boxed_object() -> Box<dyn Send> {
     Box::new(()) as _
 }
diff --git a/src/test/ui/async-await/bound-normalization.rs b/src/test/ui/async-await/bound-normalization.rs
index 8026350aaf2..5d260682f1d 100644
--- a/src/test/ui/async-await/bound-normalization.rs
+++ b/src/test/ui/async-await/bound-normalization.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 // See issue 60414
 
 trait Trait {
diff --git a/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs b/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs
index a5947e7f718..56f4cbbd190 100644
--- a/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs
+++ b/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 async fn conditional_and_guaranteed_initialization(x: usize) -> usize {
     let y;
     if x > 5 {
diff --git a/src/test/ui/async-await/dont-print-desugared-async.rs b/src/test/ui/async-await/dont-print-desugared-async.rs
index 8150a260866..68341a24c4e 100644
--- a/src/test/ui/async-await/dont-print-desugared-async.rs
+++ b/src/test/ui/async-await/dont-print-desugared-async.rs
@@ -1,7 +1,6 @@
 // Test that we don't show variables with from async fn desugaring
 
 // edition:2018
-#![feature(async_await)]
 
 async fn async_fn(&ref mut s: &[i32]) {}
 //~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
diff --git a/src/test/ui/async-await/dont-print-desugared-async.stderr b/src/test/ui/async-await/dont-print-desugared-async.stderr
index 47726ba65df..2bf1e77f09b 100644
--- a/src/test/ui/async-await/dont-print-desugared-async.stderr
+++ b/src/test/ui/async-await/dont-print-desugared-async.stderr
@@ -1,5 +1,5 @@
 error[E0596]: cannot borrow data in a `&` reference as mutable
-  --> $DIR/dont-print-desugared-async.rs:6:20
+  --> $DIR/dont-print-desugared-async.rs:5:20
    |
 LL | async fn async_fn(&ref mut s: &[i32]) {}
    |                   -^^^^^^^^^
diff --git a/src/test/ui/async-await/dont-suggest-missing-await.rs b/src/test/ui/async-await/dont-suggest-missing-await.rs
index d551ef57985..a8e5b38ec1d 100644
--- a/src/test/ui/async-await/dont-suggest-missing-await.rs
+++ b/src/test/ui/async-await/dont-suggest-missing-await.rs
@@ -2,8 +2,6 @@
 
 // This test ensures we don't make the suggestion in bodies that aren't `async`.
 
-#![feature(async_await)]
-
 fn take_u32(x: u32) {}
 
 async fn make_u32() -> u32 {
diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr
index c60b0d1f30e..c87e0bc221d 100644
--- a/src/test/ui/async-await/dont-suggest-missing-await.stderr
+++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/dont-suggest-missing-await.rs:16:18
+  --> $DIR/dont-suggest-missing-await.rs:14:18
    |
 LL |         take_u32(x)
    |                  ^ expected u32, found opaque type
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
index dfd8b2e361e..9817d377a78 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs
@@ -3,7 +3,6 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(async_await)]
 
 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
 // parameters (used or unused) are not dropped until the async fn completes execution.
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
index 2a74485afb4..00072786a50 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs
@@ -3,7 +3,6 @@
 // run-pass
 
 #![allow(unused_variables)]
-#![feature(async_await)]
 
 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
 // parameters (used or unused) are not dropped until the async fn completes execution.
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
index db396d3957e..5d020c9a526 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
@@ -2,9 +2,7 @@
 // edition:2018
 // run-pass
 
-#![allow(unused_variables)]
 #![deny(dead_code)]
-#![feature(async_await)]
 
 // Test that the drop order for locals in a fn and async fn matches up.
 extern crate arc_wake;
diff --git a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs
index bcdb8878eb5..79dedb1ba28 100644
--- a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs
@@ -1,8 +1,5 @@
 // edition:2018
 
-#![allow(unused_variables)]
-#![feature(async_await)]
-
 async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) {
     assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425]
     assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425]
diff --git a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr
index 484e1f4f426..aa04a613f47 100644
--- a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr
+++ b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr
@@ -1,23 +1,23 @@
 error[E0425]: cannot find value `__arg1` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:7:16
+  --> $DIR/drop-order-locals-are-hidden.rs:4:16
    |
 LL |     assert_eq!(__arg1, (1, 2, 3));
    |                ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `__arg2` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:8:16
+  --> $DIR/drop-order-locals-are-hidden.rs:5:16
    |
 LL |     assert_eq!(__arg2, 4);
    |                ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `__arg0` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:12:16
+  --> $DIR/drop-order-locals-are-hidden.rs:9:16
    |
 LL |     assert_eq!(__arg0, 1);
    |                ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `__arg1` in this scope
-  --> $DIR/drop-order-locals-are-hidden.rs:13:16
+  --> $DIR/drop-order-locals-are-hidden.rs:10:16
    |
 LL |     assert_eq!(__arg1, 2);
    |                ^^^^^^ not found in this scope
diff --git a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs
index 410a623681d..84fe79348c6 100644
--- a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs
@@ -2,9 +2,6 @@
 // edition:2018
 // run-pass
 
-#![allow(unused_variables)]
-#![feature(async_await)]
-
 // Test that the drop order for parameters in a fn and async fn matches up. Also test that
 // parameters (used or unused) are not dropped until the async fn is cancelled.
 // This file is mostly copy-pasted from drop-order-for-async-fn-parameters.rs
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
index a5bc1810154..c85896150c2 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs
@@ -1,7 +1,5 @@
 // edition:2015
 
-#![feature(async_await)]
-
 async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
 
 fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in the 2015 edition
diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
index efb4462095d..d3f88af09d1 100644
--- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
+++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr
@@ -1,59 +1,59 @@
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:5:1
+  --> $DIR/edition-deny-async-fns-2015.rs:3:1
    |
 LL | async fn foo() {}
    | ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:7:12
+  --> $DIR/edition-deny-async-fns-2015.rs:5:12
    |
 LL | fn baz() { async fn foo() {} }
    |            ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:10:5
+  --> $DIR/edition-deny-async-fns-2015.rs:8:5
    |
 LL |     async fn bar() {}
    |     ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:9:1
+  --> $DIR/edition-deny-async-fns-2015.rs:7:1
    |
 LL | async fn async_baz() {
    | ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:16:5
+  --> $DIR/edition-deny-async-fns-2015.rs:14:5
    |
 LL |     async fn foo() {}
    |     ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+  --> $DIR/edition-deny-async-fns-2015.rs:18:5
    |
 LL |     async fn foo() {}
    |     ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:38:9
+  --> $DIR/edition-deny-async-fns-2015.rs:36:9
    |
 LL |         async fn bar() {}
    |         ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:28:9
+  --> $DIR/edition-deny-async-fns-2015.rs:26:9
    |
 LL |         async fn foo() {}
    |         ^^^^^
 
 error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/edition-deny-async-fns-2015.rs:33:13
+  --> $DIR/edition-deny-async-fns-2015.rs:31:13
    |
 LL |             async fn bar() {}
    |             ^^^^^
 
 error[E0706]: trait fns cannot be declared `async`
-  --> $DIR/edition-deny-async-fns-2015.rs:20:5
+  --> $DIR/edition-deny-async-fns-2015.rs:18:5
    |
 LL |     async fn foo() {}
    |     ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs
index 8b60f2f82f1..963b19b34a6 100644
--- a/src/test/ui/async-await/generics-and-bounds.rs
+++ b/src/test/ui/async-await/generics-and-bounds.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 use std::future::Future;
 
 pub async fn simple_generic<T>() {}
diff --git a/src/test/ui/async-await/issue-60709.rs b/src/test/ui/async-await/issue-60709.rs
index ad0b49fa4a2..9ee419c4a56 100644
--- a/src/test/ui/async-await/issue-60709.rs
+++ b/src/test/ui/async-await/issue-60709.rs
@@ -4,9 +4,6 @@
 
 // run-pass
 
-#![feature(async_await)]
-#![allow(unused)]
-
 use std::future::Future;
 use std::task::Poll;
 use std::task::Context;
diff --git a/src/test/ui/async-await/issue-61452.rs b/src/test/ui/async-await/issue-61452.rs
index 20b9b645dae..9381251ad69 100644
--- a/src/test/ui/async-await/issue-61452.rs
+++ b/src/test/ui/async-await/issue-61452.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(async_await)]
 
 pub async fn f(x: Option<usize>) {
     x.take();
diff --git a/src/test/ui/async-await/issue-61452.stderr b/src/test/ui/async-await/issue-61452.stderr
index 742490d8de4..5eb4b548717 100644
--- a/src/test/ui/async-await/issue-61452.stderr
+++ b/src/test/ui/async-await/issue-61452.stderr
@@ -1,5 +1,5 @@
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/issue-61452.rs:5:5
+  --> $DIR/issue-61452.rs:4:5
    |
 LL | pub async fn f(x: Option<usize>) {
    |                - help: consider changing this to be mutable: `mut x`
@@ -7,7 +7,7 @@ LL |     x.take();
    |     ^ cannot borrow as mutable
 
 error[E0384]: cannot assign twice to immutable variable `x`
-  --> $DIR/issue-61452.rs:10:5
+  --> $DIR/issue-61452.rs:9:5
    |
 LL | pub async fn g(x: usize) {
    |                -
diff --git a/src/test/ui/async-await/issue-61793.rs b/src/test/ui/async-await/issue-61793.rs
index a18fad8bb91..f6084be9167 100644
--- a/src/test/ui/async-await/issue-61793.rs
+++ b/src/test/ui/async-await/issue-61793.rs
@@ -6,9 +6,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-#![allow(unused)]
-
 async fn foo<F>(_: &(), _: F) {}
 
 fn main() {
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs
index c5a66d5d4a3..6a28c69193d 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.rs
+++ b/src/test/ui/async-await/issue-61949-self-return-type.rs
@@ -1,6 +1,5 @@
 // ignore-tidy-linelength
 // edition:2018
-#![feature(async_await)]
 
 // This test checks that `Self` is prohibited as a return type. See #61949 for context.
 
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr
index a9ae544502d..12fb77d8dd6 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.stderr
+++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr
@@ -1,5 +1,5 @@
 error: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/issue-61949-self-return-type.rs:12:40
+  --> $DIR/issue-61949-self-return-type.rs:11:40
    |
 LL |     pub async fn new(_bar: &'a i32) -> Self {
    |                                        ^^^^
diff --git a/src/test/ui/async-await/issue-62658.rs b/src/test/ui/async-await/issue-62658.rs
index 90fbb47bffd..d0af01e0c00 100644
--- a/src/test/ui/async-await/issue-62658.rs
+++ b/src/test/ui/async-await/issue-62658.rs
@@ -4,8 +4,6 @@
 // build-pass
 // edition:2018
 
-#![feature(async_await)]
-
 async fn noop() {}
 
 async fn foo() {
diff --git a/src/test/ui/async-await/issues/issue-51719.rs b/src/test/ui/async-await/issues/issue-51719.rs
index 361a49c2774..09241f982aa 100644
--- a/src/test/ui/async-await/issues/issue-51719.rs
+++ b/src/test/ui/async-await/issues/issue-51719.rs
@@ -2,8 +2,6 @@
 //
 // Tests that the .await syntax can't be used to make a generator
 
-#![feature(async_await)]
-
 async fn foo() {}
 
 fn make_generator() {
diff --git a/src/test/ui/async-await/issues/issue-51719.stderr b/src/test/ui/async-await/issues/issue-51719.stderr
index 2a9fb6cf0df..6c3c8889da7 100644
--- a/src/test/ui/async-await/issues/issue-51719.stderr
+++ b/src/test/ui/async-await/issues/issue-51719.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-51719.rs:10:19
+  --> $DIR/issue-51719.rs:8:19
    |
 LL |     let _gen = || foo().await;
    |                -- ^^^^^^^^^^^ only allowed inside `async` functions and blocks
diff --git a/src/test/ui/async-await/issues/issue-51751.rs b/src/test/ui/async-await/issues/issue-51751.rs
index 7afd7ecc826..bc85a96cea9 100644
--- a/src/test/ui/async-await/issues/issue-51751.rs
+++ b/src/test/ui/async-await/issues/issue-51751.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 async fn inc(limit: i64) -> i64 {
     limit + 1
 }
diff --git a/src/test/ui/async-await/issues/issue-51751.stderr b/src/test/ui/async-await/issues/issue-51751.stderr
index 97b63d1590e..e50c78534f8 100644
--- a/src/test/ui/async-await/issues/issue-51751.stderr
+++ b/src/test/ui/async-await/issues/issue-51751.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-51751.rs:11:20
+  --> $DIR/issue-51751.rs:9:20
    |
 LL | fn main() {
    |    ---- this is not `async`
diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs
index c57dc6b0ef6..5cae0704444 100644
--- a/src/test/ui/async-await/issues/issue-53249.rs
+++ b/src/test/ui/async-await/issues/issue-53249.rs
@@ -1,7 +1,7 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(arbitrary_self_types, async_await)]
+#![feature(arbitrary_self_types)]
 
 use std::task::{self, Poll};
 use std::future::Future;
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 0036de90b25..64f260cfe01 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
@@ -3,7 +3,4 @@
 // edition:2018
 // pp-exact
 
-#![feature(async_await)]
-#![allow(unused_parens)]
-
 fn main() { let _a = (async  { }); }
diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs
index 040989b33fc..9adc0a82323 100644
--- a/src/test/ui/async-await/issues/issue-54974.rs
+++ b/src/test/ui/async-await/issues/issue-54974.rs
@@ -1,8 +1,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 use std::sync::Arc;
 
 trait SomeTrait: Send + Sync + 'static {
diff --git a/src/test/ui/async-await/issues/issue-55324.rs b/src/test/ui/async-await/issues/issue-55324.rs
index 4f383a51a88..1d77d420127 100644
--- a/src/test/ui/async-await/issues/issue-55324.rs
+++ b/src/test/ui/async-await/issues/issue-55324.rs
@@ -1,11 +1,8 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 use std::future::Future;
 
-#[allow(unused)]
 async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 {
     let y = future.await;
     *x + y
diff --git a/src/test/ui/async-await/issues/issue-55809.rs b/src/test/ui/async-await/issues/issue-55809.rs
index b7e60b773b4..3b271775a38 100644
--- a/src/test/ui/async-await/issues/issue-55809.rs
+++ b/src/test/ui/async-await/issues/issue-55809.rs
@@ -1,8 +1,6 @@
 // edition:2018
 // run-pass
 
-#![feature(async_await)]
-
 trait Foo { }
 
 impl Foo for () { }
diff --git a/src/test/ui/async-await/issues/issue-58885.rs b/src/test/ui/async-await/issues/issue-58885.rs
index 47744aeea60..72a45b5007d 100644
--- a/src/test/ui/async-await/issues/issue-58885.rs
+++ b/src/test/ui/async-await/issues/issue-58885.rs
@@ -1,8 +1,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 struct Xyz {
     a: u64,
 }
diff --git a/src/test/ui/async-await/issues/issue-59001.rs b/src/test/ui/async-await/issues/issue-59001.rs
index 9334ddb0af5..ea780d9f622 100644
--- a/src/test/ui/async-await/issues/issue-59001.rs
+++ b/src/test/ui/async-await/issues/issue-59001.rs
@@ -1,11 +1,8 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 use std::future::Future;
 
-#[allow(unused)]
 async fn enter<'a, F, R>(mut callback: F)
 where
     F: FnMut(&'a mut i32) -> R,
diff --git a/src/test/ui/async-await/issues/issue-59972.rs b/src/test/ui/async-await/issues/issue-59972.rs
index 8f4254b10ce..154226e8bb8 100644
--- a/src/test/ui/async-await/issues/issue-59972.rs
+++ b/src/test/ui/async-await/issues/issue-59972.rs
@@ -6,8 +6,6 @@
 
 // compile-flags: --edition=2018
 
-#![feature(async_await)]
-
 pub enum Uninhabited { }
 
 fn uninhabited_async() -> Uninhabited {
@@ -16,14 +14,12 @@ fn uninhabited_async() -> Uninhabited {
 
 async fn noop() { }
 
-#[allow(unused)]
 async fn contains_never() {
     let error = uninhabited_async();
     noop().await;
     let error2 = error;
 }
 
-#[allow(unused)]
 async fn overlap_never() {
     let error1 = uninhabited_async();
     noop().await;
@@ -35,6 +31,4 @@ async fn overlap_never() {
 
 #[allow(unused_must_use)]
 fn main() {
-    contains_never();
-    overlap_never();
 }
diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs
index e4bdc96511e..1ca05160751 100644
--- a/src/test/ui/async-await/issues/issue-60518.rs
+++ b/src/test/ui/async-await/issues/issue-60518.rs
@@ -1,8 +1,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
-
 // This is a regression test to ensure that simple bindings (where replacement arguments aren't
 // created during async fn lowering) that have their DefId used during HIR lowering (such as impl
 // trait) are visited during def collection and thus have a DefId.
diff --git a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs
index 99213e64d16..0d015e54f8b 100644
--- a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs
+++ b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs
@@ -3,7 +3,6 @@
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
 
-#![feature(async_await)]
 #![feature(type_alias_impl_trait)]
 
 use std::future::Future;
diff --git a/src/test/ui/async-await/issues/issue-60674.rs b/src/test/ui/async-await/issues/issue-60674.rs
index 99cdcbafc76..c0e34a8df77 100644
--- a/src/test/ui/async-await/issues/issue-60674.rs
+++ b/src/test/ui/async-await/issues/issue-60674.rs
@@ -1,7 +1,6 @@
 // aux-build:issue-60674.rs
 // build-pass (FIXME(62277): could be check-pass?)
 // edition:2018
-#![feature(async_await)]
 
 // This is a regression test that ensures that `mut` patterns are not lost when provided as input
 // to a proc macro.
diff --git a/src/test/ui/async-await/issues/issue-61187.rs b/src/test/ui/async-await/issues/issue-61187.rs
index 8b939b43b8b..8585a425111 100644
--- a/src/test/ui/async-await/issues/issue-61187.rs
+++ b/src/test/ui/async-await/issues/issue-61187.rs
@@ -1,8 +1,6 @@
 // edition:2018
-#![feature(async_await)]
 
-fn main() {
-}
+fn main() {}
 
 async fn response(data: Vec<u8>) {
     data.reverse(); //~ ERROR E0596
diff --git a/src/test/ui/async-await/issues/issue-61187.stderr b/src/test/ui/async-await/issues/issue-61187.stderr
index a0314226320..4d361c824dd 100644
--- a/src/test/ui/async-await/issues/issue-61187.stderr
+++ b/src/test/ui/async-await/issues/issue-61187.stderr
@@ -1,5 +1,5 @@
 error[E0596]: cannot borrow `data` as mutable, as it is not declared as mutable
-  --> $DIR/issue-61187.rs:8:5
+  --> $DIR/issue-61187.rs:6:5
    |
 LL | async fn response(data: Vec<u8>) {
    |                   ---- help: consider changing this to be mutable: `mut data`
diff --git a/src/test/ui/async-await/issues/issue-61986.rs b/src/test/ui/async-await/issues/issue-61986.rs
index 77ecc47dfef..879bc6912fc 100644
--- a/src/test/ui/async-await/issues/issue-61986.rs
+++ b/src/test/ui/async-await/issues/issue-61986.rs
@@ -4,8 +4,6 @@
 // Tests that we properly handle StorageDead/StorageLives for temporaries
 // created in async loop bodies.
 
-#![feature(async_await)]
-
 async fn bar() -> Option<()> {
     Some(())
 }
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 ac6605bceff..3ee7ab2e9d1 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 async fn print_dur() {}
 
 fn main() {
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 2bbb6d079ea..cd155f0fc32 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:6: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:8: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:12: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:12:5: 12:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:12: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:12:5: 12:15]`
    |
    = note: required by `std::future::poll_with_tls_context`
 
diff --git a/src/test/ui/async-await/issues/issue-62009-2.rs b/src/test/ui/async-await/issues/issue-62009-2.rs
index 52b62eaa9e0..cb7336e6134 100644
--- a/src/test/ui/async-await/issues/issue-62009-2.rs
+++ b/src/test/ui/async-await/issues/issue-62009-2.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, async_closure)]
+#![feature(async_closure)]
 
 async fn print_dur() {}
 
diff --git a/src/test/ui/async-await/issues/issue-62517-1.rs b/src/test/ui/async-await/issues/issue-62517-1.rs
index 5955d9751af..4689ce36a78 100644
--- a/src/test/ui/async-await/issues/issue-62517-1.rs
+++ b/src/test/ui/async-await/issues/issue-62517-1.rs
@@ -5,8 +5,6 @@
 // edition:2018
 // check-pass
 
-#![feature(async_await)]
-
 trait FirstTrait {}
 trait SecondTrait {
     type Item: ?Sized;
diff --git a/src/test/ui/async-await/issues/issue-62517-2.rs b/src/test/ui/async-await/issues/issue-62517-2.rs
index 17fac408151..aaf28d6c132 100644
--- a/src/test/ui/async-await/issues/issue-62517-2.rs
+++ b/src/test/ui/async-await/issues/issue-62517-2.rs
@@ -5,8 +5,6 @@
 // edition:2018
 // check-pass
 
-#![feature(async_await)]
-
 trait Object {}
 
 trait Alpha<Param: ?Sized> {}
diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
index 64fd1a4a78d..22610fe54a4 100644
--- a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/issue-63388-1.rs:14:10
+  --> $DIR/issue-63388-1.rs:12:10
    |
 LL |     ) -> &dyn Foo
    |          ^^^^^^^^
@@ -7,7 +7,7 @@ LL |     ) -> &dyn Foo
    = note: hidden type `impl std::future::Future` captures lifetime '_#22r
 
 error: lifetime may not live long enough
-  --> $DIR/issue-63388-1.rs:15:5
+  --> $DIR/issue-63388-1.rs:13:5
    |
 LL |       async fn do_sth<'a>(
    |                       -- lifetime `'a` defined here
diff --git a/src/test/ui/async-await/issues/issue-63388-1.rs b/src/test/ui/async-await/issues/issue-63388-1.rs
index 80003b0d701..3cde5de2198 100644
--- a/src/test/ui/async-await/issues/issue-63388-1.rs
+++ b/src/test/ui/async-await/issues/issue-63388-1.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 struct Xyz {
     a: u64,
 }
diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr
index 5302adce5a0..a54cadb0cd2 100644
--- a/src/test/ui/async-await/issues/issue-63388-1.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-1.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/issue-63388-1.rs:14:10
+  --> $DIR/issue-63388-1.rs:12:10
    |
 LL |         &'a self, foo: &dyn Foo
    |         -------- this parameter and the return type are declared with different lifetimes...
diff --git a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
index b91cdc1b770..7781af89dea 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
@@ -1,5 +1,5 @@
 error[E0106]: missing lifetime specifier
-  --> $DIR/issue-63388-2.rs:14:10
+  --> $DIR/issue-63388-2.rs:12:10
    |
 LL |     ) -> &dyn Foo
    |          ^ help: consider using the named lifetime: `&'a`
diff --git a/src/test/ui/async-await/issues/issue-63388-2.rs b/src/test/ui/async-await/issues/issue-63388-2.rs
index ca9bbef0d50..73e7f25f97d 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.rs
+++ b/src/test/ui/async-await/issues/issue-63388-2.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 struct Xyz {
     a: u64,
 }
diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr
index 1810138dc80..1edeb3d5493 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-2.stderr
@@ -1,5 +1,5 @@
 error[E0106]: missing lifetime specifier
-  --> $DIR/issue-63388-2.rs:14:10
+  --> $DIR/issue-63388-2.rs:12:10
    |
 LL |     ) -> &dyn Foo
    |          ^ help: consider using the named lifetime: `&'a`
@@ -7,19 +7,19 @@ LL |     ) -> &dyn Foo
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
 
 error: cannot infer an appropriate lifetime
-  --> $DIR/issue-63388-2.rs:13:9
+  --> $DIR/issue-63388-2.rs:11:9
    |
 LL |         foo: &dyn Foo, bar: &'a dyn Foo
    |         ^^^ ...but this borrow...
 LL |     ) -> &dyn Foo
    |          -------- this return type evaluates to the `'static` lifetime...
    |
-note: ...can't outlive the lifetime '_ as defined on the method body at 13:14
-  --> $DIR/issue-63388-2.rs:13:14
+note: ...can't outlive the lifetime '_ as defined on the method body at 11:14
+  --> $DIR/issue-63388-2.rs:11:14
    |
 LL |         foo: &dyn Foo, bar: &'a dyn Foo
    |              ^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 13:14
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 11:14
    |
 LL |     ) -> &dyn Foo + '_
    |          ^^^^^^^^^^^^^
diff --git a/src/test/ui/async-await/issues/issue-63388-3.rs b/src/test/ui/async-await/issues/issue-63388-3.rs
index 05f23f95965..1a9822e02fa 100644
--- a/src/test/ui/async-await/issues/issue-63388-3.rs
+++ b/src/test/ui/async-await/issues/issue-63388-3.rs
@@ -1,8 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(async_await)]
-
 struct Xyz {
     a: u64,
 }
diff --git a/src/test/ui/async-await/issues/issue-63388-4.rs b/src/test/ui/async-await/issues/issue-63388-4.rs
index 0939242d7fc..58f9dacb3bc 100644
--- a/src/test/ui/async-await/issues/issue-63388-4.rs
+++ b/src/test/ui/async-await/issues/issue-63388-4.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 struct A;
 
 impl A {
diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.rs b/src/test/ui/async-await/issues/non-async-enclosing-span.rs
index 838911d9b6e..d47c2137725 100644
--- a/src/test/ui/async-await/issues/non-async-enclosing-span.rs
+++ b/src/test/ui/async-await/issues/non-async-enclosing-span.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(async_await)]
 
 async fn do_the_thing() -> u8 {
     8
diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr
index f492c1a8045..49ebf414c55 100644
--- a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr
+++ b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/non-async-enclosing-span.rs:10:13
+  --> $DIR/non-async-enclosing-span.rs:9:13
    |
 LL | fn main() {
    |    ---- this is not `async`
diff --git a/src/test/ui/async-await/move-part-await-return-rest-struct.rs b/src/test/ui/async-await/move-part-await-return-rest-struct.rs
index 9bd7a515cbd..39ea2aae563 100644
--- a/src/test/ui/async-await/move-part-await-return-rest-struct.rs
+++ b/src/test/ui/async-await/move-part-await-return-rest-struct.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 struct Small {
     x: Vec<usize>,
     y: Vec<usize>,
diff --git a/src/test/ui/async-await/move-part-await-return-rest-tuple.rs b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs
index 69eee855e75..7b958b98b41 100644
--- a/src/test/ui/async-await/move-part-await-return-rest-tuple.rs
+++ b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 async fn move_part_await_return_rest_tuple() -> Vec<usize> {
     let x = (vec![3], vec![4, 4]);
     drop(x.1);
diff --git a/src/test/ui/async-await/multiple-lifetimes/elided.rs b/src/test/ui/async-await/multiple-lifetimes/elided.rs
index 45f3170d4c3..8258e2eff52 100644
--- a/src/test/ui/async-await/multiple-lifetimes/elided.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/elided.rs
@@ -3,8 +3,6 @@
 
 // Test that we can use async fns with multiple arbitrary lifetimes.
 
-#![feature(async_await)]
-
 async fn multiple_elided_lifetimes(_: &u8, _: &u8) {}
 
 fn main() {
diff --git a/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs
index a7254cee755..3912b854747 100644
--- a/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs
@@ -3,8 +3,6 @@
 
 // Test that we can use async fns with multiple arbitrary lifetimes.
 
-#![feature(async_await)]
-
 async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8, _: fn(&u8)) {}
 
 fn gimme(_: &u8) { }
diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
index 589e260d084..31d0736ba63 100644
--- a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
@@ -3,9 +3,6 @@
 
 // Test that we can use async fns with multiple arbitrary lifetimes.
 
-#![feature(async_await)]
-#![allow(dead_code)]
-
 use std::ops::Add;
 
 async fn multiple_hrtb_and_single_named_lifetime_ok<'c>(
diff --git a/src/test/ui/async-await/multiple-lifetimes/named.rs b/src/test/ui/async-await/multiple-lifetimes/named.rs
index cd479e256b4..e8eb98102f4 100644
--- a/src/test/ui/async-await/multiple-lifetimes/named.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/named.rs
@@ -3,8 +3,6 @@
 
 // Test that we can use async fns with multiple arbitrary lifetimes.
 
-#![feature(async_await)]
-
 async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {}
 
 fn main() {
diff --git a/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs
index 903c43950a5..02b105999f5 100644
--- a/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs
@@ -1,8 +1,6 @@
 // edition:2018
 // run-pass
 
-#![feature(async_await)]
-
 async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32)
     where 'b: 'a
 {
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs
index 08622311f7b..b901b61aa18 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs
@@ -4,7 +4,7 @@
 // Test that a feature gate is needed to use `impl Trait` as the
 // return type of an async.
 
-#![feature(async_await, member_constraints)]
+#![feature(member_constraints)]
 
 trait Trait<'a, 'b> { }
 impl<T> Trait<'_, '_> for T { }
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
index 08ecea4cc85..2c7a5cd378f 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
@@ -3,8 +3,6 @@
 // Test that a feature gate is needed to use `impl Trait` as the
 // return type of an async.
 
-#![feature(async_await)]
-
 trait Trait<'a, 'b> { }
 impl<T> Trait<'_, '_> for T { }
 
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
index de2c85d772a..59d7728d41c 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
@@ -1,5 +1,5 @@
 error: ambiguous lifetime bound in `impl Trait`
-  --> $DIR/ret-impl-trait-no-fg.rs:11:64
+  --> $DIR/ret-impl-trait-no-fg.rs:9:64
    |
 LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
    |                                                                ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
index e1b71465273..babc90a5e96 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs
@@ -3,7 +3,7 @@
 // Test that a feature gate is needed to use `impl Trait` as the
 // return type of an async.
 
-#![feature(async_await, member_constraints)]
+#![feature(member_constraints)]
 
 trait Trait<'a> { }
 impl<T> Trait<'_> for T { }
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs
index 98da90161e5..149c020f9cb 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs
@@ -4,8 +4,6 @@
 // function (which takes multiple lifetimes) only returns data from
 // one of them.
 
-#![feature(async_await)]
-
 async fn multiple_named_lifetimes<'a, 'b>(a: &'a u8, _: &'b u8) -> &'a u8 {
     a
 }
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr
index fe70d35942c..d86e84033b8 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr
@@ -1,5 +1,5 @@
 error[E0506]: cannot assign to `a` because it is borrowed
-  --> $DIR/ret-ref.rs:18:5
+  --> $DIR/ret-ref.rs:16:5
    |
 LL |     let future = multiple_named_lifetimes(&a, &b);
    |                                           -- borrow of `a` occurs here
@@ -10,7 +10,7 @@ LL |     let p = future.await;
    |             ------ borrow later used here
 
 error[E0506]: cannot assign to `b` because it is borrowed
-  --> $DIR/ret-ref.rs:19:5
+  --> $DIR/ret-ref.rs:17:5
    |
 LL |     let future = multiple_named_lifetimes(&a, &b);
    |                                               -- borrow of `b` occurs here
@@ -21,7 +21,7 @@ LL |     let p = future.await;
    |             ------ borrow later used here
 
 error[E0506]: cannot assign to `a` because it is borrowed
-  --> $DIR/ret-ref.rs:30:5
+  --> $DIR/ret-ref.rs:28:5
    |
 LL |     let future = multiple_named_lifetimes(&a, &b);
    |                                           -- borrow of `a` occurs here
diff --git a/src/test/ui/async-await/multiple-lifetimes/variance.rs b/src/test/ui/async-await/multiple-lifetimes/variance.rs
index b52ad17d563..6ed8bef956a 100644
--- a/src/test/ui/async-await/multiple-lifetimes/variance.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/variance.rs
@@ -4,9 +4,6 @@
 // Test for async fn where the parameters have distinct lifetime
 // parameters that appear in all possible variances.
 
-#![feature(async_await)]
-
-#[allow(dead_code)]
 async fn lotsa_lifetimes<'a, 'b, 'c>(_: fn(&'a u8), _: fn(&'b u8) -> &'b u8, _: fn() -> &'c u8) { }
 
 fn take_any(_: &u8) { }
diff --git a/src/test/ui/async-await/nested-in-impl.rs b/src/test/ui/async-await/nested-in-impl.rs
index 3c82160595f..76ed827d597 100644
--- a/src/test/ui/async-await/nested-in-impl.rs
+++ b/src/test/ui/async-await/nested-in-impl.rs
@@ -4,8 +4,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 struct Foo<'a>(&'a ());
 
 impl<'a> Foo<'a> {
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-args-non-move-async-closure.rs
index 62d4b3fb6f2..0ca50807f26 100644
--- a/src/test/ui/async-await/no-args-non-move-async-closure.rs
+++ b/src/test/ui/async-await/no-args-non-move-async-closure.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-#![feature(async_await, async_closure)]
+#![feature(async_closure)]
 
 fn main() {
     let _ = async |x: u8| {};
diff --git a/src/test/ui/async-await/no-async-const.rs b/src/test/ui/async-await/no-async-const.rs
index 1db314a5aa2..7a6eb498b2e 100644
--- a/src/test/ui/async-await/no-async-const.rs
+++ b/src/test/ui/async-await/no-async-const.rs
@@ -2,7 +2,5 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 pub async const fn x() {}
 //~^ ERROR expected one of `fn` or `unsafe`, found `const`
diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr
index cdb1c6e2d7b..edbdfb56522 100644
--- a/src/test/ui/async-await/no-async-const.stderr
+++ b/src/test/ui/async-await/no-async-const.stderr
@@ -1,5 +1,5 @@
 error: expected one of `fn` or `unsafe`, found `const`
-  --> $DIR/no-async-const.rs:7:11
+  --> $DIR/no-async-const.rs:5:11
    |
 LL | pub async const fn x() {}
    |           ^^^^^ expected one of `fn` or `unsafe` here
diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs
index 9f09d2188c7..bd78a18a40e 100644
--- a/src/test/ui/async-await/no-const-async.rs
+++ b/src/test/ui/async-await/no-const-async.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 pub const async fn x() {}
 //~^ ERROR expected identifier, found reserved keyword `async`
 //~^^ expected `:`, found keyword `fn`
diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr
index 693fbf186f9..6d7df57e7b6 100644
--- a/src/test/ui/async-await/no-const-async.stderr
+++ b/src/test/ui/async-await/no-const-async.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found reserved keyword `async`
-  --> $DIR/no-const-async.rs:7:11
+  --> $DIR/no-const-async.rs:5:11
    |
 LL | pub const async fn x() {}
    |           ^^^^^ expected identifier, found reserved keyword
@@ -9,7 +9,7 @@ LL | pub const r#async fn x() {}
    |           ^^^^^^^
 
 error: expected `:`, found keyword `fn`
-  --> $DIR/no-const-async.rs:7:17
+  --> $DIR/no-const-async.rs:5:17
    |
 LL | pub const async fn x() {}
    |                 ^^ expected `:`
diff --git a/src/test/ui/async-await/no-move-across-await-struct.rs b/src/test/ui/async-await/no-move-across-await-struct.rs
index 58e09470897..bef477bd256 100644
--- a/src/test/ui/async-await/no-move-across-await-struct.rs
+++ b/src/test/ui/async-await/no-move-across-await-struct.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 async fn no_move_across_await_struct() -> Vec<usize> {
     let s = Small { x: vec![31], y: vec![19, 1441] };
     needs_vec(s.x).await;
diff --git a/src/test/ui/async-await/no-move-across-await-struct.stderr b/src/test/ui/async-await/no-move-across-await-struct.stderr
index 121c7791bd9..88f147b8d9d 100644
--- a/src/test/ui/async-await/no-move-across-await-struct.stderr
+++ b/src/test/ui/async-await/no-move-across-await-struct.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `s.x`
-  --> $DIR/no-move-across-await-struct.rs:10:5
+  --> $DIR/no-move-across-await-struct.rs:8:5
    |
 LL |     needs_vec(s.x).await;
    |               --- value moved here
diff --git a/src/test/ui/async-await/no-move-across-await-tuple.rs b/src/test/ui/async-await/no-move-across-await-tuple.rs
index 5d3ed3da1e3..565cbd7d5f4 100644
--- a/src/test/ui/async-await/no-move-across-await-tuple.rs
+++ b/src/test/ui/async-await/no-move-across-await-tuple.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 async fn no_move_across_await_tuple() -> Vec<usize> {
     let x = (vec![3], vec![4, 4]);
     drop(x.1);
diff --git a/src/test/ui/async-await/no-move-across-await-tuple.stderr b/src/test/ui/async-await/no-move-across-await-tuple.stderr
index 5da037ea5c0..fe98ecd599a 100644
--- a/src/test/ui/async-await/no-move-across-await-tuple.stderr
+++ b/src/test/ui/async-await/no-move-across-await-tuple.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `x.1`
-  --> $DIR/no-move-across-await-tuple.rs:11:5
+  --> $DIR/no-move-across-await-tuple.rs:9:5
    |
 LL |     drop(x.1);
    |          --- value moved here
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
index a916afb6b09..0afbf4cee1d 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
@@ -2,8 +2,6 @@
 // edition:2018
 // compile-flags: --crate-type lib
 
-#![feature(async_await)]
-
 async fn no_non_guaranteed_initialization(x: usize) -> usize {
     let y;
     if x > 5 {
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
index fb94522cac0..91d7994654f 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
@@ -1,5 +1,5 @@
 error[E0381]: use of possibly uninitialized variable: `y`
-  --> $DIR/no-non-guaranteed-initialization.rs:12:5
+  --> $DIR/no-non-guaranteed-initialization.rs:10:5
    |
 LL |     y
    |     ^ use of possibly uninitialized `y`
diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs
index 40f9f5202e7..1785fb7f299 100644
--- a/src/test/ui/async-await/partial-initialization-across-await.rs
+++ b/src/test/ui/async-await/partial-initialization-across-await.rs
@@ -3,8 +3,6 @@
 
 // edition:2018
 
-#![feature(async_await)]
-
 struct S { x: i32, y: i32 }
 struct T(i32, i32);
 
diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr
index fe79eb08bef..d9a2db985e5 100644
--- a/src/test/ui/async-await/partial-initialization-across-await.stderr
+++ b/src/test/ui/async-await/partial-initialization-across-await.stderr
@@ -1,17 +1,17 @@
 error[E0381]: assign to part of possibly uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-await.rs:15:5
+  --> $DIR/partial-initialization-across-await.rs:13:5
    |
 LL |     t.0 = 42;
    |     ^^^^^^^^ use of possibly uninitialized `t`
 
 error[E0381]: assign to part of possibly uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-await.rs:24:5
+  --> $DIR/partial-initialization-across-await.rs:22:5
    |
 LL |     t.0 = 42;
    |     ^^^^^^^^ use of possibly uninitialized `t`
 
 error[E0381]: assign to part of possibly uninitialized variable: `t`
-  --> $DIR/partial-initialization-across-await.rs:33:5
+  --> $DIR/partial-initialization-across-await.rs:31:5
    |
 LL |     t.x = 42;
    |     ^^^^^^^^ use of possibly uninitialized `t`
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.rs b/src/test/ui/async-await/recursive-async-impl-trait-type.rs
index 54f3339870b..aa773319458 100644
--- a/src/test/ui/async-await/recursive-async-impl-trait-type.rs
+++ b/src/test/ui/async-await/recursive-async-impl-trait-type.rs
@@ -2,8 +2,6 @@
 // Test that impl trait does not allow creating recursive types that are
 // otherwise forbidden when using `async` and `await`.
 
-#![feature(async_await)]
-
 async fn recursive_async_function() -> () { //~ ERROR
     recursive_async_function().await;
 }
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
index 64f6eccd547..8781a9c444d 100644
--- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
+++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/recursive-async-impl-trait-type.rs:7:40
+  --> $DIR/recursive-async-impl-trait-type.rs:5:40
    |
 LL | async fn recursive_async_function() -> () {
    |                                        ^^ an `async fn` cannot invoke itself directly
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.fixed b/src/test/ui/async-await/suggest-missing-await-closure.fixed
index 60c9a8581ac..37b30ffe680 100644
--- a/src/test/ui/async-await/suggest-missing-await-closure.fixed
+++ b/src/test/ui/async-await/suggest-missing-await-closure.fixed
@@ -1,7 +1,7 @@
 // edition:2018
 // run-rustfix
 
-#![feature(async_await, async_closure)]
+#![feature(async_closure)]
 
 fn take_u32(_x: u32) {}
 
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.rs b/src/test/ui/async-await/suggest-missing-await-closure.rs
index cb992a27bc1..18076a15161 100644
--- a/src/test/ui/async-await/suggest-missing-await-closure.rs
+++ b/src/test/ui/async-await/suggest-missing-await-closure.rs
@@ -1,7 +1,7 @@
 // edition:2018
 // run-rustfix
 
-#![feature(async_await, async_closure)]
+#![feature(async_closure)]
 
 fn take_u32(_x: u32) {}
 
diff --git a/src/test/ui/async-await/suggest-missing-await.fixed b/src/test/ui/async-await/suggest-missing-await.fixed
index aa032682be8..7c02a907ce7 100644
--- a/src/test/ui/async-await/suggest-missing-await.fixed
+++ b/src/test/ui/async-await/suggest-missing-await.fixed
@@ -1,8 +1,6 @@
 // edition:2018
 // run-rustfix
 
-#![feature(async_await)]
-
 fn take_u32(_x: u32) {}
 
 async fn make_u32() -> u32 {
diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs
index 2ca814fbb22..91abd44e65c 100644
--- a/src/test/ui/async-await/suggest-missing-await.rs
+++ b/src/test/ui/async-await/suggest-missing-await.rs
@@ -1,8 +1,6 @@
 // edition:2018
 // run-rustfix
 
-#![feature(async_await)]
-
 fn take_u32(_x: u32) {}
 
 async fn make_u32() -> u32 {
diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr
index 9bae7150276..ccca97ec204 100644
--- a/src/test/ui/async-await/suggest-missing-await.stderr
+++ b/src/test/ui/async-await/suggest-missing-await.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/suggest-missing-await.rs:15:14
+  --> $DIR/suggest-missing-await.rs:13:14
    |
 LL |     take_u32(x)
    |              ^
diff --git a/src/test/ui/async-await/unresolved_type_param.rs b/src/test/ui/async-await/unresolved_type_param.rs
index 578d41fe0df..d8ea87d2775 100644
--- a/src/test/ui/async-await/unresolved_type_param.rs
+++ b/src/test/ui/async-await/unresolved_type_param.rs
@@ -2,7 +2,7 @@
 // Error message should pinpoint the type parameter T as needing to be bound
 // (rather than give a general error message)
 // edition:2018
-#![feature(async_await)]
+
 async fn bar<T>() -> () {}
 
 async fn foo() {
diff --git a/src/test/ui/break-outside-loop.rs b/src/test/ui/break-outside-loop.rs
index fef298f7c39..c424c25c646 100644
--- a/src/test/ui/break-outside-loop.rs
+++ b/src/test/ui/break-outside-loop.rs
@@ -7,8 +7,8 @@ fn cond() -> bool { true }
 fn foo<F>(_: F) where F: FnOnce() {}
 
 fn main() {
-    let pth = break; //~ ERROR: `break` outside of loop
-    if cond() { continue } //~ ERROR: `continue` outside of loop
+    let pth = break; //~ ERROR: `break` outside of a loop
+    if cond() { continue } //~ ERROR: `continue` outside of a loop
 
     while cond() {
         if cond() { break }
@@ -21,5 +21,5 @@ fn main() {
 
     let rs: Foo = Foo{t: pth};
 
-    let unconstrained = break; //~ ERROR: `break` outside of loop
+    let unconstrained = break; //~ ERROR: `break` outside of a loop
 }
diff --git a/src/test/ui/break-outside-loop.stderr b/src/test/ui/break-outside-loop.stderr
index 8f4656ab394..8b686356055 100644
--- a/src/test/ui/break-outside-loop.stderr
+++ b/src/test/ui/break-outside-loop.stderr
@@ -1,32 +1,37 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/break-outside-loop.rs:10:15
    |
 LL |     let pth = break;
-   |               ^^^^^ cannot break outside of a loop
+   |               ^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/break-outside-loop.rs:11:17
    |
 LL |     if cond() { continue }
-   |                 ^^^^^^^^ cannot break outside of a loop
+   |                 ^^^^^^^^ cannot `continue` outside of a loop
 
 error[E0267]: `break` inside of a closure
   --> $DIR/break-outside-loop.rs:17:25
    |
+LL |         foo(|| {
+   |             -- enclosing closure
 LL |             if cond() { break }
-   |                         ^^^^^ cannot break inside of a closure
+   |                         ^^^^^ cannot `break` inside of a closure
 
 error[E0267]: `continue` inside of a closure
   --> $DIR/break-outside-loop.rs:18:25
    |
+LL |         foo(|| {
+   |             -- enclosing closure
+LL |             if cond() { break }
 LL |             if cond() { continue }
-   |                         ^^^^^^^^ cannot break inside of a closure
+   |                         ^^^^^^^^ cannot `continue` inside of a closure
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/break-outside-loop.rs:24:25
    |
 LL |     let unconstrained = break;
-   |                         ^^^^^ cannot break outside of a loop
+   |                         ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/closures/closure-array-break-length.rs b/src/test/ui/closures/closure-array-break-length.rs
index a7f16d70ba8..f3567db1fac 100644
--- a/src/test/ui/closures/closure-array-break-length.rs
+++ b/src/test/ui/closures/closure-array-break-length.rs
@@ -1,9 +1,9 @@
 fn main() {
-    |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+    |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop
 
-    while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
+    while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop
     //~^ ERROR mismatched types
 
-    while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
+    while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop
     //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr
index 46fbd3e0fae..18da4a94e6f 100644
--- a/src/test/ui/closures/closure-array-break-length.stderr
+++ b/src/test/ui/closures/closure-array-break-length.stderr
@@ -1,20 +1,20 @@
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/closure-array-break-length.rs:2:13
    |
 LL |     |_: [_; continue]| {};
-   |             ^^^^^^^^ cannot break outside of a loop
+   |             ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/closure-array-break-length.rs:4:19
    |
 LL |     while |_: [_; continue]| {} {}
-   |                   ^^^^^^^^ cannot break outside of a loop
+   |                   ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/closure-array-break-length.rs:7:19
    |
 LL |     while |_: [_; break]| {} {}
-   |                   ^^^^^ cannot break outside of a loop
+   |                   ^^^^^ cannot `break` outside of a loop
 
 error[E0308]: mismatched types
   --> $DIR/closure-array-break-length.rs:4:11
diff --git a/src/test/ui/commandline-argfile-badutf8.args b/src/test/ui/commandline-argfile-badutf8.args
new file mode 100644
index 00000000000..c070b0c2400
--- /dev/null
+++ b/src/test/ui/commandline-argfile-badutf8.args
@@ -0,0 +1,2 @@
+--cfg
+unbroken€
\ No newline at end of file
diff --git a/src/test/ui/commandline-argfile-badutf8.rs b/src/test/ui/commandline-argfile-badutf8.rs
new file mode 100644
index 00000000000..161715685b5
--- /dev/null
+++ b/src/test/ui/commandline-argfile-badutf8.rs
@@ -0,0 +1,13 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-fail
+// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unbroken))]
+compile_error!("unbroken not set");
+
+fn main() {
+}
diff --git a/src/test/ui/commandline-argfile-badutf8.stderr b/src/test/ui/commandline-argfile-badutf8.stderr
new file mode 100644
index 00000000000..9af6fc0a518
--- /dev/null
+++ b/src/test/ui/commandline-argfile-badutf8.stderr
@@ -0,0 +1,2 @@
+error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args
+
diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/ui/commandline-argfile-missing.rs
new file mode 100644
index 00000000000..a29b4ab062d
--- /dev/null
+++ b/src/test/ui/commandline-argfile-missing.rs
@@ -0,0 +1,16 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// ignore-tidy-linelength
+// build-fail
+// normalize-stderr-test: "os error \d+" -> "os error $$ERR"
+// normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
+// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unbroken))]
+compile_error!("unbroken not set");
+
+fn main() {
+}
diff --git a/src/test/ui/commandline-argfile-missing.stderr b/src/test/ui/commandline-argfile-missing.stderr
new file mode 100644
index 00000000000..179ad831004
--- /dev/null
+++ b/src/test/ui/commandline-argfile-missing.stderr
@@ -0,0 +1,2 @@
+error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+
diff --git a/src/test/ui/commandline-argfile.args b/src/test/ui/commandline-argfile.args
new file mode 100644
index 00000000000..972938bf6c8
--- /dev/null
+++ b/src/test/ui/commandline-argfile.args
@@ -0,0 +1,2 @@
+--cfg
+unbroken
\ No newline at end of file
diff --git a/src/test/ui/commandline-argfile.rs b/src/test/ui/commandline-argfile.rs
new file mode 100644
index 00000000000..fc1ba0c8d67
--- /dev/null
+++ b/src/test/ui/commandline-argfile.rs
@@ -0,0 +1,13 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-pass
+// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unbroken))]
+compile_error!("unbroken not set");
+
+fn main() {
+}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
index 0dceba28b6e..7dbeba53afc 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
@@ -3,6 +3,6 @@
 // compile-flags: --cfg broken
 
 #![crate_type = "lib"]
-#![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental
+#![cfg_attr(broken, no_core)] //~ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
index 5a70a5efc7f..7b77701ee19 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/cfg-attr-crate-2.rs:6:21
    |
 LL | #![cfg_attr(broken, no_core)]
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
index be762c56048..42ffb71e3d7 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
@@ -1,6 +1,7 @@
 // compile-flags: --cfg broken
 
 #![crate_type = "lib"]
-#![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
+#![cfg_attr(broken, no_core, no_std)]
+//~^ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
index 5e9adf17807..ab7e1eb9603 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/cfg-attr-multi-invalid-1.rs:4:21
    |
 LL | #![cfg_attr(broken, no_core, no_std)]
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
index 8a9e99d703c..29690e2848f 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
@@ -1,6 +1,7 @@
 // compile-flags: --cfg broken
 
 #![crate_type = "lib"]
-#![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
+#![cfg_attr(broken, no_std, no_core)]
+//~^ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
index 06b67156651..8126affbd36 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/cfg-attr-multi-invalid-2.rs:4:29
    |
 LL | #![cfg_attr(broken, no_std, no_core)]
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs
new file mode 100644
index 00000000000..4281874a031
--- /dev/null
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs
@@ -0,0 +1,16 @@
+const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
+//~^ dereferencing raw pointers in constant functions
+
+const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
+//~^ dereferencing raw pointers in constant functions
+
+const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x }
+//~^ dereferencing raw pointers in constant functions
+
+fn main() {}
+
+const unsafe fn no_union() {
+    union Foo { x: (), y: () }
+    Foo { x: () }.y
+    //~^ unions in const fn
+}
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr
index d3f2ece1f92..9de0e732f33 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr
@@ -1,5 +1,5 @@
 error[E0658]: dereferencing raw pointers in constant functions is unstable
-  --> $DIR/min_const_fn_unsafe.rs:50:77
+  --> $DIR/min_const_fn_unsafe_bad.rs:1:77
    |
 LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } }
    |                                                                             ^^^
@@ -8,7 +8,7 @@ LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe {
    = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
 
 error[E0658]: dereferencing raw pointers in constant functions is unstable
-  --> $DIR/min_const_fn_unsafe.rs:53:70
+  --> $DIR/min_const_fn_unsafe_bad.rs:4:70
    |
 LL | const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
    |                                                                      ^^
@@ -17,7 +17,7 @@ LL | const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
    = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
 
 error[E0658]: dereferencing raw pointers in constant functions is unstable
-  --> $DIR/min_const_fn_unsafe.rs:56:83
+  --> $DIR/min_const_fn_unsafe_bad.rs:7:83
    |
 LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x }
    |                                                                                   ^^^
@@ -26,7 +26,7 @@ LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static u
    = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
 
 error[E0658]: unions in const fn are unstable
-  --> $DIR/min_const_fn_unsafe.rs:63:5
+  --> $DIR/min_const_fn_unsafe_bad.rs:14:5
    |
 LL |     Foo { x: () }.y
    |     ^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     Foo { x: () }.y
    = help: add `#![feature(const_fn_union)]` to the crate attributes to enable
 
 error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
-  --> $DIR/min_const_fn_unsafe.rs:50:77
+  --> $DIR/min_const_fn_unsafe_bad.rs:1:77
    |
 LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } }
    |                                                                             ^^^ dereference of raw pointer
diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs
index 0152561aefc..02c7970deca 100644
--- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs
+++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs
@@ -1,6 +1,4 @@
-//------------------------------------------------------------------------------
-// OK
-//------------------------------------------------------------------------------
+// check-pass
 
 const unsafe fn ret_i32_no_unsafe() -> i32 { 42 }
 const unsafe fn ret_null_ptr_no_unsafe<T>() -> *const T { std::ptr::null() }
@@ -43,23 +41,4 @@ const unsafe fn call_unsafe_generic_cell_const_unsafe_fn_immediate()
     ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>()
 }
 
-//------------------------------------------------------------------------------
-// NOT OK
-//------------------------------------------------------------------------------
-
-const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe
-//~^ dereferencing raw pointers in constant functions
-
-const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x }
-//~^ dereferencing raw pointers in constant functions
-
-const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x }
-//~^ dereferencing raw pointers in constant functions
-
 fn main() {}
-
-const unsafe fn no_union() {
-    union Foo { x: (), y: () }
-    Foo { x: () }.y
-    //~^ unions in const fn
-}
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index f3f5c382275..79d09d18176 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -7,10 +7,7 @@
 // edition:2018
 // ignore-wasm32-bare compiled with panic=abort by default
 
-#![allow(unused_assignments)]
-#![allow(unused_variables)]
 #![feature(slice_patterns)]
-#![feature(async_await)]
 
 use std::{
     cell::{Cell, RefCell},
diff --git a/src/test/ui/error-codes/E0267.stderr b/src/test/ui/error-codes/E0267.stderr
index b14cfd1a52d..1f8657373ef 100644
--- a/src/test/ui/error-codes/E0267.stderr
+++ b/src/test/ui/error-codes/E0267.stderr
@@ -2,7 +2,9 @@ error[E0267]: `break` inside of a closure
   --> $DIR/E0267.rs:2:18
    |
 LL |     let w = || { break; };
-   |                  ^^^^^ cannot break inside of a closure
+   |             --   ^^^^^ cannot `break` inside of a closure
+   |             |
+   |             enclosing closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr
index 3c77e7f3df2..c926f9e4874 100644
--- a/src/test/ui/error-codes/E0268.stderr
+++ b/src/test/ui/error-codes/E0268.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/E0268.rs:2:5
    |
 LL |     break;
-   |     ^^^^^ cannot break outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate-optimize_attribute.rs b/src/test/ui/feature-gate-optimize_attribute.rs
index 7fc0fdde6fb..15aa3a6af4c 100644
--- a/src/test/ui/feature-gate-optimize_attribute.rs
+++ b/src/test/ui/feature-gate-optimize_attribute.rs
@@ -1,17 +1,17 @@
 #![crate_type="rlib"]
-#![optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#![optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 
-#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 mod module {
 
-#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn size() {}
 
-#[optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#[optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn speed() {}
 
 #[optimize(banana)]
-//~^ ERROR `#[optimize]` attribute is an unstable feature
+//~^ ERROR the `#[optimize]` attribute is an experimental feature
 //~| ERROR E0722
 fn not_known() {}
 
diff --git a/src/test/ui/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gate-optimize_attribute.stderr
index 4ec512eaf39..3e3ad71c344 100644
--- a/src/test/ui/feature-gate-optimize_attribute.stderr
+++ b/src/test/ui/feature-gate-optimize_attribute.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:7:1
    |
 LL | #[optimize(size)]
@@ -7,7 +7,7 @@ LL | #[optimize(size)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:10:1
    |
 LL | #[optimize(speed)]
@@ -16,7 +16,7 @@ LL | #[optimize(speed)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:13:1
    |
 LL | #[optimize(banana)]
@@ -25,7 +25,7 @@ LL | #[optimize(banana)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:4:1
    |
 LL | #[optimize(size)]
@@ -34,7 +34,7 @@ LL | #[optimize(size)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:2:1
    |
 LL | #![optimize(speed)]
diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
index 17b4f775ad4..ad890961830 100644
--- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
+++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
@@ -5,7 +5,7 @@
 
 use core::alloc::Layout;
 
-#[alloc_error_handler] //~ ERROR `#[alloc_error_handler]` is an unstable feature
+#[alloc_error_handler] //~ ERROR the `#[alloc_error_handler]` attribute is an experimental feature
 fn oom(info: Layout) -> ! {
     loop {}
 }
diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
index d18cc09ffe7..79e44bf0d8e 100644
--- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
+++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[alloc_error_handler]` is an unstable feature
+error[E0658]: the `#[alloc_error_handler]` attribute is an experimental feature
   --> $DIR/feature-gate-alloc-error-handler.rs:8:1
    |
 LL | #[alloc_error_handler]
diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.rs b/src/test/ui/feature-gates/feature-gate-allow_fail.rs
index f9ad4855141..287d4ccf180 100644
--- a/src/test/ui/feature-gates/feature-gate-allow_fail.rs
+++ b/src/test/ui/feature-gates/feature-gate-allow_fail.rs
@@ -1,6 +1,6 @@
 // check that #[allow_fail] is feature-gated
 
-#[allow_fail] //~ ERROR allow_fail attribute is currently unstable
+#[allow_fail] //~ ERROR the `#[allow_fail]` attribute is an experimental feature
 fn ok_to_fail() {
     assert!(false);
 }
diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
index 37bf3a262aa..0f60a2de3a4 100644
--- a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
+++ b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
@@ -1,4 +1,4 @@
-error[E0658]: allow_fail attribute is currently unstable
+error[E0658]: the `#[allow_fail]` attribute is an experimental feature
   --> $DIR/feature-gate-allow_fail.rs:3:1
    |
 LL | #[allow_fail]
diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs
deleted file mode 100644
index 801aeb82aa2..00000000000
--- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// edition:2015
-
-async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
-                  //~^ ERROR async fn is unstable
-
-fn main() {
-    let _ = async {}; //~ ERROR cannot find struct, variant or union type `async`
-    let _ = async || { true }; //~ ERROR cannot find value `async` in this scope
-}
diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr
deleted file mode 100644
index 0157ed55344..00000000000
--- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0670]: `async fn` is not permitted in the 2015 edition
-  --> $DIR/feature-gate-async-await-2015-edition.rs:3:1
-   |
-LL | async fn foo() {}
-   | ^^^^^
-
-error[E0422]: cannot find struct, variant or union type `async` in this scope
-  --> $DIR/feature-gate-async-await-2015-edition.rs:7:13
-   |
-LL |     let _ = async {};
-   |             ^^^^^ not found in this scope
-
-error[E0425]: cannot find value `async` in this scope
-  --> $DIR/feature-gate-async-await-2015-edition.rs:8:13
-   |
-LL |     let _ = async || { true };
-   |             ^^^^^ not found in this scope
-
-error[E0658]: async fn is unstable
-  --> $DIR/feature-gate-async-await-2015-edition.rs:3:1
-   |
-LL | async fn foo() {}
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add `#![feature(async_await)]` to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0422, E0425, E0658, E0670.
-For more information about an error, try `rustc --explain E0422`.
diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs
deleted file mode 100644
index 78391c0e104..00000000000
--- a/src/test/ui/feature-gates/feature-gate-async-await.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// edition:2018
-
-struct S;
-
-impl S {
-    async fn foo() {} //~ ERROR async fn is unstable
-}
-
-trait T {
-    async fn foo(); //~ ERROR trait fns cannot be declared `async`
-    //~^ ERROR async fn is unstable
-}
-
-async fn foo() {} //~ ERROR async fn is unstable
-
-fn main() {
-    let _ = async {}; //~ ERROR async blocks are unstable
-}
diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr
deleted file mode 100644
index 9f4a90157a4..00000000000
--- a/src/test/ui/feature-gates/feature-gate-async-await.stderr
+++ /dev/null
@@ -1,45 +0,0 @@
-error[E0706]: trait fns cannot be declared `async`
-  --> $DIR/feature-gate-async-await.rs:10:5
-   |
-LL |     async fn foo();
-   |     ^^^^^^^^^^^^^^^
-
-error[E0658]: async fn is unstable
-  --> $DIR/feature-gate-async-await.rs:6:5
-   |
-LL |     async fn foo() {}
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add `#![feature(async_await)]` to the crate attributes to enable
-
-error[E0658]: async fn is unstable
-  --> $DIR/feature-gate-async-await.rs:10:5
-   |
-LL |     async fn foo();
-   |     ^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add `#![feature(async_await)]` to the crate attributes to enable
-
-error[E0658]: async fn is unstable
-  --> $DIR/feature-gate-async-await.rs:14:1
-   |
-LL | async fn foo() {}
-   | ^^^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add `#![feature(async_await)]` to the crate attributes to enable
-
-error[E0658]: async blocks are unstable
-  --> $DIR/feature-gate-async-await.rs:17:13
-   |
-LL |     let _ = async {};
-   |             ^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/50547
-   = help: add `#![feature(async_await)]` to the crate attributes to enable
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs
index ea06c775b1a..5050c4792b0 100644
--- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs
+++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs
@@ -1,7 +1,7 @@
 use std::fmt::{Debug, Display};
 
 #[marker] trait ExplicitMarker {}
-//~^ ERROR marker traits is an experimental feature
+//~^ ERROR the `#[marker]` attribute is an experimental feature
 
 impl<T: Display> ExplicitMarker for T {}
 impl<T: Debug> ExplicitMarker for T {}
diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr
index 94dfaf9206d..304c081c5aa 100644
--- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr
+++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr
@@ -1,4 +1,4 @@
-error[E0658]: marker traits is an experimental feature
+error[E0658]: the `#[marker]` attribute is an experimental feature
   --> $DIR/feature-gate-marker_trait_attr.rs:3:1
    |
 LL | #[marker] trait ExplicitMarker {}
diff --git a/src/test/ui/feature-gates/feature-gate-no_core.rs b/src/test/ui/feature-gates/feature-gate-no_core.rs
index 40178edd74b..706efd78672 100644
--- a/src/test/ui/feature-gates/feature-gate-no_core.rs
+++ b/src/test/ui/feature-gates/feature-gate-no_core.rs
@@ -1,5 +1,5 @@
 #![crate_type = "rlib"]
 
-#![no_core] //~ ERROR no_core is experimental
+#![no_core] //~ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/feature-gates/feature-gate-no_core.stderr b/src/test/ui/feature-gates/feature-gate-no_core.stderr
index 4d4ca96544e..a80b3cbba25 100644
--- a/src/test/ui/feature-gates/feature-gate-no_core.stderr
+++ b/src/test/ui/feature-gates/feature-gate-no_core.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/feature-gate-no_core.rs:3:1
    |
 LL | #![no_core]
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs b/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs
index aca214d1935..950f170f4fd 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs
@@ -1,6 +1,6 @@
 //#![feature(non_exhaustive)]
 
-#[non_exhaustive] //~ERROR non exhaustive is an experimental feature
+#[non_exhaustive] //~ERROR the `#[non_exhaustive]` attribute is an experimental feature
 pub enum NonExhaustiveEnum {
     Unit,
     Tuple(u32),
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr
index 8a01aa9eb6a..482332b8d70 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr
@@ -1,4 +1,4 @@
-error[E0658]: non exhaustive is an experimental feature
+error[E0658]: the `#[non_exhaustive]` attribute is an experimental feature
   --> $DIR/feature-gate-non_exhaustive.rs:3:1
    |
 LL | #[non_exhaustive]
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
index 13983726c78..4044fd2b895 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
@@ -16,7 +16,7 @@ fn f() {}
 fn g() {}
 
 #[rustc_dummy]
-//~^ ERROR used by the test suite
+//~^ ERROR the `#[rustc_dummy]` attribute is just used for rustc unit tests
 #[rustc_unknown]
 //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
 //~| ERROR cannot find attribute macro `rustc_unknown` in this scope
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
index 23cf936ee83..c1063027fa4 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
@@ -43,7 +43,7 @@ error: cannot find attribute macro `rustc_unknown` in this scope
 LL | #[rustc_unknown]
    |   ^^^^^^^^^^^^^
 
-error[E0658]: used by the test suite
+error[E0658]: the `#[rustc_dummy]` attribute is just used for rustc unit tests and will never be stable
   --> $DIR/feature-gate-rustc-attrs.rs:18:1
    |
 LL | #[rustc_dummy]
diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs
index 08e8ec9a56e..6d8ac7e8f29 100644
--- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs
+++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs
@@ -8,7 +8,7 @@ extern {
     fn extern_fn();
 // CHECK-NOT: Function Attrs: nounwind
 // CHECK: declare void @unwinding_extern_fn
-    #[unwind(allowed)] //~ ERROR `#[unwind]` is experimental
+    #[unwind(allowed)] //~ ERROR the `#[unwind]` attribute is an experimental feature
     fn unwinding_extern_fn();
 }
 
diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr
index 639b87e0162..10cc4942135 100644
--- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[unwind]` is experimental
+error[E0658]: the `#[unwind]` attribute is an experimental feature
   --> $DIR/feature-gate-unwind-attributes.rs:11:5
    |
 LL |     #[unwind(allowed)]
diff --git a/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs b/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs
index ce4642020f0..e3d19029348 100644
--- a/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs
+++ b/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs
@@ -4,7 +4,7 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await, generators, generator_trait)]
+#![feature(generators, generator_trait)]
 
 use std::ops::Generator;
 
diff --git a/src/test/ui/generator/issue-62506-two_awaits.rs b/src/test/ui/generator/issue-62506-two_awaits.rs
index 774019b6a5b..672e16b780d 100644
--- a/src/test/ui/generator/issue-62506-two_awaits.rs
+++ b/src/test/ui/generator/issue-62506-two_awaits.rs
@@ -4,7 +4,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
 use std::future::Future;
 
 pub trait T {
diff --git a/src/test/ui/hygiene/eager-from-opaque-2.rs b/src/test/ui/hygiene/eager-from-opaque-2.rs
new file mode 100644
index 00000000000..220e5526745
--- /dev/null
+++ b/src/test/ui/hygiene/eager-from-opaque-2.rs
@@ -0,0 +1,22 @@
+// Regression test for the issue #63460.
+
+// check-pass
+
+#[macro_export]
+macro_rules! separator {
+    () => { "/" };
+}
+
+#[macro_export]
+macro_rules! concat_separator {
+    ( $e:literal, $($other:literal),+ ) => {
+        concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+))
+    };
+    ( $e:literal ) => {
+        $e
+    }
+}
+
+fn main() {
+    println!("{}", concat_separator!(2, 3, 4))
+}
diff --git a/src/test/ui/hygiene/eager-from-opaque.rs b/src/test/ui/hygiene/eager-from-opaque.rs
new file mode 100644
index 00000000000..6f3215dd697
--- /dev/null
+++ b/src/test/ui/hygiene/eager-from-opaque.rs
@@ -0,0 +1,20 @@
+// Opaque macro can eagerly expand its input without breaking its resolution.
+// Regression test for issue #63685.
+
+// check-pass
+
+macro_rules! foo {
+    () => {
+        "foo"
+    };
+}
+
+macro_rules! bar {
+    () => {
+        foo!()
+    };
+}
+
+fn main() {
+    format_args!(bar!());
+}
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs
index ce1550568c1..235c1f80ef6 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.rs
+++ b/src/test/ui/impl-trait/bound-normalization-fail.rs
@@ -2,7 +2,6 @@
 // ignore-tidy-linelength
 // edition:2018
 
-#![feature(async_await)]
 #![feature(impl_trait_in_bindings)]
 //~^ WARNING the feature `impl_trait_in_bindings` is incomplete
 
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index 4811b1e0ff3..2c4c61a0957 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -1,5 +1,5 @@
 warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
-  --> $DIR/bound-normalization-fail.rs:6:12
+  --> $DIR/bound-normalization-fail.rs:5:12
    |
 LL | #![feature(impl_trait_in_bindings)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:29:32
+  --> $DIR/bound-normalization-fail.rs:28:32
    |
 LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
@@ -17,13 +17,13 @@ LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    = note: the return type of a function must have a statically known size
 
 error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/bound-normalization-fail.rs:45:41
+  --> $DIR/bound-normalization-fail.rs:44:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
-  --> $DIR/bound-normalization-fail.rs:45:41
+  --> $DIR/bound-normalization-fail.rs:44:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type
diff --git a/src/test/ui/impl-trait/bound-normalization-pass.rs b/src/test/ui/impl-trait/bound-normalization-pass.rs
index b0ed4be54b8..fff17667fda 100644
--- a/src/test/ui/impl-trait/bound-normalization-pass.rs
+++ b/src/test/ui/impl-trait/bound-normalization-pass.rs
@@ -1,7 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
 #![feature(type_alias_impl_trait)]
 #![feature(impl_trait_in_bindings)]
 //~^ WARNING the feature `impl_trait_in_bindings` is incomplete
diff --git a/src/test/ui/impl-trait/bound-normalization-pass.stderr b/src/test/ui/impl-trait/bound-normalization-pass.stderr
index 229acdb2b14..d048da7f60b 100644
--- a/src/test/ui/impl-trait/bound-normalization-pass.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-pass.stderr
@@ -1,5 +1,5 @@
 warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
-  --> $DIR/bound-normalization-pass.rs:6:12
+  --> $DIR/bound-normalization-pass.rs:5:12
    |
 LL | #![feature(impl_trait_in_bindings)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs
index dfee20ca649..1ca2e3d9065 100644
--- a/src/test/ui/impl-trait/issue-55872-2.rs
+++ b/src/test/ui/impl-trait/issue-55872-2.rs
@@ -1,6 +1,7 @@
 // edition:2018
 // ignore-tidy-linelength
-#![feature(async_await, type_alias_impl_trait)]
+
+#![feature(type_alias_impl_trait)]
 
 pub trait Bar {
     type E: Copy;
diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr
index 676c3fe3d4c..01371b4d5c6 100644
--- a/src/test/ui/impl-trait/issue-55872-2.stderr
+++ b/src/test/ui/impl-trait/issue-55872-2.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied
-  --> $DIR/issue-55872-2.rs:12:5
+  --> $DIR/issue-55872-2.rs:13:5
    |
 LL |     type E = impl Copy;
    |     ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future`
@@ -7,7 +7,7 @@ LL |     type E = impl Copy;
    = note: the return type of a function must have a statically known size
 
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:14:28
+  --> $DIR/issue-55872-2.rs:15:28
    |
 LL |       fn foo<T>() -> Self::E {
    |  ____________________________^
diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs
index 30ed5050433..7d75f254bfe 100644
--- a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs
+++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(async_await)]
 #![feature(impl_trait_in_bindings)]
 //~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
 
diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr
index 67a834a2e95..f67e45b01d2 100644
--- a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr
+++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr
@@ -1,5 +1,5 @@
 warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
-  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:3:12
+  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:2:12
    |
 LL | #![feature(impl_trait_in_bindings)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0282]: type annotations needed for `impl std::future::Future`
-  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:14:9
+  --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:13:9
    |
 LL |     let fut = async {
    |         --- consider giving `fut` the explicit type `impl std::future::Future`, with the type parameters specified
diff --git a/src/test/ui/inference/cannot-infer-async.rs b/src/test/ui/inference/cannot-infer-async.rs
index edc64276e7c..05f62f3d8cb 100644
--- a/src/test/ui/inference/cannot-infer-async.rs
+++ b/src/test/ui/inference/cannot-infer-async.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(async_await)]
 
 use std::io::Error;
 
diff --git a/src/test/ui/inference/cannot-infer-async.stderr b/src/test/ui/inference/cannot-infer-async.stderr
index 36608a11bb7..bf31fb85cf6 100644
--- a/src/test/ui/inference/cannot-infer-async.stderr
+++ b/src/test/ui/inference/cannot-infer-async.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/cannot-infer-async.rs:12:9
+  --> $DIR/cannot-infer-async.rs:11:9
    |
 LL |     let fut = async {
    |         --- consider giving `fut` a type
diff --git a/src/test/ui/issues/issue-28105.rs b/src/test/ui/issues/issue-28105.rs
index 6026cbb82ae..1e8d2d6ccf1 100644
--- a/src/test/ui/issues/issue-28105.rs
+++ b/src/test/ui/issues/issue-28105.rs
@@ -1,8 +1,8 @@
 // Make sure that a continue span actually contains the keyword.
 
 fn main() {
-    continue //~ ERROR `continue` outside of loop
+    continue //~ ERROR `continue` outside of a loop
     ;
-    break //~ ERROR `break` outside of loop
+    break //~ ERROR `break` outside of a loop
     ;
 }
diff --git a/src/test/ui/issues/issue-28105.stderr b/src/test/ui/issues/issue-28105.stderr
index 0e1b90e6520..42ed838d7c0 100644
--- a/src/test/ui/issues/issue-28105.stderr
+++ b/src/test/ui/issues/issue-28105.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/issue-28105.rs:4:5
    |
 LL |     continue
-   |     ^^^^^^^^ cannot break outside of a loop
+   |     ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-28105.rs:6:5
    |
 LL |     break
-   |     ^^^^^ cannot break outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-31776.rs b/src/test/ui/issues/issue-31776.rs
index c0d2c91e577..c86623ce289 100644
--- a/src/test/ui/issues/issue-31776.rs
+++ b/src/test/ui/issues/issue-31776.rs
@@ -13,7 +13,7 @@ mod m {
     }
 }
 
-// ------------------------------------------------------
+// Scenario 1
 
 pub trait Tr {
     type A;
@@ -28,7 +28,7 @@ fn f() {
     }
 }
 
-// ------------------------------------------------------
+// Scenario 2
 
 trait Tr1 {
     type A;
@@ -49,8 +49,6 @@ mod m1 {
     }
 }
 
-// ------------------------------------------------------
-
 fn main() {
     S.s(); // Privacy error, unless `fn s` is pub
     let a = S2.pull().field; // Privacy error unless `field: u8` is pub
diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr
index 6d3e8b5ba23..c729c05ff22 100644
--- a/src/test/ui/issues/issue-43162.stderr
+++ b/src/test/ui/issues/issue-43162.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-43162.rs:3:5
    |
 LL |     break true;
-   |     ^^^^^^^^^^ cannot break outside of a loop
+   |     ^^^^^^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-43162.rs:7:5
    |
 LL |     break {};
-   |     ^^^^^^^^ cannot break outside of a loop
+   |     ^^^^^^^^ cannot `break` outside of a loop
 
 error[E0308]: mismatched types
   --> $DIR/issue-43162.rs:1:13
diff --git a/src/test/ui/issues/issue-50415.rs b/src/test/ui/issues/issue-50415.rs
index 20c7be772f9..151b9fe442c 100644
--- a/src/test/ui/issues/issue-50415.rs
+++ b/src/test/ui/issues/issue-50415.rs
@@ -1,11 +1,9 @@
 // run-pass
 fn main() {
-    // -------- Simplified test case --------
-
+    // Simplified test case
     let _ = || 0..=1;
 
-    // -------- Original test case --------
-
+    // Original test case
     let full_length = 1024;
     let range = {
         // do some stuff, omit here
diff --git a/src/test/ui/issues/issue-50576.stderr b/src/test/ui/issues/issue-50576.stderr
index 95619eeed9a..9fea1411080 100644
--- a/src/test/ui/issues/issue-50576.stderr
+++ b/src/test/ui/issues/issue-50576.stderr
@@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L`
 LL |     |bool: [u8; break 'L]| 0;
    |                       ^^ undeclared label `'L`
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-50576.rs:2:17
    |
 LL |     |bool: [u8; break 'L]| 0;
-   |                 ^^^^^^^^ cannot break outside of a loop
+   |                 ^^^^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-50576.rs:5:16
    |
 LL |     Vec::<[u8; break]>::new();
-   |                ^^^^^ cannot break outside of a loop
+   |                ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-50581.stderr b/src/test/ui/issues/issue-50581.stderr
index 01a5f9b3c44..35d6fc49ced 100644
--- a/src/test/ui/issues/issue-50581.stderr
+++ b/src/test/ui/issues/issue-50581.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-50581.rs:2:14
    |
 LL |     |_: [u8; break]| ();
-   |              ^^^^^ cannot break outside of a loop
+   |              ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-5067.rs b/src/test/ui/issues/issue-5067.rs
index 616fd09907a..5857a081596 100644
--- a/src/test/ui/issues/issue-5067.rs
+++ b/src/test/ui/issues/issue-5067.rs
@@ -54,7 +54,7 @@ macro_rules! foo {
     //~^ ERROR repetition matches empty token tree
 }
 
-// --- Original Issue --- //
+// Original Issue
 
 macro_rules! make_vec {
     (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]);
@@ -65,7 +65,7 @@ fn main() {
     let _ = make_vec![a 1, a 2, a 3];
 }
 
-// --- Minified Issue --- //
+// Minified Issue
 
 macro_rules! m {
     ( $()* ) => {};
diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs
index 2957f931110..f140546b048 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.rs
+++ b/src/test/ui/lint/lint-unused-mut-variables.rs
@@ -3,7 +3,7 @@
 // Exercise the unused_mut attribute in some positive and negative cases
 
 #![deny(unused_mut)]
-#![feature(async_await, async_closure, param_attrs)]
+#![feature(async_closure, param_attrs)]
 
 async fn baz_async(
     mut a: i32,
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs
index a1660d23511..06b818636f9 100644
--- a/src/test/ui/lint/lint-unused-variables.rs
+++ b/src/test/ui/lint/lint-unused-variables.rs
@@ -1,7 +1,7 @@
 // compile-flags: --cfg something
 // edition:2018
 
-#![feature(async_await, async_closure, param_attrs)]
+#![feature(async_closure, param_attrs)]
 #![deny(unused_variables)]
 
 async fn foo_async(
diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr
index 1ef9427666b..5ca4088e585 100644
--- a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr
+++ b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr
@@ -8,6 +8,9 @@ LL | |
 LL | |         ""
 LL | |     }
    | |_____^
+...
+LL |       format_args!(hang!());
+   |                    ------- in this macro invocation
 help: you might be missing a string literal to format with
    |
 LL |     format_args!("{}", hang!());
diff --git a/src/test/ui/macros/macro-in-fn.rs b/src/test/ui/macros/macro-in-fn.rs
new file mode 100644
index 00000000000..d354fe4a7db
--- /dev/null
+++ b/src/test/ui/macros/macro-in-fn.rs
@@ -0,0 +1,8 @@
+// run-pass
+#![feature(decl_macro)]
+
+pub fn moo() {
+    pub macro ABC() {{}}
+}
+
+fn main() {}
diff --git a/src/test/ui/macros/restricted-shadowing-modern.rs b/src/test/ui/macros/restricted-shadowing-modern.rs
index a8818507d75..1151a829eba 100644
--- a/src/test/ui/macros/restricted-shadowing-modern.rs
+++ b/src/test/ui/macros/restricted-shadowing-modern.rs
@@ -95,8 +95,6 @@ macro include() {
         m!()
     }
 
-    // -----------------------------------------------------------
-
     fn check1() {
         macro m() {}
         {
diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr
index d147debeb51..12075d42b9a 100644
--- a/src/test/ui/macros/restricted-shadowing-modern.stderr
+++ b/src/test/ui/macros/restricted-shadowing-modern.stderr
@@ -1,5 +1,5 @@
 error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/restricted-shadowing-modern.rs:106:17
+  --> $DIR/restricted-shadowing-modern.rs:104:17
    |
 LL |                 m!();
    |                 ^ ambiguous name
@@ -16,7 +16,7 @@ LL |         macro m() { Right }
 LL | include!();
    | ----------- in this macro invocation
 note: `m` could also refer to the macro defined here
-  --> $DIR/restricted-shadowing-modern.rs:101:9
+  --> $DIR/restricted-shadowing-modern.rs:99:9
    |
 LL |         macro m() {}
    |         ^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL | include!();
    | ----------- in this macro invocation
 
 error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/restricted-shadowing-modern.rs:149:33
+  --> $DIR/restricted-shadowing-modern.rs:147:33
    |
 LL |             macro gen_invoc() { m!() }
    |                                 ^ ambiguous name
@@ -42,7 +42,7 @@ LL |         macro m() { Right }
 LL | include!();
    | ----------- in this macro invocation
 note: `m` could also refer to the macro defined here
-  --> $DIR/restricted-shadowing-modern.rs:145:9
+  --> $DIR/restricted-shadowing-modern.rs:143:9
    |
 LL |         macro m() {}
    |         ^^^^^^^^^^^^
@@ -51,7 +51,7 @@ LL | include!();
    | ----------- in this macro invocation
 
 error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/restricted-shadowing-modern.rs:158:13
+  --> $DIR/restricted-shadowing-modern.rs:156:13
    |
 LL |             m!();
    |             ^ ambiguous name
@@ -68,7 +68,7 @@ LL |         macro m() { Right }
 LL | include!();
    | ----------- in this macro invocation
 note: `m` could also refer to the macro defined here
-  --> $DIR/restricted-shadowing-modern.rs:155:9
+  --> $DIR/restricted-shadowing-modern.rs:153:9
    |
 LL |         macro m() {}
    |         ^^^^^^^^^^^^
@@ -77,7 +77,7 @@ LL | include!();
    | ----------- in this macro invocation
 
 error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/restricted-shadowing-modern.rs:174:13
+  --> $DIR/restricted-shadowing-modern.rs:172:13
    |
 LL |             m!();
    |             ^ ambiguous name
@@ -103,7 +103,7 @@ LL | include!();
    | ----------- in this macro invocation
 
 error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/restricted-shadowing-modern.rs:192:17
+  --> $DIR/restricted-shadowing-modern.rs:190:17
    |
 LL |                 m!();
    |                 ^ ambiguous name
@@ -129,7 +129,7 @@ LL | include!();
    | ----------- in this macro invocation
 
 error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/restricted-shadowing-modern.rs:235:33
+  --> $DIR/restricted-shadowing-modern.rs:233:33
    |
 LL |             macro gen_invoc() { m!() }
    |                                 ^ ambiguous name
diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index eebb6f0623f..164668f562c 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -26,8 +26,7 @@ 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 = "...")]`
+warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
   --> $DIR/malformed-regressions.rs:6:1
    |
 LL | #[link]
@@ -36,8 +35,7 @@ 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 = "...")]`
+warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
   --> $DIR/malformed-regressions.rs:7:1
    |
 LL | #[link = ""]
diff --git a/src/test/ui/non-interger-atomic.rs b/src/test/ui/non-integer-atomic.rs
index 00d07b7fe48..00d07b7fe48 100644
--- a/src/test/ui/non-interger-atomic.rs
+++ b/src/test/ui/non-integer-atomic.rs
diff --git a/src/test/ui/non-interger-atomic.stderr b/src/test/ui/non-integer-atomic.stderr
index 7d1130d238e..b3cf788d834 100644
--- a/src/test/ui/non-interger-atomic.stderr
+++ b/src/test/ui/non-integer-atomic.stderr
@@ -1,95 +1,95 @@
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:13:5
+  --> $DIR/non-integer-atomic.rs:13:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:18:5
+  --> $DIR/non-integer-atomic.rs:18:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:23:5
+  --> $DIR/non-integer-atomic.rs:23:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:28:5
+  --> $DIR/non-integer-atomic.rs:28:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:33:5
+  --> $DIR/non-integer-atomic.rs:33:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:38:5
+  --> $DIR/non-integer-atomic.rs:38:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:43:5
+  --> $DIR/non-integer-atomic.rs:43:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:48:5
+  --> $DIR/non-integer-atomic.rs:48:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:53:5
+  --> $DIR/non-integer-atomic.rs:53:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:58:5
+  --> $DIR/non-integer-atomic.rs:58:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:63:5
+  --> $DIR/non-integer-atomic.rs:63:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:68:5
+  --> $DIR/non-integer-atomic.rs:68:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:73:5
+  --> $DIR/non-integer-atomic.rs:73:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:78:5
+  --> $DIR/non-integer-atomic.rs:78:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:83:5
+  --> $DIR/non-integer-atomic.rs:83:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:88:5
+  --> $DIR/non-integer-atomic.rs:88:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr
index 867eafe2529..4944f2649b7 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr
index f31f25bf00b..61be0778c99 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr
@@ -1,16 +1,16 @@
 error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12
    |
 LL |     let _: &'a WithAssoc<TheType<'b>> = loop { };
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: the pointer is valid for the lifetime 'a as defined on the function body at 37:15
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:37:15
+note: the pointer is valid for the lifetime 'a as defined on the function body at 33:15
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:15
    |
 LL | fn with_assoc<'a,'b>() {
    |               ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 37:18
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:37:18
+note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 33:18
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:18
    |
 LL | fn with_assoc<'a,'b>() {
    |                  ^^
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr
index 867eafe2529..4944f2649b7 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12
+  --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12
    |
 LL | fn with_assoc<'a,'b>() {
    |               -- -- lifetime `'b` defined here
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
index 97c55593600..046d010002e 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs
@@ -8,8 +8,6 @@
 
 #![allow(dead_code)]
 
-///////////////////////////////////////////////////////////////////////////
-
 pub trait TheTrait {
     type TheAssocType;
 }
@@ -28,8 +26,6 @@ impl<'b> TheTrait for TheType<'b> {
 impl<'b> TheSubTrait for TheType<'b> {
 }
 
-///////////////////////////////////////////////////////////////////////////
-
 pub struct WithAssoc<T:TheSubTrait> {
     m: [T; 0]
 }
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
index 069332ffa25..5ad6e23cf2a 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -1,7 +1,7 @@
 // compile-flags: --cfg something
 // edition:2018
 
-#![feature(async_await, async_closure, param_attrs)]
+#![feature(async_closure, param_attrs)]
 #![deny(unused_variables)]
 
 extern "C" {
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
index b853f88a96d..f3474bc1f9f 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 use std::pin::Pin;
 use std::task::{Context, Poll};
 
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
index 2421632c664..a585b4fdbe6 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:48
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
    |                          -                     ^^^^^^^^ returning this value requires that `'_` must outlive `'static`
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
index aecb82325c1..0afe631f1e3 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 use std::pin::Pin;
 
 struct Foo;
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
index f0032449db1..2fb152475a1 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
@@ -1,17 +1,17 @@
 error: cannot infer an appropriate lifetime
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:16
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
    |                ^^^^                 ---------- this return type evaluates to the `'static` lifetime...
    |                |
    |                ...but this borrow...
    |
-note: ...can't outlive the lifetime '_ as defined on the method body at 10:26
-  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:26
+note: ...can't outlive the lifetime '_ as defined on the method body at 8:26
+  --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone { self }
    |                          ^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 10:26
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 8:26
    |
 LL |     async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
    |                                     ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
index e33001b9244..e53d91c3604 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:45
    |
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                                             ^^^^
@@ -7,7 +7,7 @@ LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:50
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:50
    |
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                          -                       ^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
@@ -16,7 +16,7 @@ LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                          lifetime `'_` defined here
 
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:13:73
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:73
    |
 LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
    |                          -                                              ^^^^^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
@@ -25,7 +25,7 @@ LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (
    |                          lifetime `'_` defined here
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:58
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    |                                                          ^^^
@@ -33,7 +33,7 @@ LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:62
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:62
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    |                  --              -                           ^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a`
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
index 53ab75ee16b..f42337d5340 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 use std::pin::Pin;
 
 struct Foo;
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
index 74fc4741349..57ad026bdcf 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:45
    |
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                          ----               ^^^^
@@ -8,7 +8,7 @@ LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
    |                          this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:13:55
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:55
    |
 LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
    |                          -----                        ^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (
    |                          this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:58
+  --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
    |                                  -----                   ^^^
diff --git a/src/test/ui/self/elision/alias-async.rs b/src/test/ui/self/elision/alias-async.rs
index 3d5b24a8946..9743c139096 100644
--- a/src/test/ui/self/elision/alias-async.rs
+++ b/src/test/ui/self/elision/alias-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/assoc-async.rs b/src/test/ui/self/elision/assoc-async.rs
index 0f33f288772..fa5968de5ac 100644
--- a/src/test/ui/self/elision/assoc-async.rs
+++ b/src/test/ui/self/elision/assoc-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/lt-alias-async.rs b/src/test/ui/self/elision/lt-alias-async.rs
index 5a8989f078e..cc5badaaa6e 100644
--- a/src/test/ui/self/elision/lt-alias-async.rs
+++ b/src/test/ui/self/elision/lt-alias-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/lt-assoc-async.rs b/src/test/ui/self/elision/lt-assoc-async.rs
index 98c9aa3b6c2..f060800e4da 100644
--- a/src/test/ui/self/elision/lt-assoc-async.rs
+++ b/src/test/ui/self/elision/lt-assoc-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
index 3e58c973019..998178dde1d 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:15:42
+  --> $DIR/lt-ref-self-async.rs:13:42
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                                          ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:15:47
+  --> $DIR/lt-ref-self-async.rs:13:47
    |
 LL |       async fn ref_self(&self, f: &u32) -> &u32 {
    |  _______________________-_______________________^
@@ -19,7 +19,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:21:48
+  --> $DIR/lt-ref-self-async.rs:19:48
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                                ^^^^
@@ -27,7 +27,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:21:53
+  --> $DIR/lt-ref-self-async.rs:19:53
    |
 LL |       async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |  _____________________________-_______________________^
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:25:57
+  --> $DIR/lt-ref-self-async.rs:23:57
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
@@ -47,7 +47,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:25:62
+  --> $DIR/lt-ref-self-async.rs:23:62
    |
 LL |       async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |  _____________________________________-________________________^
@@ -59,7 +59,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:29:57
+  --> $DIR/lt-ref-self-async.rs:27:57
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
@@ -67,7 +67,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:29:62
+  --> $DIR/lt-ref-self-async.rs:27:62
    |
 LL |       async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |  _____________________________________-________________________^
@@ -79,7 +79,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:33:66
+  --> $DIR/lt-ref-self-async.rs:31:66
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
@@ -87,7 +87,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:33:71
+  --> $DIR/lt-ref-self-async.rs:31:71
    |
 LL |       async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |  _____________________________________________-_________________________^
@@ -99,7 +99,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/lt-ref-self-async.rs:37:62
+  --> $DIR/lt-ref-self-async.rs:35:62
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                              ^^^^
@@ -107,7 +107,7 @@ LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#23r
 
 error: lifetime may not live long enough
-  --> $DIR/lt-ref-self-async.rs:37:67
+  --> $DIR/lt-ref-self-async.rs:35:67
    |
 LL |       async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |  _________________________________________-_________________________^
diff --git a/src/test/ui/self/elision/lt-ref-self-async.rs b/src/test/ui/self/elision/lt-ref-self-async.rs
index 79a4771978a..e3ca0c2e2dd 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.rs
+++ b/src/test/ui/self/elision/lt-ref-self-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr
index 0a459257fa7..2bc64bdf1f7 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:15:42
+  --> $DIR/lt-ref-self-async.rs:13:42
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       -----              ^^^^
@@ -8,7 +8,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:21:48
+  --> $DIR/lt-ref-self-async.rs:19:48
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             -----              ^^^^
@@ -17,7 +17,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:25:57
+  --> $DIR/lt-ref-self-async.rs:23:57
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     -----               ^^^^
@@ -26,7 +26,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:29:57
+  --> $DIR/lt-ref-self-async.rs:27:57
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     -----               ^^^^
@@ -35,7 +35,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:33:66
+  --> $DIR/lt-ref-self-async.rs:31:66
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ^^^^
@@ -44,7 +44,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/lt-ref-self-async.rs:37:62
+  --> $DIR/lt-ref-self-async.rs:35:62
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                         -----                ^^^^
diff --git a/src/test/ui/self/elision/lt-self-async.rs b/src/test/ui/self/elision/lt-self-async.rs
index 0202db8a635..42647b82ef8 100644
--- a/src/test/ui/self/elision/lt-self-async.rs
+++ b/src/test/ui/self/elision/lt-self-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/lt-struct-async.rs b/src/test/ui/self/elision/lt-struct-async.rs
index c0fc63d4232..dc5a53b89d7 100644
--- a/src/test/ui/self/elision/lt-struct-async.rs
+++ b/src/test/ui/self/elision/lt-struct-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/multiple-ref-self-async.rs b/src/test/ui/self/elision/multiple-ref-self-async.rs
index eb8c25277e1..be073c6edba 100644
--- a/src/test/ui/self/elision/multiple-ref-self-async.rs
+++ b/src/test/ui/self/elision/multiple-ref-self-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-alias-async.rs b/src/test/ui/self/elision/ref-alias-async.rs
index acc4b2153ef..4b02c2fd00c 100644
--- a/src/test/ui/self/elision/ref-alias-async.rs
+++ b/src/test/ui/self/elision/ref-alias-async.rs
@@ -1,8 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-assoc-async.rs b/src/test/ui/self/elision/ref-assoc-async.rs
index a6b6cbd6da3..258e27b7cb3 100644
--- a/src/test/ui/self/elision/ref-assoc-async.rs
+++ b/src/test/ui/self/elision/ref-assoc-async.rs
@@ -1,8 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-mut-alias-async.rs b/src/test/ui/self/elision/ref-mut-alias-async.rs
index 873e92bc6d3..5f9ccf3bc7f 100644
--- a/src/test/ui/self/elision/ref-mut-alias-async.rs
+++ b/src/test/ui/self/elision/ref-mut-alias-async.rs
@@ -1,7 +1,6 @@
 // edition:2018
 // check-pass
 
-#![feature(async_await)]
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
index b8a53808810..97bc80509df 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:15:46
+  --> $DIR/ref-mut-self-async.rs:13:46
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                                              ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:15:51
+  --> $DIR/ref-mut-self-async.rs:13:51
    |
 LL |       async fn ref_self(&mut self, f: &u32) -> &u32 {
    |  _______________________-___________________________^
@@ -19,7 +19,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:21:52
+  --> $DIR/ref-mut-self-async.rs:19:52
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                                                    ^^^^
@@ -27,7 +27,7 @@ LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:21:57
+  --> $DIR/ref-mut-self-async.rs:19:57
    |
 LL |       async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |  _____________________________-___________________________^
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:25:61
+  --> $DIR/ref-mut-self-async.rs:23:61
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -47,7 +47,7 @@ LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:25:66
+  --> $DIR/ref-mut-self-async.rs:23:66
    |
 LL |       async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |  _____________________________________-____________________________^
@@ -59,7 +59,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:29:61
+  --> $DIR/ref-mut-self-async.rs:27:61
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -67,7 +67,7 @@ LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:29:66
+  --> $DIR/ref-mut-self-async.rs:27:66
    |
 LL |       async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |  _____________________________________-____________________________^
@@ -79,7 +79,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:33:70
+  --> $DIR/ref-mut-self-async.rs:31:70
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
@@ -87,7 +87,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:33:75
+  --> $DIR/ref-mut-self-async.rs:31:75
    |
 LL |       async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |  _____________________________________________-_____________________________^
@@ -99,7 +99,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-self-async.rs:37:70
+  --> $DIR/ref-mut-self-async.rs:35:70
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
@@ -107,7 +107,7 @@ LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-self-async.rs:37:75
+  --> $DIR/ref-mut-self-async.rs:35:75
    |
 LL |       async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |  _____________________________________________-_____________________________^
diff --git a/src/test/ui/self/elision/ref-mut-self-async.rs b/src/test/ui/self/elision/ref-mut-self-async.rs
index a6bd9d69316..2ca14800a75 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.rs
+++ b/src/test/ui/self/elision/ref-mut-self-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr
index 805833f9472..39a1b30ca53 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:15:46
+  --> $DIR/ref-mut-self-async.rs:13:46
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                       ---------              ^^^^
@@ -8,7 +8,7 @@ LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
    |                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:21:52
+  --> $DIR/ref-mut-self-async.rs:19:52
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                             ---------              ^^^^
@@ -17,7 +17,7 @@ LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
    |                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:25:61
+  --> $DIR/ref-mut-self-async.rs:23:61
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                     ---------               ^^^^
@@ -26,7 +26,7 @@ LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:29:61
+  --> $DIR/ref-mut-self-async.rs:27:61
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                     ---------               ^^^^
@@ -35,7 +35,7 @@ LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:33:70
+  --> $DIR/ref-mut-self-async.rs:31:70
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                             ---------                ^^^^
@@ -44,7 +44,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
    |                                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-self-async.rs:37:70
+  --> $DIR/ref-mut-self-async.rs:35:70
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
    |                                             ---------                ^^^^
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
index cee008de667..2905a022e5d 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:15:56
+  --> $DIR/ref-mut-struct-async.rs:13:56
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                                                        ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:15:61
+  --> $DIR/ref-mut-struct-async.rs:13:61
    |
 LL |       async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |  _______________________________-_____________________________^
@@ -19,7 +19,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:19:65
+  --> $DIR/ref-mut-struct-async.rs:17:65
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                                                 ^^^^
@@ -27,7 +27,7 @@ LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:19:70
+  --> $DIR/ref-mut-struct-async.rs:17:70
    |
 LL |       async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |  _______________________________________-______________________________^
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:23:65
+  --> $DIR/ref-mut-struct-async.rs:21:65
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                                                 ^^^^
@@ -47,7 +47,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:23:70
+  --> $DIR/ref-mut-struct-async.rs:21:70
    |
 LL |       async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |  _______________________________________-______________________________^
@@ -59,7 +59,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:27:74
+  --> $DIR/ref-mut-struct-async.rs:25:74
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                                                          ^^^^
@@ -67,7 +67,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:27:79
+  --> $DIR/ref-mut-struct-async.rs:25:79
    |
 LL |       async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |  _______________________________________________-_______________________________^
@@ -79,7 +79,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-mut-struct-async.rs:31:74
+  --> $DIR/ref-mut-struct-async.rs:29:74
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                                                          ^^^^
@@ -87,7 +87,7 @@ LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-mut-struct-async.rs:31:79
+  --> $DIR/ref-mut-struct-async.rs:29:79
    |
 LL |       async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |  _______________________________________________-_______________________________^
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.rs b/src/test/ui/self/elision/ref-mut-struct-async.rs
index 7a89ef9596a..a671116de25 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.rs
+++ b/src/test/ui/self/elision/ref-mut-struct-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr
index 4c983872942..fe4a636ada6 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:15:56
+  --> $DIR/ref-mut-struct-async.rs:13:56
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                               -----------              ^^^^
@@ -8,7 +8,7 @@ LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
    |                               this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:19:65
+  --> $DIR/ref-mut-struct-async.rs:17:65
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                       -----------               ^^^^
@@ -17,7 +17,7 @@ LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
    |                                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:23:65
+  --> $DIR/ref-mut-struct-async.rs:21:65
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                       -----------               ^^^^
@@ -26,7 +26,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
    |                                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:27:74
+  --> $DIR/ref-mut-struct-async.rs:25:74
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
    |                                               -----------                ^^^^
@@ -35,7 +35,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u
    |                                               this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-mut-struct-async.rs:31:74
+  --> $DIR/ref-mut-struct-async.rs:29:74
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
    |                                               -----------                ^^^^
diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr
index c3c15485b22..0eee56654f7 100644
--- a/src/test/ui/self/elision/ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:24:42
+  --> $DIR/ref-self-async.rs:22:42
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                                          ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:24:47
+  --> $DIR/ref-self-async.rs:22:47
    |
 LL |       async fn ref_self(&self, f: &u32) -> &u32 {
    |  _______________________-_______________________^
@@ -19,7 +19,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:30:48
+  --> $DIR/ref-self-async.rs:28:48
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                                                ^^^^
@@ -27,7 +27,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:30:53
+  --> $DIR/ref-self-async.rs:28:53
    |
 LL |       async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |  _____________________________-_______________________^
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:34:57
+  --> $DIR/ref-self-async.rs:32:57
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
@@ -47,7 +47,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:34:62
+  --> $DIR/ref-self-async.rs:32:62
    |
 LL |       async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |  _____________________________________-________________________^
@@ -59,7 +59,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:38:57
+  --> $DIR/ref-self-async.rs:36:57
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                                         ^^^^
@@ -67,7 +67,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:38:62
+  --> $DIR/ref-self-async.rs:36:62
    |
 LL |       async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |  _____________________________________-________________________^
@@ -79,7 +79,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:42:66
+  --> $DIR/ref-self-async.rs:40:66
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
@@ -87,7 +87,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:42:71
+  --> $DIR/ref-self-async.rs:40:71
    |
 LL |       async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |  _____________________________________________-_________________________^
@@ -99,7 +99,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:46:66
+  --> $DIR/ref-self-async.rs:44:66
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
@@ -107,7 +107,7 @@ LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:46:71
+  --> $DIR/ref-self-async.rs:44:71
    |
 LL |       async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |  _____________________________________________-_________________________^
@@ -119,7 +119,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-self-async.rs:50:69
+  --> $DIR/ref-self-async.rs:48:69
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                                                     ^^^
@@ -127,7 +127,7 @@ LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-self-async.rs:50:73
+  --> $DIR/ref-self-async.rs:48:73
    |
 LL |       async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |  ____________________________________________-____________________________^
diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs
index 5a5705d7e09..06f3b127b21 100644
--- a/src/test/ui/self/elision/ref-self-async.rs
+++ b/src/test/ui/self/elision/ref-self-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr
index eb796a07a86..2f9e2a01e34 100644
--- a/src/test/ui/self/elision/ref-self-async.stderr
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:24:42
+  --> $DIR/ref-self-async.rs:22:42
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       -----              ^^^^
@@ -8,7 +8,7 @@ LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:30:48
+  --> $DIR/ref-self-async.rs:28:48
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             -----              ^^^^
@@ -17,7 +17,7 @@ LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:34:57
+  --> $DIR/ref-self-async.rs:32:57
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     -----               ^^^^
@@ -26,7 +26,7 @@ LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:38:57
+  --> $DIR/ref-self-async.rs:36:57
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     -----               ^^^^
@@ -35,7 +35,7 @@ LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:42:66
+  --> $DIR/ref-self-async.rs:40:66
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ^^^^
@@ -44,7 +44,7 @@ LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:46:66
+  --> $DIR/ref-self-async.rs:44:66
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ^^^^
@@ -53,7 +53,7 @@ LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                             this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:50:69
+  --> $DIR/ref-self-async.rs:48:69
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                            -----                    ^^^
diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr
index ff50f6825bc..8508e42264b 100644
--- a/src/test/ui/self/elision/ref-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr
@@ -1,5 +1,5 @@
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:15:52
+  --> $DIR/ref-struct-async.rs:13:52
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                                                    ^^^^
@@ -7,7 +7,7 @@ LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:15:57
+  --> $DIR/ref-struct-async.rs:13:57
    |
 LL |       async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |  _______________________________-_________________________^
@@ -19,7 +19,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:19:61
+  --> $DIR/ref-struct-async.rs:17:61
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -27,7 +27,7 @@ LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:19:66
+  --> $DIR/ref-struct-async.rs:17:66
    |
 LL |       async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |  _______________________________________-__________________________^
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:23:61
+  --> $DIR/ref-struct-async.rs:21:61
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                                             ^^^^
@@ -47,7 +47,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:23:66
+  --> $DIR/ref-struct-async.rs:21:66
    |
 LL |       async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |  _______________________________________-__________________________^
@@ -59,7 +59,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:27:70
+  --> $DIR/ref-struct-async.rs:25:70
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                                                      ^^^^
@@ -67,7 +67,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:27:75
+  --> $DIR/ref-struct-async.rs:25:75
    |
 LL |       async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |  _______________________________________________-___________________________^
@@ -79,7 +79,7 @@ LL | |     }
    | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-  --> $DIR/ref-struct-async.rs:31:66
+  --> $DIR/ref-struct-async.rs:29:66
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                                                  ^^^^
@@ -87,7 +87,7 @@ LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    = note: hidden type `impl std::future::Future` captures lifetime '_#15r
 
 error: lifetime may not live long enough
-  --> $DIR/ref-struct-async.rs:31:71
+  --> $DIR/ref-struct-async.rs:29:71
    |
 LL |       async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |  ___________________________________________-___________________________^
diff --git a/src/test/ui/self/elision/ref-struct-async.rs b/src/test/ui/self/elision/ref-struct-async.rs
index f0410bbee90..94eaeedc734 100644
--- a/src/test/ui/self/elision/ref-struct-async.rs
+++ b/src/test/ui/self/elision/ref-struct-async.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr
index 574b0fddc1e..222e27ebf0d 100644
--- a/src/test/ui/self/elision/ref-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:15:52
+  --> $DIR/ref-struct-async.rs:13:52
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                               -------              ^^^^
@@ -8,7 +8,7 @@ LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                               this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:19:61
+  --> $DIR/ref-struct-async.rs:17:61
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                       -------               ^^^^
@@ -17,7 +17,7 @@ LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
    |                                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:23:61
+  --> $DIR/ref-struct-async.rs:21:61
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                       -------               ^^^^
@@ -26,7 +26,7 @@ LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
    |                                       this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:27:70
+  --> $DIR/ref-struct-async.rs:25:70
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                               -------                ^^^^
@@ -35,7 +35,7 @@ LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
    |                                               this parameter and the return type are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-struct-async.rs:31:66
+  --> $DIR/ref-struct-async.rs:29:66
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
    |                                           -------                ^^^^
diff --git a/src/test/ui/self/elision/self-async.rs b/src/test/ui/self/elision/self-async.rs
index d1dc050be0d..e1379bfaf2e 100644
--- a/src/test/ui/self/elision/self-async.rs
+++ b/src/test/ui/self/elision/self-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/elision/struct-async.rs b/src/test/ui/self/elision/struct-async.rs
index f7c8591ebd3..4a38a2164c8 100644
--- a/src/test/ui/self/elision/struct-async.rs
+++ b/src/test/ui/self/elision/struct-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 #![feature(arbitrary_self_types)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/self/self_lifetime-async.rs b/src/test/ui/self/self_lifetime-async.rs
index ec4c3d15224..c3c6e56582d 100644
--- a/src/test/ui/self/self_lifetime-async.rs
+++ b/src/test/ui/self/self_lifetime-async.rs
@@ -1,8 +1,6 @@
 // check-pass
 // edition:2018
 
-#![feature(async_await)]
-
 struct Foo<'a>(&'a ());
 impl<'a> Foo<'a> {
     async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 }
diff --git a/src/test/ui/specialization/issue-63716-parse-async.rs b/src/test/ui/specialization/issue-63716-parse-async.rs
new file mode 100644
index 00000000000..c3764ffaab8
--- /dev/null
+++ b/src/test/ui/specialization/issue-63716-parse-async.rs
@@ -0,0 +1,14 @@
+// Ensure that `default async fn` will parse.
+// See issue #63716 for details.
+
+// check-pass
+// edition:2018
+
+#![feature(specialization)]
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl Foo for Bar {
+    default async fn baz() {}
+}
diff --git a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs
index 1c1230346a5..bf0c1dc27ce 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs
+++ b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs
@@ -34,7 +34,7 @@ pub fn main() {
     let vs = &vx;
     let vsm = &mut vec![X(Y)];
 
-    // -------- test for duplicate suggestions --------
+    // test for duplicate suggestions
 
     let &(X(_t), X(_u)) = &(x.clone(), x.clone());
     //~^ ERROR cannot move
diff --git a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs
index 6e3879a4155..f1e043c30f2 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs
+++ b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs
@@ -22,7 +22,7 @@ fn move_into_fn() {
 
     let x = X(Y);
 
-    // -------- move into Fn --------
+    // move into Fn
 
     consume_fn(|| {
         let X(_t) = x;
@@ -89,7 +89,7 @@ fn move_into_fnmut() {
 
     let x = X(Y);
 
-    // -------- move into FnMut --------
+    // move into FnMut
 
     consume_fnmut(|| {
         let X(_t) = x;
diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.rs b/src/test/ui/suggestions/dont-suggest-ref/simple.rs
index 69b303a6623..c53ac3d2cd6 100644
--- a/src/test/ui/suggestions/dont-suggest-ref/simple.rs
+++ b/src/test/ui/suggestions/dont-suggest-ref/simple.rs
@@ -33,7 +33,7 @@ pub fn main() {
     let vs = &vx;
     let vsm = &mut vec![X(Y)];
 
-    // -------- move from Either/X place --------
+    // move from Either/X place
 
     let X(_t) = *s;
     //~^ ERROR cannot move
@@ -163,7 +163,7 @@ pub fn main() {
         // FIXME: should suggest removing `ref` too
     }
 
-    // -------- move from &Either/&X place --------
+    // move from &Either/&X place
 
     let &X(_t) = s;
     //~^ ERROR cannot move
@@ -251,7 +251,7 @@ pub fn main() {
     //~| HELP consider removing the `&mut`
     //~| SUGGESTION X(_t)
 
-    // -------- move from tuple of &Either/&X --------
+    // move from tuple of &Either/&X
 
     // FIXME: These should have suggestions.
 
@@ -283,7 +283,7 @@ pub fn main() {
     fn f4((&mut X(_t),): (&mut X,)) { }
     //~^ ERROR cannot move
 
-    // -------- move from &Either/&X value --------
+    // move from &Either/&X value
 
     let &X(_t) = &x;
     //~^ ERROR cannot move
diff --git a/src/test/ui/suggestions/opaque-type-error.rs b/src/test/ui/suggestions/opaque-type-error.rs
new file mode 100644
index 00000000000..979bb60d48c
--- /dev/null
+++ b/src/test/ui/suggestions/opaque-type-error.rs
@@ -0,0 +1,24 @@
+// edition:2018
+use core::future::Future;
+
+async fn base_thing() -> Result<(), ()> {
+    Ok(())
+}
+
+fn thing_one() -> impl Future<Output = Result<(), ()>> {
+    base_thing()
+}
+
+fn thing_two() -> impl Future<Output = Result<(), ()>> {
+    base_thing()
+}
+
+async fn thing() -> Result<(), ()> {
+    if true {
+        thing_one()
+    } else {
+        thing_two() //~ ERROR if and else have incompatible types
+    }.await
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr
new file mode 100644
index 00000000000..3c9ea05aece
--- /dev/null
+++ b/src/test/ui/suggestions/opaque-type-error.stderr
@@ -0,0 +1,20 @@
+error[E0308]: if and else have incompatible types
+  --> $DIR/opaque-type-error.rs:20:9
+   |
+LL | /     if true {
+LL | |         thing_one()
+   | |         ----------- expected because of this
+LL | |     } else {
+LL | |         thing_two()
+   | |         ^^^^^^^^^^^ expected opaque type, found a different opaque type
+LL | |     }.await
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `impl std::future::Future` (opaque type)
+              found type `impl std::future::Future` (opaque type)
+   = note: distinct uses of `impl Trait` result in different opaque types
+   = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/traits/traits-conditional-model-fn.rs b/src/test/ui/traits/traits-conditional-model-fn.rs
index afdfb96394b..ba88670032c 100644
--- a/src/test/ui/traits/traits-conditional-model-fn.rs
+++ b/src/test/ui/traits/traits-conditional-model-fn.rs
@@ -6,7 +6,6 @@
 
 // aux-build:go_trait.rs
 
-
 extern crate go_trait;
 
 use go_trait::{Go, GoMut, GoOnce, go, go_mut, go_once};
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index 63b6399bb90..c364479d8db 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -5,5 +5,5 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"]
 edition = "2018"
 
 [dependencies]
-toml = "0.4"
+toml = "0.5"
 serde = { version = "1.0", features = ["derive"] }
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject e853aa976543168fbb6bfcc983c35c3facca984
+Subproject 3f700ec43ce72305eb5315cfc710681f3469d4b
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject 72da1015d6d918fe1b29170acbf486d30e0c269
+Subproject 2bcb6155948e2f8b86db08152a5f54bd5af625e
diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml
index 116be234f3c..992af261b83 100644
--- a/src/tools/error_index_generator/Cargo.toml
+++ b/src/tools/error_index_generator/Cargo.toml
@@ -3,10 +3,14 @@ authors = ["The Rust Project Developers"]
 name = "error_index_generator"
 version = "0.0.0"
 edition = "2018"
+build = "build.rs"
 
 [dependencies]
 rustdoc = { path = "../../librustdoc" }
 
+[build-dependencies]
+walkdir = "2"
+
 [[bin]]
 name = "error_index_generator"
 path = "main.rs"
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
new file mode 100644
index 00000000000..2ac7351fce4
--- /dev/null
+++ b/src/tools/error_index_generator/build.rs
@@ -0,0 +1,64 @@
+use walkdir::WalkDir;
+use std::path::PathBuf;
+use std::{env, fs};
+
+fn main() {
+    // The src directory (we are in src/tools/error_index_generator)
+    // Note that we could skip one of the .. but this ensures we at least loosely find the right
+    // directory.
+    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+    let dest = out_dir.join("error_codes.rs");
+    let mut idx = 0;
+    for entry in WalkDir::new("../../../src") {
+        let entry = entry.unwrap();
+        if entry.file_name() == "error_codes.rs" {
+            println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
+            let file = fs::read_to_string(entry.path()).unwrap()
+                .replace("use syntax::{register_diagnostics, register_long_diagnostics};", "")
+                .replace("use syntax::register_diagnostics;", "")
+                .replace("use syntax::register_long_diagnostics;", "");
+            let contents = format!("(|| {{\n{}\n}})();", file);
+
+            fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap();
+
+            idx += 1;
+        }
+    }
+
+    let mut all = String::new();
+    all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n");
+    all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n");
+    all.push_str(r#"
+macro_rules! register_diagnostics {
+    ($($code:tt),*) => {{
+        long_codes.extend([$(
+            stringify!($code),
+        )*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());
+    }};
+    ($($code:tt),*,) => {{
+        long_codes.extend([$(
+            stringify!($code),
+        )*].iter().cloned().map(|s| (s, None)));
+    }}
+}
+
+macro_rules! register_long_diagnostics {
+    ($($code:tt: $description:tt),*) => {
+        {long_codes.extend([$(
+            (stringify!($code), Some(stringify!($description))),
+        )*].iter());}
+    };
+    ($($code:tt: $description:tt),*,) => {
+        {long_codes.extend([$(
+            (stringify!($code), Some(stringify!($description))),
+        )*].iter());}
+    }
+}"#);
+    for idx in 0..idx {
+        all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx));
+    }
+    all.push_str("\nlong_codes\n");
+    all.push_str("}\n");
+
+    fs::write(&dest, all).unwrap();
+}
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index a9d1d9997f6..c4826a0c31d 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -2,22 +2,26 @@
 
 extern crate env_logger;
 extern crate syntax;
-extern crate serialize as rustc_serialize;
 
 use std::collections::BTreeMap;
 use std::env;
 use std::error::Error;
-use std::fs::{self, read_dir, File};
+use std::fs::File;
 use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
 use std::cell::RefCell;
 
 use syntax::edition::DEFAULT_EDITION;
-use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
 
 use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground};
-use rustc_serialize::json;
+
+pub struct ErrorMetadata {
+    pub description: Option<String>,
+}
+
+/// Mapping from error codes to metadata that can be (de)serialized.
+pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
 
 enum OutputFormat {
     HTML(HTMLFormatter),
@@ -80,11 +84,7 @@ impl Formatter for HTMLFormatter {
             Some(_) => "error-described",
             None => "error-undescribed",
         };
-        let use_desc = match info.use_site {
-            Some(_) => "error-used",
-            None => "error-unused",
-        };
-        write!(output, "<div class=\"{} {}\">", desc_desc, use_desc)?;
+        write!(output, "<div class=\"{}\">", desc_desc)?;
 
         // Error title (with self-link).
         write!(output,
@@ -199,25 +199,6 @@ impl Formatter for MarkdownFormatter {
     }
 }
 
-/// Loads all the metadata files from `metadata_dir` into an in-memory map.
-fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> {
-    let mut all_errors = BTreeMap::new();
-
-    for entry in read_dir(metadata_dir)? {
-        let path = entry?.path();
-
-        let metadata_str = fs::read_to_string(&path)?;
-
-        let some_errors: ErrorMetadataMap = json::decode(&metadata_str)?;
-
-        for (err_code, info) in some_errors {
-            all_errors.insert(err_code, info);
-        }
-    }
-
-    Ok(all_errors)
-}
-
 /// Output an HTML page for the errors in `err_map` to `output_path`.
 fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
                                    formatter: T) -> Result<(), Box<dyn Error>> {
@@ -234,9 +215,13 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat
 }
 
 fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
-    let build_arch = env::var("CFG_BUILD")?;
-    let metadata_dir = get_metadata_dir(&build_arch);
-    let err_map = load_all_errors(&metadata_dir)?;
+    let long_codes = register_all();
+    let mut err_map = BTreeMap::new();
+    for (code, desc) in long_codes {
+        err_map.insert(code.to_string(), ErrorMetadata {
+            description: desc.map(String::from),
+        });
+    }
     match format {
         OutputFormat::Unknown(s)  => panic!("Unknown output format: {}", s),
         OutputFormat::HTML(h)     => render_error_page(&err_map, dst, h)?,
@@ -272,3 +257,5 @@ fn main() {
         panic!("{}", e.description());
     }
 }
+
+include!(concat!(env!("OUT_DIR"), "/error_codes.rs"));
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 4f6f264c305ea30f1de90ad0c2f341e84d972b2
+Subproject d77fe6c63ca4c50b207a1161def90c9e57368d5
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index b8dcba3afc3..648838d26ef 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -34,7 +34,7 @@ MAINTAINERS = {
         '@ryankurte @thejpster @therealprof'
     ),
     'edition-guide': '@ehuss @Centril @steveklabnik',
-    'rustc-guide': '@mark-i-m @spastorino'
+    'rustc-guide': '@mark-i-m @spastorino @amanjeev'
 }
 
 REPOS = {
diff --git a/src/tools/rustc-std-workspace-std/Cargo.toml b/src/tools/rustc-std-workspace-std/Cargo.toml
new file mode 100644
index 00000000000..ce1644809db
--- /dev/null
+++ b/src/tools/rustc-std-workspace-std/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "rustc-std-workspace-std"
+version = "1.0.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+license = 'MIT OR Apache-2.0'
+description = """
+Hack for the compiler's own build system
+"""
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+std = { path = "../../libstd" }
diff --git a/src/tools/rustc-std-workspace-std/README.md b/src/tools/rustc-std-workspace-std/README.md
new file mode 100644
index 00000000000..2228907f304
--- /dev/null
+++ b/src/tools/rustc-std-workspace-std/README.md
@@ -0,0 +1,3 @@
+# The `rustc-std-workspace-std` crate
+
+See documentation for the `rustc-std-workspace-core` crate.
diff --git a/src/tools/rustc-std-workspace-std/lib.rs b/src/tools/rustc-std-workspace-std/lib.rs
new file mode 100644
index 00000000000..f40d09cafbb
--- /dev/null
+++ b/src/tools/rustc-std-workspace-std/lib.rs
@@ -0,0 +1 @@
+pub use std::*;
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
-Subproject 0462008de87d2757e8ef1dc26f2c54dd789a59a
+Subproject 9792ff05297c0a5c40942b346c9b0341b9e7c0e
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index de54eb8f573..e07a07234c7 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -90,15 +90,18 @@ const WHITELIST: &[Crate<'_>] = &[
     Crate("crossbeam-epoch"),
     Crate("crossbeam-utils"),
     Crate("datafrog"),
+    Crate("dlmalloc"),
     Crate("either"),
     Crate("ena"),
     Crate("env_logger"),
     Crate("filetime"),
     Crate("flate2"),
+    Crate("fortanix-sgx-abi"),
     Crate("fuchsia-zircon"),
     Crate("fuchsia-zircon-sys"),
     Crate("getopts"),
     Crate("getrandom"),
+    Crate("hashbrown"),
     Crate("humantime"),
     Crate("indexmap"),
     Crate("itertools"),
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 88a469ef955..468e5600101 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -221,7 +221,14 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool {
 }
 
 pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
-    let contents = t!(fs::read_to_string(base_src_path.join("libsyntax/feature_gate.rs")));
+    let mut all = collect_lang_features_in(base_src_path, "active.rs", bad);
+    all.extend(collect_lang_features_in(base_src_path, "accepted.rs", bad));
+    all.extend(collect_lang_features_in(base_src_path, "removed.rs", bad));
+    all
+}
+
+fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features {
+    let contents = t!(fs::read_to_string(base.join("libsyntax/feature_gate").join(file)));
 
     // We allow rustc-internal features to omit a tracking issue.
     // To make tidy accept omitting a tracking issue, group the list of features