about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Cargo.lock3
-rw-r--r--README.md2
-rw-r--r--src/doc/rustc/src/codegen-options/index.md6
-rw-r--r--src/doc/rustc/src/command-line-arguments.md30
-rw-r--r--src/doc/unstable-book/src/language-features/on-unimplemented.md154
-rwxr-xr-xsrc/etc/generate-deriving-span-tests.py3
-rw-r--r--src/liballoc/collections/linked_list.rs2
-rw-r--r--src/liballoc/lib.rs2
-rw-r--r--src/liballoc/rc.rs2
-rw-r--r--src/liballoc/string.rs2
-rw-r--r--src/liballoc/sync.rs2
-rw-r--r--src/libcore/alloc.rs2
-rw-r--r--src/libcore/any.rs6
-rw-r--r--src/libcore/array/iter.rs13
-rw-r--r--src/libcore/array/mod.rs2
-rw-r--r--src/libcore/ascii.rs1
-rw-r--r--src/libcore/benches/ascii.rs2
-rw-r--r--src/libcore/cell.rs11
-rw-r--r--src/libcore/char/convert.rs1
-rw-r--r--src/libcore/char/decode.rs3
-rw-r--r--src/libcore/char/methods.rs2
-rw-r--r--src/libcore/ffi.rs1
-rw-r--r--src/libcore/fmt/float.rs2
-rw-r--r--src/libcore/fmt/mod.rs2
-rw-r--r--src/libcore/fmt/num.rs2
-rw-r--r--src/libcore/hash/mod.rs2
-rw-r--r--src/libcore/hash/sip.rs2
-rw-r--r--src/libcore/hint.rs2
-rw-r--r--src/libcore/iter/adapters/mod.rs14
-rw-r--r--src/libcore/iter/adapters/zip.rs2
-rw-r--r--src/libcore/iter/traits/collect.rs1
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/mem/maybe_uninit.rs66
-rw-r--r--src/libcore/mem/mod.rs19
-rw-r--r--src/libcore/num/dec2flt/algorithm.rs4
-rw-r--r--src/libcore/num/f32.rs2
-rw-r--r--src/libcore/num/f64.rs2
-rw-r--r--src/libcore/num/mod.rs25
-rw-r--r--src/libcore/option.rs2
-rw-r--r--src/libcore/panicking.rs2
-rw-r--r--src/libcore/pin.rs2
-rw-r--r--src/libcore/ptr/mod.rs25
-rw-r--r--src/libcore/ptr/non_null.rs2
-rw-r--r--src/libcore/ptr/unique.rs2
-rw-r--r--src/libcore/slice/memchr.rs2
-rw-r--r--src/libcore/slice/mod.rs61
-rw-r--r--src/libcore/slice/sort.rs2
-rw-r--r--src/libcore/str/lossy.rs2
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/libcore/str/pattern.rs2
-rw-r--r--src/libcore/sync/atomic.rs2
-rw-r--r--src/libcore/tests/num/flt2dec/mod.rs2
-rw-r--r--src/libcore/time.rs2
-rw-r--r--src/libpanic_abort/lib.rs1
-rw-r--r--src/libpanic_unwind/lib.rs1
-rw-r--r--src/librustc/error_codes.rs7
-rw-r--r--src/librustc/hir/lowering.rs20
-rw-r--r--src/librustc/hir/lowering/item.rs25
-rw-r--r--src/librustc/hir/map/def_collector.rs2
-rw-r--r--src/librustc/hir/mod.rs25
-rw-r--r--src/librustc/hir/print.rs4
-rw-r--r--src/librustc/ich/impls_syntax.rs38
-rw-r--r--src/librustc/infer/error_reporting/mod.rs6
-rw-r--r--src/librustc/infer/region_constraints/README.md2
-rw-r--r--src/librustc/lint/context.rs3
-rw-r--r--src/librustc/session/config.rs17
-rw-r--r--src/librustc/ty/codec.rs3
-rw-r--r--src/librustc/ty/layout.rs14
-rw-r--r--src/librustc/ty/print/obsolete.rs26
-rw-r--r--src/librustc/ty/print/pretty.rs25
-rw-r--r--src/librustc_codegen_llvm/back/write.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs10
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs8
-rw-r--r--src/librustc_codegen_llvm/llvm/mod.rs1
-rw-r--r--src/librustc_codegen_llvm/type_of.rs6
-rw-r--r--src/librustc_codegen_ssa/debuginfo/type_names.rs14
-rw-r--r--src/librustc_driver/lib.rs3
-rw-r--r--src/librustc_errors/lib.rs10
-rw-r--r--src/librustc_interface/Cargo.toml4
-rw-r--r--src/librustc_interface/interface.rs2
-rw-r--r--src/librustc_interface/passes.rs3
-rw-r--r--src/librustc_lint/array_into_iter.rs91
-rw-r--r--src/librustc_lint/builtin.rs35
-rw-r--r--src/librustc_lint/lib.rs5
-rw-r--r--src/librustc_lint/types.rs138
-rw-r--r--src/librustc_metadata/creader.rs2
-rw-r--r--src/librustc_metadata/cstore.rs8
-rw-r--r--src/librustc_metadata/lib.rs6
-rw-r--r--src/librustc_metadata/link_args.rs2
-rw-r--r--src/librustc_metadata/locator.rs2
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs (renamed from src/librustc_metadata/decoder.rs)124
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs (renamed from src/librustc_metadata/cstore_impl.rs)9
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs (renamed from src/librustc_metadata/encoder.rs)70
-rw-r--r--src/librustc_metadata/rmeta/mod.rs (renamed from src/librustc_metadata/schema.rs)179
-rw-r--r--src/librustc_metadata/rmeta/table.rs (renamed from src/librustc_metadata/table.rs)21
-rw-r--r--src/librustc_mir/hair/constant.rs5
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs5
-rw-r--r--src/librustc_mir/interpret/cast.rs4
-rw-r--r--src/librustc_mir/interpret/intern.rs22
-rw-r--r--src/librustc_mir/interpret/operand.rs20
-rw-r--r--src/librustc_mir/interpret/place.rs12
-rw-r--r--src/librustc_mir/interpret/validity.rs44
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs530
-rw-r--r--src/librustc_passes/ast_validation.rs2
-rw-r--r--src/librustc_passes/dead.rs17
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs8
-rw-r--r--src/librustc_resolve/macros.rs5
-rw-r--r--src/librustc_save_analysis/Cargo.toml1
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs2
-rw-r--r--src/librustc_save_analysis/lib.rs6
-rw-r--r--src/librustc_save_analysis/sig.rs26
-rw-r--r--src/librustc_save_analysis/span_utils.rs2
-rw-r--r--src/librustc_target/abi/call/mips64.rs6
-rw-r--r--src/librustc_target/abi/call/mod.rs2
-rw-r--r--src/librustc_target/abi/call/x86_64.rs2
-rw-r--r--src/librustc_target/abi/mod.rs58
-rw-r--r--src/librustc_typeck/check/cast.rs5
-rw-r--r--src/librustc_typeck/check/expr.rs36
-rw-r--r--src/librustc_typeck/check/intrinsic.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs157
-rw-r--r--src/librustc_typeck/collect.rs74
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/librustdoc/clean/mod.rs68
-rw-r--r--src/librustdoc/config.rs4
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/librustdoc/html/render.rs99
-rw-r--r--src/librustdoc/html/static/main.js94
-rw-r--r--src/librustdoc/html/static/settings.css14
-rw-r--r--src/librustdoc/html/static/storage.js4
-rw-r--r--src/librustdoc/html/static/themes/dark.css3
-rw-r--r--src/librustdoc/html/static/themes/light.css3
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs2
-rw-r--r--src/libstd/f64.rs18
-rw-r--r--src/libstd/io/buffered.rs7
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/process.rs29
-rw-r--r--src/libstd/sys/sgx/abi/mod.rs1
-rw-r--r--src/libstd/sys/sgx/rwlock.rs3
-rw-r--r--src/libstd/thread/local.rs4
-rw-r--r--src/libstd/thread/mod.rs12
-rw-r--r--src/libsyntax/Cargo.toml1
-rw-r--r--src/libsyntax/ast.rs138
-rw-r--r--src/libsyntax/attr/builtin.rs8
-rw-r--r--src/libsyntax/attr/mod.rs114
-rw-r--r--src/libsyntax/config.rs9
-rw-r--r--src/libsyntax/error_codes.rs1
-rw-r--r--src/libsyntax/feature_gate/active.rs3
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs15
-rw-r--r--src/libsyntax/feature_gate/check.rs80
-rw-r--r--src/libsyntax/feature_gate/removed.rs3
-rw-r--r--src/libsyntax/lib.rs4
-rw-r--r--src/libsyntax/mut_visit.rs14
-rw-r--r--src/libsyntax/parse/lexer/mod.rs26
-rw-r--r--src/libsyntax/parse/lexer/tests.rs3
-rw-r--r--src/libsyntax/parse/lexer/tokentrees.rs5
-rw-r--r--src/libsyntax/parse/lexer/unescape_error_reporting.rs (renamed from src/libsyntax/parse/unescape_error_reporting.rs)0
-rw-r--r--src/libsyntax/parse/lexer/unicode_chars.rs2
-rw-r--r--src/libsyntax/parse/mod.rs40
-rw-r--r--src/libsyntax/parse/parser/attr.rs20
-rw-r--r--src/libsyntax/parse/parser/diagnostics.rs10
-rw-r--r--src/libsyntax/parse/parser/expr.rs36
-rw-r--r--src/libsyntax/parse/parser/generics.rs11
-rw-r--r--src/libsyntax/parse/parser/item.rs43
-rw-r--r--src/libsyntax/parse/parser/mod.rs (renamed from src/libsyntax/parse/parser.rs)78
-rw-r--r--src/libsyntax/parse/parser/module.rs6
-rw-r--r--src/libsyntax/parse/parser/pat.rs22
-rw-r--r--src/libsyntax/parse/parser/path.rs10
-rw-r--r--src/libsyntax/parse/parser/stmt.rs9
-rw-r--r--src/libsyntax/parse/parser/ty.rs6
-rw-r--r--src/libsyntax/parse/tests.rs8
-rw-r--r--src/libsyntax/print/pprust.rs42
-rw-r--r--src/libsyntax/print/pprust/tests.rs7
-rw-r--r--src/libsyntax/sess.rs82
-rw-r--r--src/libsyntax/tests.rs4
-rw-r--r--src/libsyntax/token.rs (renamed from src/libsyntax/parse/token.rs)11
-rw-r--r--src/libsyntax/tokenstream.rs2
-rw-r--r--src/libsyntax/util/classify.rs (renamed from src/libsyntax/parse/classify.rs)0
-rw-r--r--src/libsyntax/util/comments.rs (renamed from src/libsyntax/parse/lexer/comments.rs)24
-rw-r--r--src/libsyntax/util/comments/tests.rs (renamed from src/libsyntax/parse/lexer/comments/tests.rs)0
-rw-r--r--src/libsyntax/util/literal.rs (renamed from src/libsyntax/parse/literal.rs)25
-rw-r--r--src/libsyntax/util/parser.rs2
-rw-r--r--src/libsyntax/visit.rs7
-rw-r--r--src/libsyntax_expand/Cargo.toml1
-rw-r--r--src/libsyntax_expand/base.rs2
-rw-r--r--src/libsyntax_expand/expand.rs24
-rw-r--r--src/libsyntax_expand/mbe.rs2
-rw-r--r--src/libsyntax_expand/mbe/macro_check.rs2
-rw-r--r--src/libsyntax_expand/mbe/macro_parser.rs6
-rw-r--r--src/libsyntax_expand/mbe/macro_rules.rs20
-rw-r--r--src/libsyntax_expand/mbe/quoted.rs2
-rw-r--r--src/libsyntax_expand/mbe/transcribe.rs2
-rw-r--r--src/libsyntax_expand/proc_macro.rs7
-rw-r--r--src/libsyntax_expand/proc_macro_server.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/cmdline_attrs.rs3
-rw-r--r--src/libsyntax_ext/concat.rs3
-rw-r--r--src/libsyntax_ext/concat_idents.rs2
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs31
-rw-r--r--src/libsyntax_ext/format.rs2
-rw-r--r--src/libsyntax_ext/global_asm.rs2
-rw-r--r--src/libsyntax_ext/plugin_macro_defs.rs4
-rw-r--r--src/libsyntax_ext/proc_macro_harness.rs14
-rw-r--r--src/libsyntax_ext/source_util.rs3
-rw-r--r--src/libsyntax_pos/symbol.rs5
-rw-r--r--src/libtest/tests.rs4
-rw-r--r--src/test/codegen/abi-efiapi.rs6
-rw-r--r--src/test/incremental/issue-59523-on-implemented-is-not-unused.rs2
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/Makefile4
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-fun/rustc.rs1
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/Makefile18
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs3
-rw-r--r--src/test/run-make-fulldeps/extern-flag-pathless/foo.rs3
-rw-r--r--src/test/run-make-fulldeps/long-linker-command-lines/foo.rs73
-rw-r--r--src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile3
-rw-r--r--src/test/rustdoc/inline_cross/use_crate.rs2
-rw-r--r--src/test/ui-fulldeps/ast_stmt_expr_attr.rs5
-rw-r--r--src/test/ui-fulldeps/auxiliary/roman-numerals.rs2
-rw-r--r--src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr4
-rw-r--r--src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr4
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.rs10
-rw-r--r--src/test/ui-fulldeps/pathless-extern-unstable.stderr12
-rw-r--r--src/test/ui/abi/abi-sysv64-register-usage.rs1
-rw-r--r--src/test/ui/align-with-extern-c-fn.rs2
-rw-r--r--src/test/ui/async-await/issue-61793.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-53249.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-54974.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-60518.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.rs3
-rw-r--r--src/test/ui/async-await/issues/issue-62009-1.stderr12
-rw-r--r--src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs2
-rw-r--r--src/test/ui/closure-expected-type/issue-24421.rs2
-rw-r--r--src/test/ui/closures/closure-move-sync.rs3
-rw-r--r--src/test/ui/closures/closure-move-sync.stderr8
-rw-r--r--src/test/ui/consts/const-eval/ub-wide-ptr.stderr4
-rw-r--r--src/test/ui/consts/const-size_of-cycle.rs3
-rw-r--r--src/test/ui/consts/const-size_of-cycle.stderr6
-rw-r--r--src/test/ui/consts/const_let_promote.rs17
-rw-r--r--src/test/ui/consts/issue-62045.rs2
-rw-r--r--src/test/ui/consts/promote_borrowed_field.rs12
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Clone-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Clone-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Debug-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Debug-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Default-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Default-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Default-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Default-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Eq-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Eq-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-struct.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Hash-tuple-struct.rs3
-rw-r--r--src/test/ui/derives/derives-span-Hash-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-Ord-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-Ord-tuple-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-enum.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-struct.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr4
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-enum.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-struct.stderr2
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs1
-rw-r--r--src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr2
-rw-r--r--src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs2
-rw-r--r--src/test/ui/enum-discriminant/discriminant_value.rs45
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs2
-rw-r--r--src/test/ui/feature-gated-feature-in-macro-arg.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr4
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi.stderr272
-rw-r--r--src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-intrinsics.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-on-unimplemented.rs9
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr16
-rw-r--r--src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr8
-rw-r--r--src/test/ui/generator/issue-53548-1.rs2
-rw-r--r--src/test/ui/generator/issue-53548.rs2
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.rs3
-rw-r--r--src/test/ui/impl-trait/impl-generic-mismatch.stderr6
-rw-r--r--src/test/ui/impl-trait/issues/issue-42479.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-49376.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-52128.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs2
-rw-r--r--src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs2
-rw-r--r--src/test/ui/impl-trait/trait_type.stderr2
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs3
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr6
-rw-r--r--src/test/ui/imports/issue-53140.rs2
-rw-r--r--src/test/ui/imports/issue-55811.rs2
-rw-r--r--src/test/ui/imports/issue-56263.rs2
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs3
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr2
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.rs3
-rw-r--r--src/test/ui/interior-mutability/interior-mutability.stderr4
-rw-r--r--src/test/ui/issues/issue-10396.rs2
-rw-r--r--src/test/ui/issues/issue-10456.rs2
-rw-r--r--src/test/ui/issues/issue-10763.rs2
-rw-r--r--src/test/ui/issues/issue-10853.rs2
-rw-r--r--src/test/ui/issues/issue-10902.rs2
-rw-r--r--src/test/ui/issues/issue-11384.rs2
-rw-r--r--src/test/ui/issues/issue-11592.rs2
-rw-r--r--src/test/ui/issues/issue-11612.rs2
-rw-r--r--src/test/ui/issues/issue-11869.rs2
-rw-r--r--src/test/ui/issues/issue-1251.rs2
-rw-r--r--src/test/ui/issues/issue-12729.rs2
-rw-r--r--src/test/ui/issues/issue-13105.rs2
-rw-r--r--src/test/ui/issues/issue-13167.rs2
-rw-r--r--src/test/ui/issues/issue-13214.rs2
-rw-r--r--src/test/ui/issues/issue-13405.rs2
-rw-r--r--src/test/ui/issues/issue-13703.rs2
-rw-r--r--src/test/ui/issues/issue-13775.rs2
-rw-r--r--src/test/ui/issues/issue-13837.rs2
-rw-r--r--src/test/ui/issues/issue-14082.rs2
-rw-r--r--src/test/ui/issues/issue-14254.rs2
-rw-r--r--src/test/ui/issues/issue-14330.rs2
-rw-r--r--src/test/ui/issues/issue-14837.rs2
-rw-r--r--src/test/ui/issues/issue-14901.rs2
-rw-r--r--src/test/ui/issues/issue-14933.rs2
-rw-r--r--src/test/ui/issues/issue-14936.rs2
-rw-r--r--src/test/ui/issues/issue-14959.rs2
-rw-r--r--src/test/ui/issues/issue-15108.rs4
-rw-r--r--src/test/ui/issues/issue-15261.rs2
-rw-r--r--src/test/ui/issues/issue-15689-2.rs2
-rw-r--r--src/test/ui/issues/issue-15735.rs2
-rw-r--r--src/test/ui/issues/issue-16441.rs1
-rw-r--r--src/test/ui/issues/issue-16596.rs2
-rw-r--r--src/test/ui/issues/issue-16668.rs2
-rw-r--r--src/test/ui/issues/issue-17121.rs2
-rw-r--r--src/test/ui/issues/issue-17263.rs2
-rw-r--r--src/test/ui/issues/issue-17336.rs2
-rw-r--r--src/test/ui/issues/issue-17450.rs2
-rw-r--r--src/test/ui/issues/issue-17718-const-destructors.rs2
-rw-r--r--src/test/ui/issues/issue-17732.rs2
-rw-r--r--src/test/ui/issues/issue-17746.rs2
-rw-r--r--src/test/ui/issues/issue-17904.rs2
-rw-r--r--src/test/ui/issues/issue-18083.rs2
-rw-r--r--src/test/ui/issues/issue-18088.rs2
-rw-r--r--src/test/ui/issues/issue-18188.rs2
-rw-r--r--src/test/ui/issues/issue-1821.rs2
-rw-r--r--src/test/ui/issues/issue-18446-2.rs2
-rw-r--r--src/test/ui/issues/issue-1866.rs2
-rw-r--r--src/test/ui/issues/issue-18738.rs2
-rw-r--r--src/test/ui/issues/issue-18809.rs2
-rw-r--r--src/test/ui/issues/issue-18906.rs2
-rw-r--r--src/test/ui/issues/issue-18988.rs2
-rw-r--r--src/test/ui/issues/issue-19037.rs2
-rw-r--r--src/test/ui/issues/issue-19081.rs2
-rw-r--r--src/test/ui/issues/issue-19097.rs2
-rw-r--r--src/test/ui/issues/issue-19098.rs2
-rw-r--r--src/test/ui/issues/issue-19102.rs2
-rw-r--r--src/test/ui/issues/issue-19129-1.rs2
-rw-r--r--src/test/ui/issues/issue-19129-2.rs2
-rw-r--r--src/test/ui/issues/issue-19398.rs2
-rw-r--r--src/test/ui/issues/issue-19404.rs2
-rw-r--r--src/test/ui/issues/issue-19479.rs2
-rw-r--r--src/test/ui/issues/issue-19631.rs2
-rw-r--r--src/test/ui/issues/issue-19632.rs2
-rw-r--r--src/test/ui/issues/issue-19850.rs2
-rw-r--r--src/test/ui/issues/issue-19982.rs2
-rw-r--r--src/test/ui/issues/issue-20009.rs2
-rw-r--r--src/test/ui/issues/issue-20091.rs2
-rw-r--r--src/test/ui/issues/issue-20186.rs2
-rw-r--r--src/test/ui/issues/issue-20396.rs2
-rw-r--r--src/test/ui/issues/issue-20414.rs2
-rw-r--r--src/test/ui/issues/issue-20454.rs2
-rw-r--r--src/test/ui/issues/issue-2063-resource.rs2
-rw-r--r--src/test/ui/issues/issue-20644.rs2
-rw-r--r--src/test/ui/issues/issue-20763-1.rs2
-rw-r--r--src/test/ui/issues/issue-20763-2.rs2
-rw-r--r--src/test/ui/issues/issue-20797.rs2
-rw-r--r--src/test/ui/issues/issue-20825-2.rs2
-rw-r--r--src/test/ui/issues/issue-21140.rs2
-rw-r--r--src/test/ui/issues/issue-21160.rs3
-rw-r--r--src/test/ui/issues/issue-21160.stderr2
-rw-r--r--src/test/ui/issues/issue-21174-2.rs2
-rw-r--r--src/test/ui/issues/issue-21245.rs2
-rw-r--r--src/test/ui/issues/issue-21363.rs2
-rw-r--r--src/test/ui/issues/issue-21402.rs2
-rw-r--r--src/test/ui/issues/issue-21520.rs2
-rw-r--r--src/test/ui/issues/issue-21562.rs2
-rw-r--r--src/test/ui/issues/issue-21622.rs2
-rw-r--r--src/test/ui/issues/issue-21634.rs2
-rw-r--r--src/test/ui/issues/issue-21726.rs2
-rw-r--r--src/test/ui/issues/issue-21891.rs2
-rw-r--r--src/test/ui/issues/issue-22066.rs2
-rw-r--r--src/test/ui/issues/issue-22356.rs2
-rw-r--r--src/test/ui/issues/issue-22375.rs2
-rw-r--r--src/test/ui/issues/issue-22471.rs2
-rw-r--r--src/test/ui/issues/issue-22777.rs2
-rw-r--r--src/test/ui/issues/issue-22781.rs2
-rw-r--r--src/test/ui/issues/issue-22814.rs2
-rw-r--r--src/test/ui/issues/issue-22894.rs2
-rw-r--r--src/test/ui/issues/issue-2311-2.rs2
-rw-r--r--src/test/ui/issues/issue-2311.rs2
-rw-r--r--src/test/ui/issues/issue-2312.rs2
-rw-r--r--src/test/ui/issues/issue-23406.rs2
-rw-r--r--src/test/ui/issues/issue-23442.rs2
-rw-r--r--src/test/ui/issues/issue-23550.rs2
-rw-r--r--src/test/ui/issues/issue-23649-3.rs2
-rw-r--r--src/test/ui/issues/issue-24085.rs2
-rw-r--r--src/test/ui/issues/issue-24161.rs2
-rw-r--r--src/test/ui/issues/issue-24227.rs2
-rw-r--r--src/test/ui/issues/issue-24338.rs2
-rw-r--r--src/test/ui/issues/issue-24389.rs2
-rw-r--r--src/test/ui/issues/issue-24434.rs2
-rw-r--r--src/test/ui/issues/issue-2487-a.rs2
-rw-r--r--src/test/ui/issues/issue-2502.rs2
-rw-r--r--src/test/ui/issues/issue-25180.rs2
-rw-r--r--src/test/ui/issues/issue-25394.rs2
-rw-r--r--src/test/ui/issues/issue-25579.rs2
-rw-r--r--src/test/ui/issues/issue-26095.rs2
-rw-r--r--src/test/ui/issues/issue-2611-3.rs2
-rw-r--r--src/test/ui/issues/issue-26205.rs2
-rw-r--r--src/test/ui/issues/issue-26646.rs2
-rw-r--r--src/test/ui/issues/issue-26997.rs3
-rw-r--r--src/test/ui/issues/issue-27033.rs3
-rw-r--r--src/test/ui/issues/issue-27033.stderr4
-rw-r--r--src/test/ui/issues/issue-27105.rs2
-rw-r--r--src/test/ui/issues/issue-27281.rs2
-rw-r--r--src/test/ui/issues/issue-2748-a.rs2
-rw-r--r--src/test/ui/issues/issue-27583.rs2
-rw-r--r--src/test/ui/issues/issue-27889.rs2
-rw-r--r--src/test/ui/issues/issue-2804-2.rs2
-rw-r--r--src/test/ui/issues/issue-28279.rs2
-rw-r--r--src/test/ui/issues/issue-28561.rs2
-rw-r--r--src/test/ui/issues/issue-28600.rs3
-rw-r--r--src/test/ui/issues/issue-28822.rs2
-rw-r--r--src/test/ui/issues/issue-28871.rs2
-rw-r--r--src/test/ui/issues/issue-28936.rs2
-rw-r--r--src/test/ui/issues/issue-28999.rs2
-rw-r--r--src/test/ui/issues/issue-29030.rs2
-rw-r--r--src/test/ui/issues/issue-29037.rs2
-rw-r--r--src/test/ui/issues/issue-2904.rs2
-rw-r--r--src/test/ui/issues/issue-29048.rs2
-rw-r--r--src/test/ui/issues/issue-29071.rs2
-rw-r--r--src/test/ui/issues/issue-29276.rs2
-rw-r--r--src/test/ui/issues/issue-29516.rs2
-rw-r--r--src/test/ui/issues/issue-29540.rs2
-rw-r--r--src/test/ui/issues/issue-29710.rs2
-rw-r--r--src/test/ui/issues/issue-29740.rs2
-rw-r--r--src/test/ui/issues/issue-29743.rs3
-rw-r--r--src/test/ui/issues/issue-31260.rs2
-rw-r--r--src/test/ui/issues/issue-3149.rs2
-rw-r--r--src/test/ui/issues/issue-31597.rs2
-rw-r--r--src/test/ui/issues/issue-32324.rs2
-rw-r--r--src/test/ui/issues/issue-33140-traitobject-crate.rs2
-rw-r--r--src/test/ui/issues/issue-33264.rs2
-rw-r--r--src/test/ui/issues/issue-33287.rs2
-rw-r--r--src/test/ui/issues/issue-3344.stderr2
-rw-r--r--src/test/ui/issues/issue-33903.rs2
-rw-r--r--src/test/ui/issues/issue-34194.rs2
-rw-r--r--src/test/ui/issues/issue-3424.rs2
-rw-r--r--src/test/ui/issues/issue-34751.rs2
-rw-r--r--src/test/ui/issues/issue-34780.rs2
-rw-r--r--src/test/ui/issues/issue-35376.rs2
-rw-r--r--src/test/ui/issues/issue-35546.rs2
-rw-r--r--src/test/ui/issues/issue-3563-2.rs2
-rw-r--r--src/test/ui/issues/issue-36075.rs2
-rw-r--r--src/test/ui/issues/issue-3609.rs2
-rw-r--r--src/test/ui/issues/issue-36744-without-calls.rs2
-rw-r--r--src/test/ui/issues/issue-37323.rs3
-rw-r--r--src/test/ui/issues/issue-37655.rs2
-rw-r--r--src/test/ui/issues/issue-37725.rs2
-rw-r--r--src/test/ui/issues/issue-37733.rs2
-rw-r--r--src/test/ui/issues/issue-38727.rs2
-rw-r--r--src/test/ui/issues/issue-3874.rs2
-rw-r--r--src/test/ui/issues/issue-38763.rs1
-rw-r--r--src/test/ui/issues/issue-38875/issue-38875.rs2
-rw-r--r--src/test/ui/issues/issue-3888-2.rs2
-rw-r--r--src/test/ui/issues/issue-39089.rs2
-rw-r--r--src/test/ui/issues/issue-39467.rs2
-rw-r--r--src/test/ui/issues/issue-3979-2.rs2
-rw-r--r--src/test/ui/issues/issue-3991.rs2
-rw-r--r--src/test/ui/issues/issue-39984.rs2
-rw-r--r--src/test/ui/issues/issue-40136.rs2
-rw-r--r--src/test/ui/issues/issue-4025.rs2
-rw-r--r--src/test/ui/issues/issue-40510-2.rs2
-rw-r--r--src/test/ui/issues/issue-40510-4.rs2
-rw-r--r--src/test/ui/issues/issue-40962.rs2
-rw-r--r--src/test/ui/issues/issue-41272.rs2
-rw-r--r--src/test/ui/issues/issue-41298.rs2
-rw-r--r--src/test/ui/issues/issue-41628.rs2
-rw-r--r--src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs2
-rw-r--r--src/test/ui/issues/issue-41998.rs2
-rw-r--r--src/test/ui/issues/issue-42467.rs2
-rw-r--r--src/test/ui/issues/issue-42956.rs2
-rw-r--r--src/test/ui/issues/issue-43057.rs2
-rw-r--r--src/test/ui/issues/issue-43357.rs2
-rw-r--r--src/test/ui/issues/issue-43398.rs8
-rw-r--r--src/test/ui/issues/issue-43483.rs2
-rw-r--r--src/test/ui/issues/issue-44005.rs2
-rw-r--r--src/test/ui/issues/issue-44056.rs2
-rw-r--r--src/test/ui/issues/issue-44247.rs2
-rw-r--r--src/test/ui/issues/issue-44373-2.rs2
-rw-r--r--src/test/ui/issues/issue-4464.rs2
-rw-r--r--src/test/ui/issues/issue-44730.rs2
-rw-r--r--src/test/ui/issues/issue-44851.rs2
-rw-r--r--src/test/ui/issues/issue-45425.rs2
-rw-r--r--src/test/ui/issues/issue-46959.rs2
-rw-r--r--src/test/ui/issues/issue-46964.rs2
-rw-r--r--src/test/ui/issues/issue-47094.rs6
-rw-r--r--src/test/ui/issues/issue-47309.rs2
-rw-r--r--src/test/ui/issues/issue-47673.rs2
-rw-r--r--src/test/ui/issues/issue-47703-1.rs2
-rw-r--r--src/test/ui/issues/issue-47703-tuple.rs2
-rw-r--r--src/test/ui/issues/issue-47703.rs2
-rw-r--r--src/test/ui/issues/issue-47722.rs2
-rw-r--r--src/test/ui/issues/issue-47789.rs2
-rw-r--r--src/test/ui/issues/issue-4830.rs2
-rw-r--r--src/test/ui/issues/issue-48551.rs2
-rw-r--r--src/test/ui/issues/issue-49556.rs2
-rw-r--r--src/test/ui/issues/issue-49579.rs2
-rw-r--r--src/test/ui/issues/issue-50187.rs2
-rw-r--r--src/test/ui/issues/issue-50411.rs2
-rw-r--r--src/test/ui/issues/issue-50471.rs2
-rw-r--r--src/test/ui/issues/issue-50518.rs2
-rw-r--r--src/test/ui/issues/issue-50761.rs2
-rw-r--r--src/test/ui/issues/issue-50993.rs2
-rw-r--r--src/test/ui/issues/issue-51582.rs2
-rw-r--r--src/test/ui/issues/issue-51655.rs2
-rw-r--r--src/test/ui/issues/issue-51907.rs2
-rw-r--r--src/test/ui/issues/issue-51947.rs2
-rw-r--r--src/test/ui/issues/issue-52992.rs2
-rw-r--r--src/test/ui/issues/issue-53419.rs2
-rw-r--r--src/test/ui/issues/issue-5353.rs2
-rw-r--r--src/test/ui/issues/issue-53568.rs2
-rw-r--r--src/test/ui/issues/issue-53675-a-test-called-panic.rs2
-rw-r--r--src/test/ui/issues/issue-53912.rs2
-rw-r--r--src/test/ui/issues/issue-54387.rs2
-rw-r--r--src/test/ui/issues/issue-54521-1.rs2
-rw-r--r--src/test/ui/issues/issue-54943-1.rs2
-rw-r--r--src/test/ui/issues/issue-54943-2.rs2
-rw-r--r--src/test/ui/issues/issue-54943-3.rs2
-rw-r--r--src/test/ui/issues/issue-5500-1.rs2
-rw-r--r--src/test/ui/issues/issue-5572.rs2
-rw-r--r--src/test/ui/issues/issue-56128.rs2
-rw-r--r--src/test/ui/issues/issue-56202.rs2
-rw-r--r--src/test/ui/issues/issue-56411-aux.rs2
-rw-r--r--src/test/ui/issues/issue-57156.rs2
-rw-r--r--src/test/ui/issues/issue-57162.rs2
-rw-r--r--src/test/ui/issues/issue-57410-1.rs2
-rw-r--r--src/test/ui/issues/issue-57410.rs2
-rw-r--r--src/test/ui/issues/issue-5754.rs2
-rw-r--r--src/test/ui/issues/issue-5884.rs2
-rw-r--r--src/test/ui/issues/issue-5900.rs2
-rw-r--r--src/test/ui/issues/issue-5950.rs2
-rw-r--r--src/test/ui/issues/issue-60662.rs2
-rw-r--r--src/test/ui/issues/issue-60662.stdout2
-rw-r--r--src/test/ui/issues/issue-6341.rs2
-rw-r--r--src/test/ui/issues/issue-6470.rs2
-rw-r--r--src/test/ui/issues/issue-6557.rs2
-rw-r--r--src/test/ui/issues/issue-6898.rs2
-rw-r--r--src/test/ui/issues/issue-6991.rs2
-rw-r--r--src/test/ui/issues/issue-7268.rs2
-rw-r--r--src/test/ui/issues/issue-7607-2.rs2
-rw-r--r--src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs2
-rw-r--r--src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs2
-rw-r--r--src/test/ui/issues/issue-8398.rs2
-rw-r--r--src/test/ui/issues/issue-8521.rs2
-rw-r--r--src/test/ui/issues/issue-8578.rs2
-rw-r--r--src/test/ui/issues/issue-9110.rs2
-rw-r--r--src/test/ui/issues/issue-9243.rs2
-rw-r--r--src/test/ui/issues/issue-9249.rs2
-rw-r--r--src/test/ui/issues/issue-9719.rs2
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.fixed33
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.rs33
-rw-r--r--src/test/ui/iterators/into-iter-on-arrays-lint.stderr37
-rw-r--r--src/test/ui/lint/dead-code/alias-in-pat.rs (renamed from src/test/ui/dead-code-alias-in-pat.rs)0
-rw-r--r--src/test/ui/lint/dead-code/associated-type.rs (renamed from src/test/ui/lint-dead-code-associated-type.rs)0
-rw-r--r--src/test/ui/lint/dead-code/basic.rs (renamed from src/test/ui/fail-no-dead-code.rs)0
-rw-r--r--src/test/ui/lint/dead-code/basic.stderr (renamed from src/test/ui/fail-no-dead-code.stderr)6
-rw-r--r--src/test/ui/lint/dead-code/closure-bang.rs (renamed from src/test/ui/dead-code-closure-bang.rs)0
-rw-r--r--src/test/ui/lint/dead-code/const-and-self.rs (renamed from src/test/ui/lint/lint-dead-code-const-and-self.rs)0
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-enum.rs (renamed from src/test/ui/lint/lint-dead-code-empty-unused-enum.rs)0
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-enum.stderr (renamed from src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr)6
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-public-enum.rs (renamed from src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs)0
-rw-r--r--src/test/ui/lint/dead-code/enum-variants.rs (renamed from src/test/ui/lint-dead-code-variant.rs)0
-rw-r--r--src/test/ui/lint/dead-code/impl-trait.rs (renamed from src/test/ui/lint/lint-dead-code-impl-trait.rs)0
-rw-r--r--src/test/ui/lint/dead-code/impl-trait.stderr (renamed from src/test/ui/lint/lint-dead-code-impl-trait.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/leading-underscore.rs (renamed from src/test/ui/dead-code-leading-underscore.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-1.rs (renamed from src/test/ui/lint/lint-dead-code-1.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-1.stderr (renamed from src/test/ui/lint/lint-dead-code-1.stderr)28
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-2.rs (renamed from src/test/ui/lint/lint-dead-code-2.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-2.stderr (renamed from src/test/ui/lint/lint-dead-code-2.stderr)12
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.rs (renamed from src/test/ui/lint/lint-dead-code-3.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.stderr (renamed from src/test/ui/lint/lint-dead-code-3.stderr)12
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-4.rs (renamed from src/test/ui/lint/lint-dead-code-4.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-4.stderr (renamed from src/test/ui/lint/lint-dead-code-4.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-5.rs (renamed from src/test/ui/lint/lint-dead-code-5.rs)0
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-5.stderr (renamed from src/test/ui/lint/lint-dead-code-5.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/newline-span.rs19
-rw-r--r--src/test/ui/lint/dead-code/newline-span.stderr26
-rw-r--r--src/test/ui/lint/dead-code/tuple-struct-field.rs (renamed from src/test/ui/dead-code-tuple-struct-field.rs)0
-rw-r--r--src/test/ui/lint/dead-code/type-alias.rs (renamed from src/test/ui/lint/lint-dead-code-type-alias.rs)0
-rw-r--r--src/test/ui/lint/dead-code/type-alias.stderr (renamed from src/test/ui/lint/lint-dead-code-type-alias.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/unused-enum.rs (renamed from src/test/ui/lint/lint-dead-code-unused-enum.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-enum.stderr (renamed from src/test/ui/lint/lint-dead-code-unused-enum.stderr)14
-rw-r--r--src/test/ui/lint/dead-code/unused-struct-variant.rs (renamed from src/test/ui/lint/lint-dead-code-unused-variant.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-struct-variant.stderr (renamed from src/test/ui/lint/lint-dead-code-unused-variant.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/unused-variant-pub.rs (renamed from src/test/ui/lint/lint-dead-code-unused-variant-pub.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.rs (renamed from src/test/ui/lint/lint-dead-code-variant.rs)0
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.stderr (renamed from src/test/ui/lint/lint-dead-code-variant.stderr)4
-rw-r--r--src/test/ui/lint/dead-code/with-core-crate.rs (renamed from src/test/ui/fail-no-dead-code-core.rs)0
-rw-r--r--src/test/ui/lint/dead-code/with-core-crate.stderr (renamed from src/test/ui/fail-no-dead-code-core.stderr)6
-rw-r--r--src/test/ui/lint/dead-code/with-impl.rs (renamed from src/test/ui/dead-code-impl.rs)0
-rw-r--r--src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs2
-rw-r--r--src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs2
-rw-r--r--src/test/ui/lint/issue-54099-camel-case-underscore-types.rs2
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.rs186
-rw-r--r--src/test/ui/lint/lint-ctypes-fn.stderr247
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.rs9
-rw-r--r--src/test/ui/lint/uninitialized-zeroed.stderr129
-rw-r--r--src/test/ui/lint/unused_import_warning_issue_45268.rs2
-rw-r--r--src/test/ui/mir/mir_cast_fn_ret.rs2
-rw-r--r--src/test/ui/mir/mir_codegen_calls.rs1
-rw-r--r--src/test/ui/missing/missing-items/m2.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs2
-rw-r--r--src/test/ui/nll/issue-16223.rs2
-rw-r--r--src/test/ui/nll/issue-21114-ebfull.rs2
-rw-r--r--src/test/ui/nll/issue-21114-kixunil.rs2
-rw-r--r--src/test/ui/nll/issue-22323-temp-destruction.rs2
-rw-r--r--src/test/ui/nll/issue-30104.rs2
-rw-r--r--src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs2
-rw-r--r--src/test/ui/nll/issue-43058.rs2
-rw-r--r--src/test/ui/nll/issue-47022.rs2
-rw-r--r--src/test/ui/nll/issue-50716-1.rs2
-rw-r--r--src/test/ui/nll/issue-51351.rs2
-rw-r--r--src/test/ui/nll/issue-52078.rs2
-rw-r--r--src/test/ui/nll/issue-53119.rs2
-rw-r--r--src/test/ui/nll/issue-53570.rs2
-rw-r--r--src/test/ui/nll/issue-55344.rs2
-rw-r--r--src/test/ui/nll/issue-55651.rs2
-rw-r--r--src/test/ui/nll/issue-57280-1.rs2
-rw-r--r--src/test/ui/nll/issue-57280.rs2
-rw-r--r--src/test/ui/nll/issue-61311-normalize.rs2
-rw-r--r--src/test/ui/nll/issue-61320-normalize.rs2
-rw-r--r--src/test/ui/nll/relate_tys/issue-48071.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/issue-53789-1.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/issue-53789-2.rs2
-rw-r--r--src/test/ui/nll/ty-outlives/issue-55756.rs2
-rw-r--r--src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs2
-rw-r--r--src/test/ui/no-send-res-ports.rs3
-rw-r--r--src/test/ui/no-send-res-ports.stderr6
-rw-r--r--src/test/ui/no-warn-on-field-replace-issue-34101.rs2
-rw-r--r--src/test/ui/on-unimplemented/bad-annotation.rs2
-rw-r--r--src/test/ui/on-unimplemented/expected-comma-found-token.rs2
-rw-r--r--src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs8
-rw-r--r--src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr (renamed from src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr)8
-rw-r--r--src/test/ui/on-unimplemented/multiple-impls.rs2
-rw-r--r--src/test/ui/on-unimplemented/on-impl.rs2
-rw-r--r--src/test/ui/on-unimplemented/on-trait.rs2
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.rs4
-rw-r--r--src/test/ui/parser/bad-lit-suffixes.stderr4
-rw-r--r--src/test/ui/parser/extern-abi-from-mac-literal-frag.rs26
-rw-r--r--src/test/ui/parser/extern-abi-raw-strings.rs13
-rw-r--r--src/test/ui/parser/extern-abi-string-escaping.rs13
-rw-r--r--src/test/ui/parser/extern-abi-syntactic.rs17
-rw-r--r--src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs14
-rw-r--r--src/test/ui/path-lookahead.rs8
-rw-r--r--src/test/ui/path-lookahead.stderr24
-rw-r--r--src/test/ui/pathless-extern-ok.rs9
-rw-r--r--src/test/ui/privacy/issue-57264-1.rs2
-rw-r--r--src/test/ui/privacy/issue-57264-2.rs2
-rw-r--r--src/test/ui/proc-macro/dollar-crate-issue-57089.rs2
-rw-r--r--src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs2
-rw-r--r--src/test/ui/resolve/issue-57523.rs2
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs3
-rw-r--r--src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr2
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/issue-54467.rs2
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs2
-rw-r--r--src/test/ui/span/impl-wrong-item-for-trait.stderr2
-rw-r--r--src/test/ui/span/issue-23729.stderr2
-rw-r--r--src/test/ui/span/issue-23827.stderr2
-rw-r--r--src/test/ui/span/issue-24356.stderr2
-rw-r--r--src/test/ui/span/issue-24690.rs2
-rw-r--r--src/test/ui/span/unused-warning-point-at-identifier.rs (renamed from src/test/ui/span/unused-warning-point-at-signature.rs)4
-rw-r--r--src/test/ui/span/unused-warning-point-at-identifier.stderr (renamed from src/test/ui/span/unused-warning-point-at-signature.stderr)25
-rw-r--r--src/test/ui/suggestions/issue-57672.rs2
-rw-r--r--src/test/ui/suggestions/missing-trait-item.fixed20
-rw-r--r--src/test/ui/suggestions/missing-trait-item.rs16
-rw-r--r--src/test/ui/suggestions/missing-trait-item.stderr25
-rw-r--r--src/test/ui/test-attrs/test-warns-dead-code.stderr4
-rw-r--r--src/test/ui/thread-local-not-in-prelude.rs1
-rw-r--r--src/test/ui/traits/trait-suggest-where-clause.rs3
-rw-r--r--src/test/ui/traits/trait-suggest-where-clause.stderr14
-rw-r--r--src/test/ui/traits/traits-issue-23003-overflow.rs2
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-57866.rs2
-rw-r--r--src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs2
-rw-r--r--src/test/ui/type_length_limit.rs3
-rw-r--r--src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs2
-rw-r--r--src/test/ui/unreachable-code-ret.rs (renamed from src/test/ui/dead-code-ret.rs)0
-rw-r--r--src/test/ui/unreachable-code-ret.stderr (renamed from src/test/ui/dead-code-ret.stderr)4
-rw-r--r--src/tools/tidy/src/style.rs17
734 files changed, 3828 insertions, 2758 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 37a217d2a04..bd1d49fb24d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -105,7 +105,7 @@ contributions to the compiler and the standard library. It also lists some
 really useful commands to the build system (`./x.py`), which could save you a
 lot of time.
 
-[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html
+[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/building/how-to-build-and-run.html
 
 ## Pull Requests
 [pull-requests]: #pull-requests
diff --git a/Cargo.lock b/Cargo.lock
index a6dca2048d4..0f770f3eadb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3762,7 +3762,6 @@ dependencies = [
  "rustc",
  "rustc_codegen_utils",
  "rustc_data_structures",
- "rustc_target",
  "serde_json",
  "syntax",
  "syntax_pos",
@@ -4362,7 +4361,6 @@ dependencies = [
  "rustc_errors",
  "rustc_index",
  "rustc_lexer",
- "rustc_target",
  "scoped-tls",
  "serialize",
  "smallvec 1.0.0",
@@ -4380,7 +4378,6 @@ dependencies = [
  "rustc_errors",
  "rustc_index",
  "rustc_lexer",
- "rustc_target",
  "scoped-tls",
  "serialize",
  "smallvec 1.0.0",
diff --git a/README.md b/README.md
index c5468a29248..61d3c9e1157 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ The Rust build system has a Python script called `x.py` to bootstrap building
 the compiler. More information about it may be found by running `./x.py --help`
 or reading the [rustc guide][rustcguidebuild].
 
-[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html
+[rustcguidebuild]: https://rust-lang.github.io/rustc-guide/building/how-to-build-and-run.html
 
 ### Building on *nix
 1. Make sure you have installed the dependencies:
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 70c7acccd36..0dc81378e05 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -197,7 +197,11 @@ in software.
 ## prefer-dynamic
 
 By default, `rustc` prefers to statically link dependencies. This option will
-make it use dynamic linking instead.
+indicate that dynamic linking should be used if possible if both a static and
+dynamic versions of a library are available. There is an internal algorithm
+for determining whether or not it is possible to statically or dynamically
+link with a dependency. For example, `cdylib` crate types may only use static
+linkage.
 
 ## no-integrated-as
 
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 79b4f7542f9..577d03d1038 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -21,8 +21,7 @@ to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.
 <a id="option-l-search-path"></a>
 ## `-L`: add a directory to the library search path
 
-When looking for external crates or libraries, a directory passed to this flag
-will be searched.
+The `-L` flag adds a path to search for external crates and libraries.
 
 The kind of search path can optionally be specified with the form `-L
 KIND=PATH` where `KIND` may be one of:
@@ -262,9 +261,30 @@ This flag, when combined with other flags, makes them produce extra output.
 <a id="option-extern"></a>
 ## `--extern`: specify where an external library is located
 
-This flag allows you to pass the name and location of an external crate that
-will be linked into the crate you are building. This flag may be specified
-multiple times. The format of the value should be `CRATENAME=PATH`.
+This flag allows you to pass the name and location for an external crate of a
+direct dependency. Indirect dependencies (dependencies of dependencies) are
+located using the [`-L` flag](#option-l-search-path). The given crate name is
+added to the [extern prelude], which is the same as specifying `extern crate`
+within the root module. The given crate name does not need to match the name
+the library was built with.
+
+This flag may be specified multiple times. This flag takes an argument with
+either of the following formats:
+
+* `CRATENAME=PATH` — Indicates the given crate is found at the given path.
+* `CRATENAME` — Indicates the given crate may be found in the search path,
+  such as within the sysroot or via the `-L` flag.
+
+The same crate name may be specified multiple times for different crate types.
+If both an `rlib` and `dylib` are found, an internal algorithm is used to
+decide which to use for linking. The [`-C prefer-dynamic`
+flag][prefer-dynamic] may be used to influence which is used.
+
+If the same crate name is specified with and without a path, the one with the
+path is used and the pathless flag has no effect.
+
+[extern prelude]: ../reference/items/extern-crates.html#extern-prelude
+[prefer-dynamic]: codegen-options/index.md#prefer-dynamic
 
 <a id="option-sysroot"></a>
 ## `--sysroot`: Override the system root
diff --git a/src/doc/unstable-book/src/language-features/on-unimplemented.md b/src/doc/unstable-book/src/language-features/on-unimplemented.md
deleted file mode 100644
index 8db241e4b4e..00000000000
--- a/src/doc/unstable-book/src/language-features/on-unimplemented.md
+++ /dev/null
@@ -1,154 +0,0 @@
-# `on_unimplemented`
-
-The tracking issue for this feature is: [#29628]
-
-[#29628]: https://github.com/rust-lang/rust/issues/29628
-
-------------------------
-
-The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]`
-attribute, which allows trait definitions to add specialized notes to error
-messages when an implementation was expected but not found. You can refer
-to the trait's generic arguments by name and to the resolved type using
-`Self`.
-
-For example:
-
-```rust,compile_fail
-#![feature(on_unimplemented)]
-
-#[rustc_on_unimplemented="an iterator over elements of type `{A}` \
-    cannot be built from a collection of type `{Self}`"]
-trait MyIterator<A> {
-    fn next(&mut self) -> A;
-}
-
-fn iterate_chars<I: MyIterator<char>>(i: I) {
-    // ...
-}
-
-fn main() {
-    iterate_chars(&[1, 2, 3][..]);
-}
-```
-
-When the user compiles this, they will see the following;
-
-```txt
-error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
-  --> <anon>:14:5
-   |
-14 |     iterate_chars(&[1, 2, 3][..]);
-   |     ^^^^^^^^^^^^^ an iterator over elements of type `char` cannot be built from a collection of type `&[{integer}]`
-   |
-   = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
-   = note: required by `iterate_chars`
-```
-
-`on_unimplemented` also supports advanced filtering for better targeting
-of messages, as well as modifying specific parts of the error message. You
-target the text of:
-
- - the main error message (`message`)
- - the label (`label`)
- - an extra note (`note`)
-
-For example, the following attribute
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    message="message",
-    label="label",
-    note="note"
-)]
-trait MyIterator<A> {
-    fn next(&mut self) -> A;
-}
-```
-
-Would generate the following output:
-
-```text
-error[E0277]: message
-  --> <anon>:14:5
-   |
-14 |     iterate_chars(&[1, 2, 3][..]);
-   |     ^^^^^^^^^^^^^ label
-   |
-   = note: note
-   = help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
-   = note: required by `iterate_chars`
-```
-
-To allow more targeted error messages, it is possible to filter the
-application of these fields based on a variety of attributes when using
-`on`:
-
- - `crate_local`: whether the code causing the trait bound to not be
-   fulfilled is part of the user's crate. This is used to avoid suggesting
-   code changes that would require modifying a dependency.
- - Any of the generic arguments that can be substituted in the text can be
-   referred by name as well for filtering, like `Rhs="i32"`, except for
-   `Self`.
- - `_Self`: to filter only on a particular calculated trait resolution, like
-   `Self="std::iter::Iterator<char>"`. This is needed because `Self` is a
-   keyword which cannot appear in attributes.
- - `direct`: user-specified rather than derived obligation.
- - `from_method`: usable both as boolean (whether the flag is present, like
-   `crate_local`) or matching against a particular method. Currently used
-   for `try`.
- - `from_desugaring`: usable both as boolean (whether the flag is present)
-   or matching against a particular desugaring. The desugaring is identified
-   with its variant name in the `DesugaringKind` enum.
-
-For example, the `Iterator` trait can be annotated in the following way:
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    on(
-        _Self="&str",
-        note="call `.chars()` or `.as_bytes()` on `{Self}"
-    ),
-    message="`{Self}` is not an iterator",
-    label="`{Self}` is not an iterator",
-    note="maybe try calling `.iter()` or a similar method"
-)]
-pub trait Iterator {}
-```
-
-Which would produce the following outputs:
-
-```text
-error[E0277]: `Foo` is not an iterator
- --> src/main.rs:4:16
-  |
-4 |     for foo in Foo {}
-  |                ^^^ `Foo` is not an iterator
-  |
-  = note: maybe try calling `.iter()` or a similar method
-  = help: the trait `std::iter::Iterator` is not implemented for `Foo`
-  = note: required by `std::iter::IntoIterator::into_iter`
-
-error[E0277]: `&str` is not an iterator
- --> src/main.rs:5:16
-  |
-5 |     for foo in "" {}
-  |                ^^ `&str` is not an iterator
-  |
-  = note: call `.chars()` or `.bytes() on `&str`
-  = help: the trait `std::iter::Iterator` is not implemented for `&str`
-  = note: required by `std::iter::IntoIterator::into_iter`
-```
-
-If you need to filter on multiple attributes, you can use `all`, `any` or
-`not` in the following way:
-
-```rust,compile_fail
-#[rustc_on_unimplemented(
-    on(
-        all(_Self="&str", T="std::string::String"),
-        note="you can coerce a `{T}` into a `{Self}` by writing `&*variable`"
-    )
-)]
-pub trait From<T>: Sized { /* ... */ }
-```
diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
index 66a3c8e5554..39c24fb10e5 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -14,8 +14,7 @@ TEST_DIR = os.path.abspath(
     os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
 
 TEMPLATE = """\
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 {error_deriving}
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index 48f9865b870..a0c9263673d 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -90,7 +90,7 @@ impl<T> Clone for Iter<'_, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T: 'a> {
     // We do *not* exclusively own the entire list here, references to node's `element`
-    // have been handed out by the iterator!  So be careful when using this; the methods
+    // have been handed out by the iterator! So be careful when using this; the methods
     // called must be aware that there can be aliasing pointers to `element`.
     list: &'a mut LinkedList<T>,
     head: Option<NonNull<Node<T>>>,
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 94379afc2bd..ddfa6797a57 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -116,7 +116,7 @@
 #![feature(unsize)]
 #![feature(unsized_locals)]
 #![feature(allocator_internals)]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(rustc_const_unstable)]
 #![feature(slice_partition_dedup)]
 #![feature(maybe_uninit_extra, maybe_uninit_slice)]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index f1c4c32e116..a11f9e8c145 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -280,7 +280,7 @@ struct RcBox<T: ?Sized> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Rc<T: ?Sized> {
     ptr: NonNull<RcBox<T>>,
-    phantom: PhantomData<T>,
+    phantom: PhantomData<RcBox<T>>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index 0e5746d0d9d..f7dff4c21f7 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -687,7 +687,7 @@ impl String {
     /// checked:
     ///
     /// * The memory at `ptr` needs to have been previously allocated by the
-    ///   same allocator the standard library uses.
+    ///   same allocator the standard library uses, with a required alignment of exactly 1.
     /// * `length` needs to be less than or equal to `capacity`.
     /// * `capacity` needs to be the correct value.
     ///
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 80d6c6e0d43..4b10f089c29 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -195,7 +195,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Arc<T: ?Sized> {
     ptr: NonNull<ArcInner<T>>,
-    phantom: PhantomData<T>,
+    phantom: PhantomData<ArcInner<T>>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 5d0333d5226..1b06baeb711 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -1,5 +1,7 @@
 //! Memory allocation APIs
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
 use crate::cmp;
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index e2704e807d1..39a5dd7263c 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -182,6 +182,7 @@ impl dyn Any {
     #[inline]
     pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
         if self.is::<T>() {
+            // SAFETY: just checked whether we are pointing to the correct type
             unsafe {
                 Some(&*(self as *const dyn Any as *const T))
             }
@@ -217,6 +218,7 @@ impl dyn Any {
     #[inline]
     pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
+            // SAFETY: just checked whether we are pointing to the correct type
             unsafe {
                 Some(&mut *(self as *mut dyn Any as *mut T))
             }
@@ -424,7 +426,11 @@ impl TypeId {
     #[rustc_const_unstable(feature="const_type_id")]
     pub const fn of<T: ?Sized + 'static>() -> TypeId {
         TypeId {
+            #[cfg(bootstrap)]
+            // SAFETY: going away soon
             t: unsafe { intrinsics::type_id::<T>() },
+            #[cfg(not(bootstrap))]
+            t: intrinsics::type_id::<T>(),
         }
     }
 }
diff --git a/src/libcore/array/iter.rs b/src/libcore/array/iter.rs
index 11803238407..307e9b90ee2 100644
--- a/src/libcore/array/iter.rs
+++ b/src/libcore/array/iter.rs
@@ -51,7 +51,7 @@ where
     /// iterator (either via `IntoIterator` for arrays or via another way).
     #[unstable(feature = "array_value_iter", issue = "65798")]
     pub fn new(array: [T; N]) -> Self {
-        // The transmute here is actually safe. The docs of `MaybeUninit`
+        // SAFETY: The transmute here is actually safe. The docs of `MaybeUninit`
         // promise:
         //
         // > `MaybeUninit<T>` is guaranteed to have the same size and alignment
@@ -84,10 +84,10 @@ where
     /// Returns an immutable slice of all elements that have not been yielded
     /// yet.
     fn as_slice(&self) -> &[T] {
-        // This transmute is safe. As mentioned in `new`, `MaybeUninit` retains
+        let slice = &self.data[self.alive.clone()];
+        // SAFETY: This transmute is safe. As mentioned in `new`, `MaybeUninit` retains
         // the size and alignment of `T`. Furthermore, we know that all
         // elements within `alive` are properly initialized.
-        let slice = &self.data[self.alive.clone()];
         unsafe {
             mem::transmute::<&[MaybeUninit<T>], &[T]>(slice)
         }
@@ -117,7 +117,8 @@ where
         let idx = self.alive.start;
         self.alive.start += 1;
 
-        // Read the element from the array. This is safe: `idx` is an index
+        // Read the element from the array.
+        // SAFETY: This is safe: `idx` is an index
         // into the "alive" region of the array. Reading this element means
         // that `data[idx]` is regarded as dead now (i.e. do not touch). As
         // `idx` was the start of the alive-zone, the alive zone is now
@@ -163,7 +164,8 @@ where
         // + 1]`.
         self.alive.end -= 1;
 
-        // Read the element from the array. This is safe: `alive.end` is an
+        // Read the element from the array.
+        // SAFETY: This is safe: `alive.end` is an
         // index into the "alive" region of the array. Compare the previous
         // comment that states that the alive region is
         // `data[alive.start..alive.end + 1]`. Reading this element means that
@@ -226,6 +228,7 @@ where
     [T; N]: LengthAtMost32,
 {
     fn clone(&self) -> Self {
+        // SAFETY: each point of unsafety is documented inside the unsafe block
         unsafe {
             // This creates a new uninitialized array. Note that the `assume_init`
             // refers to the array, not the individual elements. And it is Ok if
diff --git a/src/libcore/array/mod.rs b/src/libcore/array/mod.rs
index e1ec8b795d0..74a7d062d3f 100644
--- a/src/libcore/array/mod.rs
+++ b/src/libcore/array/mod.rs
@@ -156,6 +156,7 @@ where
     fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
         if slice.len() == N {
             let ptr = slice.as_ptr() as *const [T; N];
+            // SAFETY: ok because we just checked that the length fits
             unsafe { Ok(&*ptr) }
         } else {
             Err(TryFromSliceError(()))
@@ -173,6 +174,7 @@ where
     fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
         if slice.len() == N {
             let ptr = slice.as_mut_ptr() as *mut [T; N];
+            // SAFETY: ok because we just checked that the length fits
             unsafe { Ok(&mut *ptr) }
         } else {
             Err(TryFromSliceError(()))
diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs
index 4087333e2cf..9b588525bd6 100644
--- a/src/libcore/ascii.rs
+++ b/src/libcore/ascii.rs
@@ -135,6 +135,7 @@ impl FusedIterator for EscapeDefault {}
 #[stable(feature = "ascii_escape_display", since = "1.39.0")]
 impl fmt::Display for EscapeDefault {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // SAFETY: ok because `escape_default` created only valid utf-8 data
         f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) })
     }
 }
diff --git a/src/libcore/benches/ascii.rs b/src/libcore/benches/ascii.rs
index a337c467131..e921dd1ba06 100644
--- a/src/libcore/benches/ascii.rs
+++ b/src/libcore/benches/ascii.rs
@@ -118,6 +118,7 @@ benches! {
     }
 
     fn case07_fake_simd_u32(bytes: &mut [u8]) {
+        // SAFETY: transmuting a sequence of `u8` to `u32` is always fine
         let (before, aligned, after) = unsafe {
             bytes.align_to_mut::<u32>()
         };
@@ -142,6 +143,7 @@ benches! {
     }
 
     fn case08_fake_simd_u64(bytes: &mut [u8]) {
+        // SAFETY: transmuting a sequence of `u8` to `u64` is always fine
         let (before, aligned, after) = unsafe {
             bytes.align_to_mut::<u64>()
         };
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index fda103a52d8..87d8e7aff05 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -137,9 +137,11 @@
 //! use std::cell::Cell;
 //! use std::ptr::NonNull;
 //! use std::intrinsics::abort;
+//! use std::marker::PhantomData;
 //!
 //! struct Rc<T: ?Sized> {
-//!     ptr: NonNull<RcBox<T>>
+//!     ptr: NonNull<RcBox<T>>,
+//!     phantom: PhantomData<RcBox<T>>,
 //! }
 //!
 //! struct RcBox<T: ?Sized> {
@@ -151,7 +153,10 @@
 //! impl<T: ?Sized> Clone for Rc<T> {
 //!     fn clone(&self) -> Rc<T> {
 //!         self.inc_strong();
-//!         Rc { ptr: self.ptr }
+//!         Rc {
+//!             ptr: self.ptr,
+//!             phantom: PhantomData,
+//!         }
 //!     }
 //! }
 //!
@@ -182,6 +187,8 @@
 //! ```
 //!
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::cmp::Ordering;
diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs
index c456e14db12..28f52074495 100644
--- a/src/libcore/char/convert.rs
+++ b/src/libcore/char/convert.rs
@@ -224,6 +224,7 @@ impl TryFrom<u32> for char {
         if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
             Err(CharTryFromError(()))
         } else {
+            // SAFETY: checked that it's a legal unicode value
             Ok(unsafe { from_u32_unchecked(i) })
         }
     }
diff --git a/src/libcore/char/decode.rs b/src/libcore/char/decode.rs
index b71c9c2c40b..ae09251c776 100644
--- a/src/libcore/char/decode.rs
+++ b/src/libcore/char/decode.rs
@@ -87,7 +87,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
         };
 
         if u < 0xD800 || 0xDFFF < u {
-            // not a surrogate
+            // SAFETY: not a surrogate
             Some(Ok(unsafe { from_u32_unchecked(u as u32) }))
         } else if u >= 0xDC00 {
             // a trailing surrogate
@@ -107,6 +107,7 @@ impl<I: Iterator<Item = u16>> Iterator for DecodeUtf16<I> {
 
             // all ok, so lets decode it.
             let c = (((u - 0xD800) as u32) << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
+            // SAFETY: we checked that it's a legal unicode value
             Some(Ok(unsafe { from_u32_unchecked(c) }))
         }
     }
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index 971d89e0044..c048bab287d 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -438,6 +438,7 @@ impl char {
     #[inline]
     pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
         let code = self as u32;
+        // SAFETY: each arm checks the size of the slice and only uses `get_unchecked` unsafe ops
         unsafe {
             let len = if code < MAX_ONE_B && !dst.is_empty() {
                 *dst.get_unchecked_mut(0) = code as u8;
@@ -507,6 +508,7 @@ impl char {
     #[inline]
     pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
         let mut code = self as u32;
+        // SAFETY: each arm checks whether there are enough bits to write into
         unsafe {
             if (code & 0xFFFF) == code && !dst.is_empty() {
                 // The BMP falls through (assuming non-surrogate, as it should)
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index 569c667ac0a..499dd0facd3 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -315,6 +315,7 @@ impl<'f> Clone for VaListImpl<'f> {
     #[inline]
     fn clone(&self) -> Self {
         let mut dest = crate::mem::MaybeUninit::uninit();
+        // SAFETY: we write to the `MaybeUninit`, thus it is initialized and `assume_init` is legal
         unsafe {
             va_copy(dest.as_mut_ptr(), self);
             dest.assume_init()
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index a2fff913ac7..b52b56b1bdb 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -2,6 +2,8 @@ use crate::fmt::{Formatter, Result, LowerExp, UpperExp, Display, Debug};
 use crate::mem::MaybeUninit;
 use crate::num::flt2dec;
 
+// ignore-tidy-undocumented-unsafe
+
 // Don't inline this so callers don't use the stack space this function
 // requires unless they have to.
 #[inline(never)]
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 0e83a282b18..5a039144f66 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1,5 +1,7 @@
 //! Utilities for formatting and printing strings.
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::cell::{UnsafeCell, Cell, RefCell, Ref, RefMut};
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 3b5c9fbff25..3c7aefc090f 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -1,5 +1,7 @@
 //! Integer and floating-point number formatting
 
+// ignore-tidy-undocumented-unsafe
+
 
 use crate::fmt;
 use crate::ops::{Div, Rem, Sub};
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 020e085abf8..0082363692d 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -79,6 +79,8 @@
 //! }
 //! ```
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fmt;
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 19aeafd882e..194d9e6e2f8 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -1,5 +1,7 @@
 //! An implementation of SipHash.
 
+// ignore-tidy-undocumented-unsafe
+
 #![allow(deprecated)] // the types in this module are deprecated
 
 use crate::marker::PhantomData;
diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 368a2f16b28..f68a3e5a76f 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -2,6 +2,8 @@
 
 //! Hints to compiler that affects how code should be emitted or optimized.
 
+// ignore-tidy-undocumented-unsafe
+
 use crate::intrinsics;
 
 /// Informs the compiler that this point in the code is not reachable, enabling
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index 3b8edc2ad61..39d571006e6 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -517,8 +517,18 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
         // overflow handling
         loop {
             let mul = n.checked_mul(step);
-            if unsafe { intrinsics::likely(mul.is_some()) } {
-                return self.iter.nth(mul.unwrap() - 1);
+            #[cfg(bootstrap)]
+            {
+                // SAFETY: going away soon
+                if unsafe { intrinsics::likely(mul.is_some()) } {
+                    return self.iter.nth(mul.unwrap() - 1);
+                }
+            }
+            #[cfg(not(bootstrap))]
+            {
+                if intrinsics::likely(mul.is_some()) {
+                    return self.iter.nth(mul.unwrap() - 1);
+                }
             }
             let div_n = usize::MAX / n;
             let div_step = usize::MAX / step;
diff --git a/src/libcore/iter/adapters/zip.rs b/src/libcore/iter/adapters/zip.rs
index 430ceacdd9f..14d9d5499b8 100644
--- a/src/libcore/iter/adapters/zip.rs
+++ b/src/libcore/iter/adapters/zip.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-undocumented-unsafe
+
 use crate::cmp;
 
 use super::super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen};
diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs
index 00a86417058..bbdb169cac0 100644
--- a/src/libcore/iter/traits/collect.rs
+++ b/src/libcore/iter/traits/collect.rs
@@ -205,6 +205,7 @@ pub trait FromIterator<A>: Sized {
 ///         .collect()
 /// }
 /// ```
+#[rustc_diagnostic_item = "IntoIterator"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait IntoIterator {
     /// The type of the elements being iterated over.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 1b67b05c730..ca431627147 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -89,7 +89,7 @@
 #![feature(nll)]
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(optin_builtin_traits)]
 #![feature(prelude_import)]
 #![feature(repr_simd, platform_intrinsics)]
diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs
index 51ba260589f..d35a5ce57fe 100644
--- a/src/libcore/mem/maybe_uninit.rs
+++ b/src/libcore/mem/maybe_uninit.rs
@@ -1,6 +1,8 @@
 use crate::intrinsics;
 use crate::mem::ManuallyDrop;
 
+// ignore-tidy-undocumented-unsafe
+
 /// A wrapper type to construct uninitialized instances of `T`.
 ///
 /// # Initialization invariant
@@ -258,6 +260,43 @@ impl<T> MaybeUninit<T> {
         MaybeUninit { uninit: () }
     }
 
+    /// Create a new array of `MaybeUninit<T>` items, in an uninitialized state.
+    ///
+    /// Note: in a future Rust version this method may become unnecessary
+    /// when array literal syntax allows
+    /// [repeating const expressions](https://github.com/rust-lang/rust/issues/49147).
+    /// The example below could then use `let mut buf = [MaybeUninit::<u8>::uninit(); 32];`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)]
+    ///
+    /// use std::mem::MaybeUninit;
+    ///
+    /// extern "C" {
+    ///     fn read_into_buffer(ptr: *mut u8, max_len: usize) -> usize;
+    /// }
+    ///
+    /// /// Returns a (possibly smaller) slice of data that was actually read
+    /// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
+    ///     unsafe {
+    ///         let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
+    ///         MaybeUninit::slice_get_ref(&buf[..len])
+    ///     }
+    /// }
+    ///
+    /// let mut buf: [MaybeUninit<u8>; 32] = MaybeUninit::uninit_array();
+    /// let data = read(&mut buf);
+    /// ```
+    #[unstable(feature = "maybe_uninit_uninit_array", issue = "0")]
+    #[inline(always)]
+    pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
+        unsafe {
+            MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init()
+        }
+    }
+
     /// A promotable constant, equivalent to `uninit()`.
     #[unstable(feature = "internal_uninit_const", issue = "0",
         reason = "hack to work around promotability")]
@@ -440,6 +479,7 @@ impl<T> MaybeUninit<T> {
     /// ```
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
     #[inline(always)]
+    #[cfg_attr(all(not(bootstrap)), rustc_diagnostic_item = "assume_init")]
     pub unsafe fn assume_init(self) -> T {
         intrinsics::panic_if_uninhabited::<T>();
         ManuallyDrop::into_inner(self.value)
@@ -689,6 +729,32 @@ impl<T> MaybeUninit<T> {
         &mut *self.value
     }
 
+    /// Assuming all the elements are initialized, get a slice to them.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
+    /// really are in an initialized state.
+    /// Calling this when the content is not yet fully initialized causes undefined behavior.
+    #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")]
+    #[inline(always)]
+    pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] {
+        &*(slice as *const [Self] as *const [T])
+    }
+
+    /// Assuming all the elements are initialized, get a mutable slice to them.
+    ///
+    /// # Safety
+    ///
+    /// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
+    /// really are in an initialized state.
+    /// Calling this when the content is not yet fully initialized causes undefined behavior.
+    #[unstable(feature = "maybe_uninit_slice_assume_init", issue = "0")]
+    #[inline(always)]
+    pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] {
+        &mut *(slice as *mut [Self] as *mut [T])
+    }
+
     /// Gets a pointer to the first element of the array.
     #[unstable(feature = "maybe_uninit_slice", issue = "63569")]
     #[inline(always)]
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index c7da56aad30..26909be9496 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -93,6 +93,8 @@ pub fn forget<T>(t: T) {
 #[inline]
 #[unstable(feature = "forget_unsized", issue = "0")]
 pub fn forget_unsized<T: ?Sized>(t: T) {
+    // SAFETY: the forget intrinsic could be safe, but there's no point in making it safe since
+    // we'll be implementing this function soon via `ManuallyDrop`
     unsafe { intrinsics::forget(t) }
 }
 
@@ -266,7 +268,11 @@ pub const fn size_of<T>() -> usize {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn size_of_val<T: ?Sized>(val: &T) -> usize {
+    #[cfg(bootstrap)]
+    // SAFETY: going away soon
     unsafe { intrinsics::size_of_val(val) }
+    #[cfg(not(bootstrap))]
+    intrinsics::size_of_val(val)
 }
 
 /// Returns the [ABI]-required minimum alignment of a type.
@@ -310,7 +316,11 @@ pub fn min_align_of<T>() -> usize {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(reason = "use `align_of_val` instead", since = "1.2.0")]
 pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
+    #[cfg(bootstrap)]
+    // SAFETY: going away soon
     unsafe { intrinsics::min_align_of_val(val) }
+    #[cfg(not(bootstrap))]
+    intrinsics::min_align_of_val(val)
 }
 
 /// Returns the [ABI]-required minimum alignment of a type.
@@ -350,8 +360,9 @@ pub const fn align_of<T>() -> usize {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
-    unsafe { intrinsics::min_align_of_val(val) }
+    min_align_of_val(val)
 }
 
 /// Returns `true` if dropping values of type `T` matters.
@@ -508,6 +519,8 @@ pub unsafe fn uninitialized<T>() -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn swap<T>(x: &mut T, y: &mut T) {
+    // SAFETY: the raw pointers have been created from safe mutable references satisfying all the
+    // constraints on `ptr::swap_nonoverlapping_one`
     unsafe {
         ptr::swap_nonoverlapping_one(x, y);
     }
@@ -822,7 +835,11 @@ impl<T> fmt::Debug for Discriminant<T> {
 /// ```
 #[stable(feature = "discriminant_value", since = "1.21.0")]
 pub fn discriminant<T>(v: &T) -> Discriminant<T> {
+    #[cfg(bootstrap)]
+    // SAFETY: going away soon
     unsafe {
         Discriminant(intrinsics::discriminant_value(v), PhantomData)
     }
+    #[cfg(not(bootstrap))]
+    Discriminant(intrinsics::discriminant_value(v), PhantomData)
 }
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index ed89852dc48..64146302626 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -58,6 +58,8 @@ mod fpu_precision {
     pub struct FPUControlWord(u16);
 
     fn set_cw(cw: u16) {
+        // SAFETY: the `fldcw` instruction has been audited to be able to work correctly with
+        // any `u16`
         unsafe { asm!("fldcw $0" :: "m" (cw) :: "volatile") }
     }
 
@@ -74,6 +76,8 @@ mod fpu_precision {
 
         // Get the original value of the control word to restore it later, when the
         // `FPUControlWord` structure is dropped
+        // SAFETY: the `fnstcw` instruction has been audited to be able to work correctly with
+        // any `u16`
         unsafe { asm!("fnstcw $0" : "=*m" (&cw) ::: "volatile") }
 
         // Set the control word to the desired precision. This is achieved by masking away the old
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 5730088c4d9..7662bba6b5e 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -414,6 +414,7 @@ impl f32 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn to_bits(self) -> u32 {
+        // SAFETY: `u32` is a plain old datatype so we can always transmute to it
         unsafe { mem::transmute(self) }
     }
 
@@ -456,6 +457,7 @@ impl f32 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn from_bits(v: u32) -> Self {
+        // SAFETY: `u32` is a plain old datatype so we can always transmute from it
         // It turns out the safety issues with sNaN were overblown! Hooray!
         unsafe { mem::transmute(v) }
     }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 2bdeda340dc..4a2a35dfb09 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -427,6 +427,7 @@ impl f64 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn to_bits(self) -> u64 {
+        // SAFETY: `u64` is a plain old datatype so we can always transmute to it
         unsafe { mem::transmute(self) }
     }
 
@@ -469,6 +470,7 @@ impl f64 {
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
     #[inline]
     pub fn from_bits(v: u64) -> Self {
+        // SAFETY: `u64` is a plain old datatype so we can always transmute from it
         // It turns out the safety issues with sNaN were overblown! Hooray!
         unsafe { mem::transmute(v) }
     }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index b4ade704144..4b9e82c7cfe 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -71,6 +71,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
                 #[inline]
                 pub fn new(n: $Int) -> Option<Self> {
                     if n != 0 {
+                        // SAFETY: we just checked that there's no `0`
                         Some(unsafe { $Ty(n) })
                     } else {
                         None
@@ -703,6 +704,7 @@ $EndFeature, "
                 if rhs == 0 || (self == Self::min_value() && rhs == -1) {
                     None
                 } else {
+                    // SAFETY: div by zero and by INT_MIN have been checked above
                     Some(unsafe { intrinsics::unchecked_div(self, rhs) })
                 }
             }
@@ -759,6 +761,7 @@ $EndFeature, "
                 if rhs == 0 || (self == Self::min_value() && rhs == -1) {
                     None
                 } else {
+                    // SAFETY: div by zero and by INT_MIN have been checked above
                     Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                 }
             }
@@ -1329,6 +1332,8 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shl(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -1358,6 +1363,8 @@ $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shr(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -2113,6 +2120,8 @@ assert_eq!(
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+                // SAFETY: integers are plain old datatypes so we can always transmute them to
+                // arrays of bytes
                 unsafe { mem::transmute(self) }
             }
         }
@@ -2221,6 +2230,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+                // SAFETY: integers are plain old datatypes so we can always transmute to them
                 unsafe { mem::transmute(bytes) }
             }
         }
@@ -2748,6 +2758,8 @@ assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
             pub fn checked_div(self, rhs: Self) -> Option<Self> {
                 match rhs {
                     0 => None,
+                    // SAFETY: div by zero has been checked above and unsigned types have no other
+                    // failure modes for division
                     rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }),
                 }
             }
@@ -2799,6 +2811,8 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
                 if rhs == 0 {
                     None
                 } else {
+                    // SAFETY: div by zero has been checked above and unsigned types have no other
+                    // failure modes for division
                     Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
                 }
             }
@@ -3248,6 +3262,8 @@ assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shl(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shl(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -3279,6 +3295,8 @@ assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
                           without modifying the original"]
             #[inline]
             pub const fn wrapping_shr(self, rhs: u32) -> Self {
+                // SAFETY: the masking by the bitsize of the type ensures that we do not shift
+                // out of bounds
                 unsafe {
                     intrinsics::unchecked_shr(self, (rhs & ($BITS - 1)) as $SelfT)
                 }
@@ -3775,11 +3793,11 @@ assert!(!10", stringify!($SelfT), ".is_power_of_two());", $EndFeature, "
         fn one_less_than_next_power_of_two(self) -> Self {
             if self <= 1 { return 0; }
 
-            // Because `p > 0`, it cannot consist entirely of leading zeros.
+            let p = self - 1;
+            // SAFETY: Because `p > 0`, it cannot consist entirely of leading zeros.
             // That means the shift is always in-bounds, and some processors
             // (such as intel pre-haswell) have more efficient ctlz
             // intrinsics when the argument is non-zero.
-            let p = self - 1;
             let z = unsafe { intrinsics::ctlz_nonzero(p) };
             <$SelfT>::max_value() >> z
         }
@@ -3925,6 +3943,8 @@ assert_eq!(
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+                // SAFETY: integers are plain old datatypes so we can always transmute them to
+                // arrays of bytes
                 unsafe { mem::transmute(self) }
             }
         }
@@ -4033,6 +4053,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
             #[rustc_const_unstable(feature = "const_int_conversion")]
             #[inline]
             pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+                // SAFETY: integers are plain old datatypes so we can always transmute to them
                 unsafe { mem::transmute(bytes) }
             }
         }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index f0ac5e749f6..958f31c0fd2 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -133,6 +133,8 @@
 //! [`Box<T>`]: ../../std/boxed/struct.Box.html
 //! [`i32`]: ../../std/primitive.i32.html
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::iter::{FromIterator, FusedIterator, TrustedLen};
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 685b749776b..b88dc336097 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -20,6 +20,8 @@
 //! one function. Currently, the actual symbol is declared in the standard
 //! library, but the location of this may change over time.
 
+// ignore-tidy-undocumented-unsafe
+
 #![allow(dead_code, missing_docs)]
 #![unstable(feature = "core_panic",
             reason = "internal details of the implementation of the `panic!` \
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index be057ed6d59..1219fd09a9d 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -552,6 +552,7 @@ impl<P: Deref> Pin<P> {
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_ref(&self) -> Pin<&P::Target> {
+        // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&*self.pointer) }
     }
 
@@ -610,6 +611,7 @@ impl<P: DerefMut> Pin<P> {
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_mut(&mut self) -> Pin<&mut P::Target> {
+        // SAFETY: see documentation on this function
         unsafe { Pin::new_unchecked(&mut *self.pointer) }
     }
 
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 1355ce1aa43..5a75730cf2b 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -18,6 +18,10 @@
 //! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
 //! * All pointers (except for the null pointer) are valid for all operations of
 //!   [size zero][zst].
+//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer
+//!   be *dereferencable*: the memory range of the given size starting at the pointer must all be
+//!   within the bounds of a single allocated object. Note that in Rust,
+//!   every (stack-allocated) variable is considered a separate allocated object.
 //! * All accesses performed by functions in this module are *non-atomic* in the sense
 //!   of [atomic operations] used to synchronize between threads. This means it is
 //!   undefined behavior to perform two concurrent accesses to the same location from different
@@ -61,6 +65,8 @@
 //! [`write_volatile`]: ./fn.write_volatile.html
 //! [`NonNull::dangling`]: ./struct.NonNull.html#method.dangling
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::intrinsics;
@@ -221,10 +227,15 @@ pub(crate) struct FatPtr<T> {
     pub(crate) len: usize,
 }
 
-/// Forms a slice from a pointer and a length.
+/// Forms a raw slice from a pointer and a length.
 ///
 /// The `len` argument is the number of **elements**, not the number of bytes.
 ///
+/// This function is safe, but actually using the return value is unsafe.
+/// See the documentation of [`from_raw_parts`] for slice safety requirements.
+///
+/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
+///
 /// # Examples
 ///
 /// ```rust
@@ -243,12 +254,16 @@ pub fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
     unsafe { Repr { raw: FatPtr { data, len } }.rust }
 }
 
-/// Performs the same functionality as [`from_raw_parts`], except that a
-/// mutable slice is returned.
+/// Performs the same functionality as [`slice_from_raw_parts`], except that a
+/// raw mutable slice is returned, as opposed to a raw immutable slice.
 ///
-/// See the documentation of [`from_raw_parts`] for more details.
+/// See the documentation of [`slice_from_raw_parts`] for more details.
 ///
-/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
+/// This function is safe, but actually using the return value is unsafe.
+/// See the documentation of [`from_raw_parts_mut`] for slice safety requirements.
+///
+/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
+/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
 #[inline]
 #[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")]
 pub fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index 7dcd57f1f98..7599991f0f1 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -7,6 +7,8 @@ use crate::mem;
 use crate::ptr::Unique;
 use crate::cmp::Ordering;
 
+// ignore-tidy-undocumented-unsafe
+
 /// `*mut T` but non-zero and covariant.
 ///
 /// This is often the correct thing to use when building data structures using
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index 3521dd79979..11a3aed1ab4 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -5,6 +5,8 @@ use crate::marker::{PhantomData, Unsize};
 use crate::mem;
 use crate::ptr::NonNull;
 
+// ignore-tidy-undocumented-unsafe
+
 /// A wrapper around a raw non-null `*mut T` that indicates that the possessor
 /// of this wrapper owns the referent. Useful for building abstractions like
 /// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs
index 45ab016c496..2a2169dd348 100644
--- a/src/libcore/slice/memchr.rs
+++ b/src/libcore/slice/memchr.rs
@@ -1,6 +1,8 @@
 // Original implementation taken from rust-memchr.
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
+// ignore-tidy-undocumented-unsafe
+
 use crate::cmp;
 use crate::mem;
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index cdada1252d2..c8fe9f98613 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-filelength
+// ignore-tidy-undocumented-unsafe
 
 //! Slice management and manipulation.
 //!
@@ -5272,18 +5273,24 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 ///
 /// # Safety
 ///
-/// This function is unsafe as there is no guarantee that the given pointer is
-/// valid for `len` elements, nor whether the lifetime inferred is a suitable
-/// lifetime for the returned slice.
+/// Behavior is undefined if any of the following conditions are violated:
 ///
-/// `data` must be non-null and aligned, even for zero-length slices. One
-/// reason for this is that enum layout optimizations may rely on references
-/// (including slices of any length) being aligned and non-null to distinguish
-/// them from other data. You can obtain a pointer that is usable as `data`
-/// for zero-length slices using [`NonNull::dangling()`].
+/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
+///   and it must be properly aligned. This means in particular:
 ///
-/// The total size of the slice must be no larger than `isize::MAX` **bytes**
-/// in memory. See the safety documentation of [`pointer::offset`].
+///     * The entire memory range of this slice must be contained within a single allocated object!
+///       Slices can never span across multiple allocated objects.
+///     * `data` must be non-null and aligned even for zero-length slices. One
+///       reason for this is that enum layout optimizations may rely on references
+///       (including slices of any length) being aligned and non-null to distinguish
+///       them from other data. You can obtain a pointer that is usable as `data`
+///       for zero-length slices using [`NonNull::dangling()`].
+///
+/// * The memory referenced by the returned slice must not be mutated for the duration
+///   of lifetime `'a`, except inside an `UnsafeCell`.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+///   See the safety documentation of [`pointer::offset`].
 ///
 /// # Caveat
 ///
@@ -5305,6 +5312,7 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 /// assert_eq!(slice[0], 42);
 /// ```
 ///
+/// [valid]: ../../std/ptr/index.html#safety
 /// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
 /// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
 #[inline]
@@ -5312,28 +5320,45 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
 pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
     debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
     debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
-                  "attempt to create slice covering half the address space");
+                  "attempt to create slice covering at least half the address space");
     &*ptr::slice_from_raw_parts(data, len)
 }
 
 /// Performs the same functionality as [`from_raw_parts`], except that a
 /// mutable slice is returned.
 ///
-/// This function is unsafe for the same reasons as [`from_raw_parts`], as well
-/// as not being able to provide a non-aliasing guarantee of the returned
-/// mutable slice. `data` must be non-null and aligned even for zero-length
-/// slices as with [`from_raw_parts`]. The total size of the slice must be no
-/// larger than `isize::MAX` **bytes** in memory.
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `data` must be [valid] for writes for `len * mem::size_of::<T>()` many bytes,
+///   and it must be properly aligned. This means in particular:
 ///
-/// See the documentation of [`from_raw_parts`] for more details.
+///     * The entire memory range of this slice must be contained within a single allocated object!
+///       Slices can never span across multiple allocated objects.
+///     * `data` must be non-null and aligned even for zero-length slices. One
+///       reason for this is that enum layout optimizations may rely on references
+///       (including slices of any length) being aligned and non-null to distinguish
+///       them from other data. You can obtain a pointer that is usable as `data`
+///       for zero-length slices using [`NonNull::dangling()`].
 ///
+/// * The memory referenced by the returned slice must not be accessed through any other pointer
+///   (not derived from the return value) for the duration of lifetime `'a`.
+///   Both read and write accesses are forbidden.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+///   See the safety documentation of [`pointer::offset`].
+///
+/// [valid]: ../../std/ptr/index.html#safety
+/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
+/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
 /// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
     debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
     debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
-                  "attempt to create slice covering half the address space");
+                  "attempt to create slice covering at least half the address space");
     &mut *ptr::slice_from_raw_parts_mut(data, len)
 }
 
diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs
index 2f2170f7ff1..a719a51b616 100644
--- a/src/libcore/slice/sort.rs
+++ b/src/libcore/slice/sort.rs
@@ -6,6 +6,8 @@
 //! Unstable sorting is compatible with libcore because it doesn't allocate memory, unlike our
 //! stable sorting implementation.
 
+// ignore-tidy-undocumented-unsafe
+
 use crate::cmp;
 use crate::mem::{self, MaybeUninit};
 use crate::ptr;
diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs
index e8f747f1a67..762de0489a9 100644
--- a/src/libcore/str/lossy.rs
+++ b/src/libcore/str/lossy.rs
@@ -3,6 +3,8 @@ use crate::str as core_str;
 use crate::fmt::{self, Write};
 use crate::mem;
 
+// ignore-tidy-undocumented-unsafe
+
 /// Lossy UTF-8 string.
 #[unstable(feature = "str_internals", issue = "0")]
 pub struct Utf8Lossy {
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 1968919f554..25b7eec5b33 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1,4 +1,5 @@
 // ignore-tidy-filelength
+// ignore-tidy-undocumented-unsafe
 
 //! String manipulation.
 //!
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index ad9d956fda1..a494274118a 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -3,6 +3,8 @@
 //! For more details, see the traits [`Pattern`], [`Searcher`],
 //! [`ReverseSearcher`], and [`DoubleEndedSearcher`].
 
+// ignore-tidy-undocumented-unsafe
+
 #![unstable(feature = "pattern",
             reason = "API not fully fleshed out and ready to be stabilized",
             issue = "27721")]
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 73d5abf1aed..d311cb16b64 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -112,6 +112,8 @@
 //! println!("live threads: {}", old_thread_count + 1);
 //! ```
 
+// ignore-tidy-undocumented-unsafe
+
 #![stable(feature = "rust1", since = "1.0.0")]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))]
 #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))]
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
index c41d35efced..a35897e9bc1 100644
--- a/src/libcore/tests/num/flt2dec/mod.rs
+++ b/src/libcore/tests/num/flt2dec/mod.rs
@@ -85,6 +85,8 @@ fn ldexp_f64(a: f64, b: i32) -> f64 {
     extern {
         fn ldexp(x: f64, n: i32) -> f64;
     }
+    // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
+    // cause undefined behavior
     unsafe { ldexp(a, b) }
 }
 
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 5a0e4388e03..57fc1a7b760 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -920,7 +920,7 @@ impl fmt::Debug for Duration {
             if end == 0 {
                 write!(f, "{}", integer_part)
             } else {
-                // We are only writing ASCII digits into the buffer and it was
+                // SAFETY: We are only writing ASCII digits into the buffer and it was
                 // initialized with '0's, so it contains valid UTF8.
                 let s = unsafe {
                     crate::str::from_utf8_unchecked(&buf[..end])
diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs
index 5509f47bc88..bc9dd2edaf2 100644
--- a/src/libpanic_abort/lib.rs
+++ b/src/libpanic_abort/lib.rs
@@ -21,6 +21,7 @@
 // Rust's "try" function, but if we're aborting on panics we just call the
 // function as there's nothing else we need to do here.
 #[rustc_std_internal_symbol]
+#[allow(improper_ctypes)]
 pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                               data: *mut u8,
                                               _data_ptr: *mut usize,
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index d2a0ef7b1dd..7de347446ad 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -69,6 +69,7 @@ mod dwarf;
 // hairy and tightly coupled, for more information see the compiler's
 // implementation of this.
 #[no_mangle]
+#[allow(improper_ctypes)]
 pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                                   data: *mut u8,
                                                   data_ptr: *mut usize,
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index f5ff92e69bc..f40b892a06b 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -607,7 +607,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -639,7 +639,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -669,7 +669,7 @@ position that needs that trait. For example, when the following code is
 compiled:
 
 ```compile_fail
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 fn foo<T: Index<u8>>(x: T){}
 
@@ -2336,6 +2336,7 @@ the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
     E0657, // `impl Trait` can only capture lifetimes bound at the fn level
     E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
+    E0703, // invalid ABI
 //  E0707, // multiple elided lifetimes used in arguments of `async fn`
     E0708, // `async` non-`move` closures with parameters are not currently
            // supported
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 9f5e5fae07f..278f45371b1 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -65,7 +65,7 @@ use syntax::ptr::P as AstP;
 use syntax::ast::*;
 use syntax::errors;
 use syntax::print::pprust;
-use syntax::parse::token::{self, Nonterminal, Token};
+use syntax::token::{self, Nonterminal, Token};
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::sess::ParseSess;
 use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
@@ -995,14 +995,20 @@ impl<'a> LoweringContext<'a> {
         // Note that we explicitly do not walk the path. Since we don't really
         // lower attributes (we use the AST version) there is nowhere to keep
         // the `HirId`s. We don't actually need HIR version of attributes anyway.
+        let kind = match attr.kind {
+            AttrKind::Normal(ref item) => {
+                AttrKind::Normal(AttrItem {
+                    path: item.path.clone(),
+                    tokens: self.lower_token_stream(item.tokens.clone()),
+                })
+            }
+            AttrKind::DocComment(comment) => AttrKind::DocComment(comment)
+        };
+
         Attribute {
-            item: AttrItem {
-                path: attr.path.clone(),
-                tokens: self.lower_token_stream(attr.tokens.clone()),
-            },
+            kind,
             id: attr.id,
             style: attr.style,
-            is_sugared_doc: attr.is_sugared_doc,
             span: attr.span,
         }
     }
@@ -1208,7 +1214,7 @@ impl<'a> LoweringContext<'a> {
                                     ImplTraitContext::disallowed(),
                                 ),
                                 unsafety: this.lower_unsafety(f.unsafety),
-                                abi: f.abi,
+                                abi: this.lower_abi(f.abi),
                                 decl: this.lower_fn_decl(&f.decl, None, false, None),
                                 param_names: this.lower_fn_params_to_names(&f.decl),
                             }))
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index f1b999cdd6f..5fe463d783f 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -12,6 +12,7 @@ use crate::hir::def::{Res, DefKind};
 use crate::util::nodemap::NodeMap;
 
 use rustc_data_structures::thin_vec::ThinVec;
+use rustc_target::spec::abi;
 
 use std::collections::BTreeSet;
 use smallvec::SmallVec;
@@ -735,7 +736,7 @@ impl LoweringContext<'_> {
 
     fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
         hir::ForeignMod {
-            abi: fm.abi,
+            abi: self.lower_abi(fm.abi),
             items: fm.items
                 .iter()
                 .map(|x| self.lower_foreign_item(x))
@@ -1291,10 +1292,30 @@ impl LoweringContext<'_> {
             unsafety: self.lower_unsafety(h.unsafety),
             asyncness: self.lower_asyncness(h.asyncness.node),
             constness: self.lower_constness(h.constness),
-            abi: h.abi,
+            abi: self.lower_abi(h.abi),
         }
     }
 
+    pub(super) fn lower_abi(&mut self, abi: Abi) -> abi::Abi {
+        abi::lookup(&abi.symbol.as_str()).unwrap_or_else(|| {
+            self.error_on_invalid_abi(abi);
+            abi::Abi::Rust
+        })
+    }
+
+    fn error_on_invalid_abi(&self, abi: Abi) {
+        struct_span_err!(
+            self.sess,
+            abi.span,
+            E0703,
+            "invalid ABI: found `{}`",
+            abi.symbol
+        )
+        .span_label(abi.span, "invalid ABI")
+        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
+        .emit();
+    }
+
     pub(super) fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
         match u {
             Unsafety::Unsafe => hir::Unsafety::Unsafe,
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index e9970e30bf9..57c1421bde6 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -4,7 +4,7 @@ use crate::hir::def_id::DefIndex;
 use syntax::ast::*;
 use syntax::visit;
 use syntax::symbol::{kw, sym};
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax_pos::hygiene::ExpnId;
 use syntax_pos::Span;
 
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 0edc41e6b48..d409ca6f3c5 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1075,6 +1075,13 @@ impl Mutability {
             MutImmutable => MutMutable,
         }
     }
+
+    pub fn prefix_str(&self) -> &'static str {
+        match self {
+            MutMutable => "mut ",
+            MutImmutable => "",
+        }
+    }
 }
 
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
@@ -1616,6 +1623,11 @@ pub enum ExprKind {
     /// and the remaining elements are the rest of the arguments.
     /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
     /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
+    ///
+    /// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with
+    /// the `hir_id` of the `MethodCall` node itself.
+    ///
+    /// [`type_dependent_def_id`]: ../ty/struct.TypeckTables.html#method.type_dependent_def_id
     MethodCall(P<PathSegment>, Span, HirVec<Expr>),
     /// A tuple (e.g., `(a, b, c, d)`).
     Tup(HirVec<Expr>),
@@ -1698,6 +1710,10 @@ pub enum ExprKind {
 }
 
 /// Represents an optionally `Self`-qualified value/type path or associated extension.
+///
+/// To resolve the path to a `DefId`, call [`qpath_res`].
+///
+/// [`qpath_res`]: ../ty/struct.TypeckTables.html#method.qpath_res
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum QPath {
     /// Path to a definition, optionally "fully-qualified" with a `Self`
@@ -2175,6 +2191,15 @@ pub enum Unsafety {
     Normal,
 }
 
+impl Unsafety {
+    pub fn prefix_str(&self) -> &'static str {
+        match self {
+            Unsafety::Unsafe => "unsafe ",
+            Unsafety::Normal => "",
+        }
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Constness {
     Const,
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 328d475be06..a25c111b598 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1734,9 +1734,7 @@ impl<'a> State<'a> {
                     _ => false,
                 };
                 self.s.word("&");
-                if mutbl == hir::MutMutable {
-                    self.s.word("mut ");
-                }
+                self.s.word(mutbl.prefix_str());
                 if is_range_inner {
                     self.popen();
                 }
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 304735fb1c7..e8ef46d7abe 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -8,9 +8,9 @@ use std::mem;
 
 use syntax::ast;
 use syntax::feature_gate;
-use syntax::parse::token;
-use syntax::symbol::SymbolStr;
+use syntax::token;
 use syntax::tokenstream;
+use syntax_pos::symbol::SymbolStr;
 use syntax_pos::SourceFile;
 
 use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX};
@@ -124,7 +124,6 @@ for ::syntax::attr::StabilityLevel {
 
 impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason, suggestion });
 
-
 impl_stable_hash_for!(enum ::syntax::attr::IntType {
     SignedInt(int_ty),
     UnsignedInt(uint_ty)
@@ -136,6 +135,11 @@ impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
     Unsuffixed
 });
 
+impl_stable_hash_for!(enum ::syntax::ast::LitFloatType {
+    Suffixed(float_ty),
+    Unsuffixed
+});
+
 impl_stable_hash_for!(struct ::syntax::ast::Lit {
     kind,
     token,
@@ -148,8 +152,7 @@ impl_stable_hash_for!(enum ::syntax::ast::LitKind {
     Byte(value),
     Char(value),
     Int(value, lit_int_type),
-    Float(value, float_ty),
-    FloatUnsuffixed(value),
+    Float(value, lit_float_type),
     Bool(value),
     Err(value)
 });
@@ -177,7 +180,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [ast::Attribute] {
         let filtered: SmallVec<[&ast::Attribute; 8]> = self
             .iter()
             .filter(|attr| {
-                !attr.is_sugared_doc &&
+                !attr.is_doc_comment() &&
                 !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
             })
             .collect();
@@ -207,19 +210,16 @@ impl<'a> HashStable<StableHashingContext<'a>> for ast::Attribute {
     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
         // Make sure that these have been filtered out.
         debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
-        debug_assert!(!self.is_sugared_doc);
-
-        let ast::Attribute {
-            ref item,
-            id: _,
-            style,
-            is_sugared_doc: _,
-            span,
-        } = *self;
-
-        item.hash_stable(hcx, hasher);
-        style.hash_stable(hcx, hasher);
-        span.hash_stable(hcx, hasher);
+        debug_assert!(!self.is_doc_comment());
+
+        let ast::Attribute { kind, id: _, style, span } = self;
+        if let ast::AttrKind::Normal(item) = kind {
+            item.hash_stable(hcx, hasher);
+            style.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        } else {
+            unreachable!();
+        }
     }
 }
 
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index e238c966122..38edef50c96 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -897,11 +897,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             } else {
                 r.push(' ');
             }
-            s.push_highlighted(format!(
-                "&{}{}",
-                r,
-                if mutbl == hir::MutMutable { "mut " } else { "" }
-            ));
+            s.push_highlighted(format!("&{}{}", r, mutbl.prefix_str()));
             s.push_normal(ty.to_string());
         }
 
diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md
index ea7fffe9dc1..d789fb0de10 100644
--- a/src/librustc/infer/region_constraints/README.md
+++ b/src/librustc/infer/region_constraints/README.md
@@ -1,3 +1,3 @@
 For info on how the current borrowck works, see the [rustc guide].
 
-[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
+[rustc guide]: https://rust-lang.github.io/rustc-guide/borrow_check.html
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index eef1cee8db3..721baad2563 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -699,6 +699,9 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
 
     /// Check if a `DefId`'s path matches the given absolute type path usage.
     ///
+    /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`;
+    /// inherent `impl` blocks are matched with the name of the type.
+    ///
     /// # Examples
     ///
     /// ```rust,ignore (no context or def id available)
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2bcddeaf196..eb5654e80a8 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1800,7 +1800,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "",
             "extern",
             "Specify where an external rust library is located",
-            "NAME=PATH",
+            "NAME[=PATH]",
         ),
         opt::multi_s(
             "",
@@ -2164,7 +2164,6 @@ fn collect_print_requests(
     cg: &mut CodegenOptions,
     dopts: &mut DebuggingOptions,
     matches: &getopts::Matches,
-    is_unstable_enabled: bool,
     error_format: ErrorOutputType,
 ) -> Vec<PrintRequest> {
     let mut prints = Vec::<PrintRequest>::new();
@@ -2206,7 +2205,7 @@ fn collect_print_requests(
         "tls-models" => PrintRequest::TlsModels,
         "native-static-libs" => PrintRequest::NativeStaticLibs,
         "target-spec-json" => {
-            if is_unstable_enabled {
+            if dopts.unstable_options {
                 PrintRequest::TargetSpec
             } else {
                 early_error(
@@ -2370,7 +2369,6 @@ fn parse_externs(
     matches: &getopts::Matches,
     debugging_opts: &DebuggingOptions,
     error_format: ErrorOutputType,
-    is_unstable_enabled: bool,
 ) -> Externs {
     if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
         early_error(
@@ -2392,13 +2390,6 @@ fn parse_externs(
         let name = parts.next().unwrap_or_else(||
             early_error(error_format, "--extern value must not be empty"));
         let location = parts.next().map(|s| s.to_string());
-        if location.is_none() && !is_unstable_enabled {
-            early_error(
-                error_format,
-                "the `-Z unstable-options` flag must also be passed to \
-                 enable `--extern crate_name` without `=path`",
-            );
-        };
 
         let entry = externs
             .entry(name.to_owned())
@@ -2483,12 +2474,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
-    let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
     let prints = collect_print_requests(
         &mut cg,
         &mut debugging_opts,
         matches,
-        is_unstable_enabled,
         error_format,
     );
 
@@ -2521,7 +2510,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
-    let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled);
+    let externs = parse_externs(matches, &debugging_opts, error_format);
 
     let crate_name = matches.opt_str("crate-name");
 
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index d5e7ac19263..b3ef3217ec6 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -76,7 +76,10 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E,
 
     // The shorthand encoding uses the same usize as the
     // discriminant, with an offset so they can't conflict.
+    #[cfg(bootstrap)]
     let discriminant = unsafe { intrinsics::discriminant_value(variant) };
+    #[cfg(not(bootstrap))]
+    let discriminant = intrinsics::discriminant_value(variant);
     assert!(discriminant < SHORTHAND_OFFSET as u64);
     let shorthand = start + SHORTHAND_OFFSET;
 
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 95040135eb7..4bf500555f1 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -132,8 +132,8 @@ impl PrimitiveExt for Primitive {
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             Int(i, signed) => i.to_ty(tcx, signed),
-            Float(FloatTy::F32) => tcx.types.f32,
-            Float(FloatTy::F64) => tcx.types.f64,
+            F32 => tcx.types.f32,
+            F64 => tcx.types.f64,
             Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
         }
     }
@@ -144,7 +144,7 @@ impl PrimitiveExt for Primitive {
         match *self {
             Int(i, signed) => i.to_ty(tcx, signed),
             Pointer => tcx.types.usize,
-            Float(..) => bug!("floats do not have an int type"),
+            F32 | F64 => bug!("floats do not have an int type"),
         }
     }
 }
@@ -538,7 +538,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             ty::Uint(ity) => {
                 scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false))
             }
-            ty::Float(fty) => scalar(Float(fty)),
+            ty::Float(fty) => scalar(match fty {
+                ast::FloatTy::F32 => F32,
+                ast::FloatTy::F64 => F64,
+            }),
             ty::FnPtr(_) => {
                 let mut ptr = scalar_unit(Pointer);
                 ptr.valid_range = 1..=*ptr.valid_range.end();
@@ -2454,7 +2457,8 @@ impl_stable_hash_for!(enum crate::ty::layout::Integer {
 
 impl_stable_hash_for!(enum crate::ty::layout::Primitive {
     Int(integer, signed),
-    Float(fty),
+    F32,
+    F64,
     Pointer
 });
 
diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs
index e72916de6a9..ddbba972e51 100644
--- a/src/librustc/ty/print/obsolete.rs
+++ b/src/librustc/ty/print/obsolete.rs
@@ -12,7 +12,6 @@ use rustc::ty::{self, Const, Instance, Ty, TyCtxt};
 use rustc::{bug, hir};
 use std::fmt::Write;
 use std::iter;
-use syntax::ast;
 
 /// Same as `unique_type_name()` but with the result pushed onto the given
 /// `output` parameter.
@@ -39,20 +38,9 @@ impl DefPathBasedNames<'tcx> {
             ty::Char => output.push_str("char"),
             ty::Str => output.push_str("str"),
             ty::Never => output.push_str("!"),
-            ty::Int(ast::IntTy::Isize) => output.push_str("isize"),
-            ty::Int(ast::IntTy::I8) => output.push_str("i8"),
-            ty::Int(ast::IntTy::I16) => output.push_str("i16"),
-            ty::Int(ast::IntTy::I32) => output.push_str("i32"),
-            ty::Int(ast::IntTy::I64) => output.push_str("i64"),
-            ty::Int(ast::IntTy::I128) => output.push_str("i128"),
-            ty::Uint(ast::UintTy::Usize) => output.push_str("usize"),
-            ty::Uint(ast::UintTy::U8) => output.push_str("u8"),
-            ty::Uint(ast::UintTy::U16) => output.push_str("u16"),
-            ty::Uint(ast::UintTy::U32) => output.push_str("u32"),
-            ty::Uint(ast::UintTy::U64) => output.push_str("u64"),
-            ty::Uint(ast::UintTy::U128) => output.push_str("u128"),
-            ty::Float(ast::FloatTy::F32) => output.push_str("f32"),
-            ty::Float(ast::FloatTy::F64) => output.push_str("f64"),
+            ty::Int(ty) => output.push_str(ty.name_str()),
+            ty::Uint(ty) => output.push_str(ty.name_str()),
+            ty::Float(ty) => output.push_str(ty.name_str()),
             ty::Adt(adt_def, substs) => {
                 self.push_def_path(adt_def.did, output);
                 self.push_generic_params(substs, iter::empty(), output, debug);
@@ -80,9 +68,7 @@ impl DefPathBasedNames<'tcx> {
             }
             ty::Ref(_, inner_type, mutbl) => {
                 output.push('&');
-                if mutbl == hir::MutMutable {
-                    output.push_str("mut ");
-                }
+                output.push_str(mutbl.prefix_str());
 
                 self.push_type_name(inner_type, output, debug);
             }
@@ -114,9 +100,7 @@ impl DefPathBasedNames<'tcx> {
             ty::Foreign(did) => self.push_def_path(did, output),
             ty::FnDef(..) | ty::FnPtr(_) => {
                 let sig = t.fn_sig(self.tcx);
-                if sig.unsafety() == hir::Unsafety::Unsafe {
-                    output.push_str("unsafe ");
-                }
+                output.push_str(sig.unsafety().prefix_str());
 
                 let abi = sig.abi();
                 if abi != ::rustc_target::spec::abi::Abi::Rust {
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 8a98a5d8361..4c75e474011 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -466,9 +466,9 @@ pub trait PrettyPrinter<'tcx>:
         match ty.kind {
             ty::Bool => p!(write("bool")),
             ty::Char => p!(write("char")),
-            ty::Int(t) => p!(write("{}", t.ty_to_string())),
-            ty::Uint(t) => p!(write("{}", t.ty_to_string())),
-            ty::Float(t) => p!(write("{}", t.ty_to_string())),
+            ty::Int(t) => p!(write("{}", t.name_str())),
+            ty::Uint(t) => p!(write("{}", t.name_str())),
+            ty::Float(t) => p!(write("{}", t.name_str())),
             ty::RawPtr(ref tm) => {
                 p!(write("*{} ", match tm.mutbl {
                     hir::MutMutable => "mut",
@@ -895,10 +895,11 @@ pub trait PrettyPrinter<'tcx>:
                 let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
                 let max = truncate(u128::max_value(), bit_size);
 
+                let ui_str = ui.name_str();
                 if data == max {
-                    p!(write("std::{}::MAX", ui))
+                    p!(write("std::{}::MAX", ui_str))
                 } else {
-                    p!(write("{}{}", data, ui))
+                    p!(write("{}{}", data, ui_str))
                 };
             },
             (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Int(i)) => {
@@ -911,10 +912,11 @@ pub trait PrettyPrinter<'tcx>:
                 let size = self.tcx().layout_of(ty::ParamEnv::empty().and(ty))
                     .unwrap()
                     .size;
+                let i_str = i.name_str();
                 match data {
-                    d if d == min => p!(write("std::{}::MIN", i)),
-                    d if d == max => p!(write("std::{}::MAX", i)),
-                    _ => p!(write("{}{}", sign_extend(data, size) as i128, i))
+                    d if d == min => p!(write("std::{}::MIN", i_str)),
+                    d if d == max => p!(write("std::{}::MAX", i_str)),
+                    _ => p!(write("{}{}", sign_extend(data, size) as i128, i_str))
                 }
             },
             (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Char) =>
@@ -1666,8 +1668,7 @@ define_print_and_forward_display! {
     }
 
     ty::TypeAndMut<'tcx> {
-        p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
-            print(self.ty))
+        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
     }
 
     ty::ExistentialTraitRef<'tcx> {
@@ -1693,9 +1694,7 @@ define_print_and_forward_display! {
     }
 
     ty::FnSig<'tcx> {
-        if self.unsafety == hir::Unsafety::Unsafe {
-            p!(write("unsafe "));
-        }
+        p!(write("{}", self.unsafety.prefix_str()));
 
         if self.abi != Abi::Rust {
             p!(write("extern {} ", self.abi));
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index fa14ce7b03c..e5a5d05ba5e 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -240,9 +240,7 @@ impl<'a> Drop for DiagnosticHandlers<'a> {
     }
 }
 
-unsafe extern "C" fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>,
-                                       msg: &str,
-                                       cookie: c_uint) {
+fn report_inline_asm(cgcx: &CodegenContext<LlvmCodegenBackend>, msg: &str, cookie: c_uint) {
     cgcx.diag_emitter.inline_asm_error(cookie as u32, msg.to_owned());
 }
 
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index f0148a21ae6..f1bf4511131 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -843,13 +843,13 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
         ty::Bool => ("bool", DW_ATE_boolean),
         ty::Char => ("char", DW_ATE_unsigned_char),
         ty::Int(int_ty) => {
-            (int_ty.ty_to_string(), DW_ATE_signed)
+            (int_ty.name_str(), DW_ATE_signed)
         },
         ty::Uint(uint_ty) => {
-            (uint_ty.ty_to_string(), DW_ATE_unsigned)
+            (uint_ty.name_str(), DW_ATE_unsigned)
         },
         ty::Float(float_ty) => {
-            (float_ty.ty_to_string(), DW_ATE_float)
+            (float_ty.name_str(), DW_ATE_float)
         },
         _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
     };
@@ -1904,8 +1904,8 @@ fn prepare_enum_metadata(
 
             let discr_type = match discr.value {
                 layout::Int(t, _) => t,
-                layout::Float(layout::FloatTy::F32) => Integer::I32,
-                layout::Float(layout::FloatTy::F64) => Integer::I64,
+                layout::F32 => Integer::I32,
+                layout::F64 => Integer::I64,
                 layout::Pointer => cx.data_layout().ptr_sized_integer(),
             }.to_ty(cx.tcx, false);
 
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 1bce34abe55..6935e09054d 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -18,8 +18,8 @@ use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive};
 use rustc::mir::interpret::GlobalId;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc::hir;
-use syntax::ast::{self, FloatTy};
 use rustc_target::abi::HasDataLayout;
+use syntax::ast;
 
 use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
 use rustc_codegen_ssa::traits::*;
@@ -163,12 +163,12 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                                     emit_va_arg(self, args[0], ret_ty)
                                 }
                             }
-                            Primitive::Float(FloatTy::F64) |
+                            Primitive::F64 |
                             Primitive::Pointer => {
                                 emit_va_arg(self, args[0], ret_ty)
                             }
                             // `va_arg` should never be used with the return type f32.
-                            Primitive::Float(FloatTy::F32) => {
+                            Primitive::F32 => {
                                 bug!("the va_arg intrinsic does not work with `f32`")
                             }
                         }
@@ -1335,7 +1335,7 @@ fn generic_simd_intrinsic(
             },
             ty::Float(f) => {
                 return_error!("unsupported element type `{}` of floating-point vector `{}`",
-                              f, in_ty);
+                              f.name_str(), in_ty);
             },
             _ => {
                 return_error!("`{}` is not a floating-point type", in_ty);
diff --git a/src/librustc_codegen_llvm/llvm/mod.rs b/src/librustc_codegen_llvm/llvm/mod.rs
index 57815933af0..e49462674b3 100644
--- a/src/librustc_codegen_llvm/llvm/mod.rs
+++ b/src/librustc_codegen_llvm/llvm/mod.rs
@@ -87,6 +87,7 @@ pub struct RustString {
 }
 
 /// Appending to a Rust string -- used by RawRustStringOstream.
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub unsafe extern "C" fn LLVMRustStringWriteImpl(sr: &RustString,
                                                  ptr: *const c_char,
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index dc68872ede1..c21e62e7562 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -3,7 +3,7 @@ use crate::common::*;
 use crate::type_::Type;
 use rustc::ty::{self, Ty, TypeFoldable};
 use rustc::ty::layout::{self, Align, LayoutOf, FnAbiExt, PointeeInfo, Size, TyLayout};
-use rustc_target::abi::{FloatTy, TyLayoutMethods};
+use rustc_target::abi::TyLayoutMethods;
 use rustc::ty::print::obsolete::DefPathBasedNames;
 use rustc_codegen_ssa::traits::*;
 
@@ -300,8 +300,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
                                scalar: &layout::Scalar, offset: Size) -> &'a Type {
         match scalar.value {
             layout::Int(i, _) => cx.type_from_integer( i),
-            layout::Float(FloatTy::F32) => cx.type_f32(),
-            layout::Float(FloatTy::F64) => cx.type_f64(),
+            layout::F32 => cx.type_f32(),
+            layout::F64 => cx.type_f64(),
             layout::Pointer => {
                 // If we know the alignment, pick something better than i8.
                 let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) {
diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs
index 166a74fe487..f40b942b1e3 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs
@@ -37,9 +37,9 @@ pub fn push_debuginfo_type_name<'tcx>(
         ty::Char => output.push_str("char"),
         ty::Str => output.push_str("str"),
         ty::Never => output.push_str("!"),
-        ty::Int(int_ty) => output.push_str(int_ty.ty_to_string()),
-        ty::Uint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
-        ty::Float(float_ty) => output.push_str(float_ty.ty_to_string()),
+        ty::Int(int_ty) => output.push_str(int_ty.name_str()),
+        ty::Uint(uint_ty) => output.push_str(uint_ty.name_str()),
+        ty::Float(float_ty) => output.push_str(float_ty.name_str()),
         ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
         ty::Adt(def, substs) => {
             push_item_name(tcx, def.did, qualified, output);
@@ -76,9 +76,7 @@ pub fn push_debuginfo_type_name<'tcx>(
             if !cpp_like_names {
                 output.push('&');
             }
-            if mutbl == hir::MutMutable {
-                output.push_str("mut ");
-            }
+            output.push_str(mutbl.prefix_str());
 
             push_debuginfo_type_name(tcx, inner_type, true, output, visited);
 
@@ -140,9 +138,7 @@ pub fn push_debuginfo_type_name<'tcx>(
 
 
             let sig = t.fn_sig(tcx);
-            if sig.unsafety() == hir::Unsafety::Unsafe {
-                output.push_str("unsafe ");
-            }
+            output.push_str(sig.unsafety().prefix_str());
 
             let abi = sig.abi();
             if abi != rustc_target::spec::abi::Abi::Rust {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 6e8bc11162f..611b891d99a 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -42,6 +42,7 @@ use rustc::ty::TyCtxt;
 use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
 use rustc_metadata::locator;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
+use errors::PResult;
 use rustc_interface::interface;
 use rustc_interface::util::get_codegen_sysroot;
 use rustc_data_structures::sync::SeqCst;
@@ -64,7 +65,7 @@ use std::time::Instant;
 use syntax::ast;
 use syntax::source_map::FileLoader;
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
-use syntax::parse::{self, PResult};
+use syntax::parse;
 use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, FileName};
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 67c180a05e9..fb5cccf61a7 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -15,7 +15,8 @@ use Level::*;
 
 use emitter::{Emitter, EmitterWriter, is_case_difference};
 use registry::Registry;
-
+#[cfg(target_arch = "x86_64")]
+use rustc_data_structures::static_assert_size;
 use rustc_data_structures::sync::{self, Lrc, Lock};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::stable_hasher::StableHasher;
@@ -48,6 +49,13 @@ use syntax_pos::{
     SpanSnippetError,
 };
 
+pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
+
+// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
+// (See also the comment on `DiagnosticBuilderInner`.)
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(PResult<'_, bool>, 16);
+
 /// Indicates the confidence in the correctness of a suggestion.
 ///
 /// All suggestions are marked with an `Applicability`. Tools use the applicability of a suggestion
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index 98e4f974a9f..35b93db1d65 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -27,7 +27,6 @@ rustc_codegen_utils = { path = "../librustc_codegen_utils" }
 rustc_metadata = { path = "../librustc_metadata" }
 rustc_mir = { path = "../librustc_mir" }
 rustc_passes = { path = "../librustc_passes" }
-rustc_target = { path = "../librustc_target" }
 rustc_typeck = { path = "../librustc_typeck" }
 rustc_lint = { path = "../librustc_lint" }
 rustc_errors = { path = "../librustc_errors" }
@@ -36,3 +35,6 @@ rustc_privacy = { path = "../librustc_privacy" }
 rustc_resolve = { path = "../librustc_resolve" }
 tempfile = "3.0.5"
 once_cell = "1"
+
+[dev-dependencies]
+rustc_target = { path = "../librustc_target" }
diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs
index 4e4d6d982fb..034e861b212 100644
--- a/src/librustc_interface/interface.rs
+++ b/src/librustc_interface/interface.rs
@@ -16,7 +16,7 @@ use std::result;
 use std::sync::{Arc, Mutex};
 use syntax::{self, parse};
 use syntax::ast::{self, MetaItemKind};
-use syntax::parse::token;
+use syntax::token;
 use syntax::source_map::{FileName, FileLoader, SourceMap};
 use syntax::sess::ParseSess;
 use syntax_pos::edition;
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 52332744d1a..ce34caee6fa 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -22,6 +22,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_codegen_utils::link::filename_for_metadata;
 use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
 use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
+use rustc_errors::PResult;
 use rustc_incremental;
 use rustc_metadata::cstore;
 use rustc_mir as mir;
@@ -36,7 +37,7 @@ use syntax::{self, ast, visit};
 use syntax::early_buffered_lints::BufferedEarlyLint;
 use syntax_expand::base::{NamedSyntaxExtension, ExtCtxt};
 use syntax::mut_visit::MutVisitor;
-use syntax::parse::{self, PResult};
+use syntax::parse;
 use syntax::util::node_count::NodeCounter;
 use syntax::symbol::Symbol;
 use syntax_pos::FileName;
diff --git a/src/librustc_lint/array_into_iter.rs b/src/librustc_lint/array_into_iter.rs
new file mode 100644
index 00000000000..e73414174fb
--- /dev/null
+++ b/src/librustc_lint/array_into_iter.rs
@@ -0,0 +1,91 @@
+use crate::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
+use rustc::{
+    lint::FutureIncompatibleInfo,
+    hir,
+    ty::{
+        self,
+        adjustment::{Adjust, Adjustment},
+    },
+};
+use syntax::{
+    errors::Applicability,
+    symbol::sym,
+};
+
+
+declare_lint! {
+    pub ARRAY_INTO_ITER,
+    Warn,
+    "detects calling `into_iter` on arrays",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "issue #66145 <https://github.com/rust-lang/rust/issues/66145>",
+        edition: None,
+    };
+}
+
+declare_lint_pass!(
+    /// Checks for instances of calling `into_iter` on arrays.
+    ArrayIntoIter => [ARRAY_INTO_ITER]
+);
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIntoIter {
+    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
+        // We only care about method call expressions.
+        if let hir::ExprKind::MethodCall(call, span, args) = &expr.kind {
+            if call.ident.name != sym::into_iter {
+                return;
+            }
+
+            // Check if the method call actually calls the libcore
+            // `IntoIterator::into_iter`.
+            let def_id = cx.tables.type_dependent_def_id(expr.hir_id).unwrap();
+            match cx.tcx.trait_of_item(def_id) {
+                Some(trait_id) if cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_id) => {},
+                _ => return,
+            };
+
+            // As this is a method call expression, we have at least one
+            // argument.
+            let receiver_arg = &args[0];
+
+            // Test if the original `self` type is an array type.
+            match cx.tables.expr_ty(receiver_arg).kind {
+                ty::Array(..) => {}
+                _ => return,
+            }
+
+            // Make sure that the first adjustment is an autoref coercion.
+            match cx.tables.expr_adjustments(receiver_arg).get(0) {
+                Some(Adjustment { kind: Adjust::Borrow(_), .. }) => {}
+                _ => return,
+            }
+
+            // Emit lint diagnostic.
+            let target = match cx.tables.expr_ty_adjusted(receiver_arg).kind {
+                ty::Ref(_, ty::TyS { kind: ty::Array(..), ..}, _) => "[T; N]",
+                ty::Ref(_, ty::TyS { kind: ty::Slice(..), ..}, _) => "[T]",
+
+                // We know the original first argument type is an array type,
+                // we know that the first adjustment was an autoref coercion
+                // and we know that `IntoIterator` is the trait involved. The
+                // array cannot be coerced to something other than a reference
+                // to an array or to a slice.
+                _ => bug!("array type coerced to something other than array or slice"),
+            };
+            let msg = format!(
+                "this method call currently resolves to `<&{} as IntoIterator>::into_iter` (due \
+                    to autoref coercions), but that might change in the future when \
+                    `IntoIterator` impls for arrays are added.",
+                target,
+            );
+            cx.struct_span_lint(ARRAY_INTO_ITER, *span, &msg)
+                .span_suggestion(
+                    call.ident.span,
+                    "use `.iter()` instead of `.into_iter()` to avoid ambiguity",
+                    "iter".into(),
+                    Applicability::MachineApplicable,
+                )
+                .emit();
+        }
+    }
+}
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 30d68fd0bfc..c6fd1256a8e 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -706,7 +706,7 @@ impl EarlyLintPass for DeprecatedAttr {
             }
         }
         if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) {
-            let path_str = pprust::path_to_string(&attr.path);
+            let path_str = pprust::path_to_string(&attr.get_normal_item().path);
             let msg = format!("use of deprecated attribute `{}`: no longer used.", path_str);
             lint_deprecated_attr(cx, attr, &msg, None);
         }
@@ -736,7 +736,7 @@ impl UnusedDocComment {
         let mut sugared_span: Option<Span> = None;
 
         while let Some(attr) = attrs.next() {
-            if attr.is_sugared_doc {
+            if attr.is_doc_comment() {
                 sugared_span = Some(
                     sugared_span.map_or_else(
                         || attr.span,
@@ -745,7 +745,7 @@ impl UnusedDocComment {
                 );
             }
 
-            if attrs.peek().map(|next_attr| next_attr.is_sugared_doc).unwrap_or_default() {
+            if attrs.peek().map(|next_attr| next_attr.is_doc_comment()).unwrap_or_default() {
                 continue;
             }
 
@@ -1909,8 +1909,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
             // `Invalid` represents the empty string and matches that.
             const TRANSMUTE_PATH: &[Symbol] =
                 &[sym::core, sym::intrinsics, kw::Invalid, sym::transmute];
+            const MU_ZEROED_PATH: &[Symbol] =
+                &[sym::core, sym::mem, sym::maybe_uninit, sym::MaybeUninit, sym::zeroed];
+            const MU_UNINIT_PATH: &[Symbol] =
+                &[sym::core, sym::mem, sym::maybe_uninit, sym::MaybeUninit, sym::uninit];
 
             if let hir::ExprKind::Call(ref path_expr, ref args) = expr.kind {
+                // Find calls to `mem::{uninitialized,zeroed}` methods.
                 if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
                     let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
 
@@ -1925,8 +1930,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                             return Some(InitKind::Zeroed);
                         }
                     }
-                    // FIXME: Also detect `MaybeUninit::zeroed().assume_init()` and
-                    // `MaybeUninit::uninit().assume_init()`.
+                }
+            } else if let hir::ExprKind::MethodCall(_, _, ref args) = expr.kind {
+                // Find problematic calls to `MaybeUninit::assume_init`.
+                let def_id = cx.tables.type_dependent_def_id(expr.hir_id)?;
+                if cx.tcx.is_diagnostic_item(sym::assume_init, def_id) {
+                    // This is a call to *some* method named `assume_init`.
+                    // See if the `self` parameter is one of the dangerous constructors.
+                    if let hir::ExprKind::Call(ref path_expr, _) = args[0].kind {
+                        if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
+                            let def_id = cx.tables.qpath_res(qpath, path_expr.hir_id).opt_def_id()?;
+                            if cx.match_def_path(def_id, MU_ZEROED_PATH) {
+                                return Some(InitKind::Zeroed);
+                            } else if cx.match_def_path(def_id, MU_UNINIT_PATH) {
+                                return Some(InitKind::Uninit);
+                            }
+                        }
+                    }
                 }
             }
 
@@ -1947,6 +1967,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                 Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)),
                 FnPtr(..) => Some((format!("Function pointers must be non-null"), None)),
                 Never => Some((format!("The never type (`!`) has no valid value"), None)),
+                RawPtr(tm) if matches!(tm.ty.kind, Dynamic(..)) => // raw ptr to dyn Trait
+                    Some((format!("The vtable of a wide raw pointer must be non-null"), None)),
                 // Primitive types with other constraints.
                 Bool if init == InitKind::Uninit =>
                     Some((format!("Booleans must be `true` or `false`"), None)),
@@ -2030,7 +2052,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue {
                 );
                 err.span_label(expr.span,
                     "this code causes undefined behavior when executed");
-                err.span_label(expr.span, "help: use `MaybeUninit<T>` instead");
+                err.span_label(expr.span, "help: use `MaybeUninit<T>` instead, \
+                    and only call `assume_init` after initialization is done");
                 if let Some(span) = span {
                     err.span_note(span, &msg);
                 } else {
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 2ca3d4b19b2..a1e50018f8a 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -15,12 +15,14 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(nll)]
+#![feature(matches_macro)]
 
 #![recursion_limit="256"]
 
 #[macro_use]
 extern crate rustc;
 
+mod array_into_iter;
 mod error_codes;
 mod nonstandard_style;
 mod redundant_semicolon;
@@ -56,6 +58,7 @@ use types::*;
 use unused::*;
 use non_ascii_idents::*;
 use rustc::lint::internal::*;
+use array_into_iter::ArrayIntoIter;
 
 /// Useful for other parts of the compiler.
 pub use builtin::SoftLints;
@@ -130,6 +133,8 @@ macro_rules! late_lint_passes {
             // FIXME: Turn the computation of types which implement Debug into a query
             // and change this to a module lint pass
             MissingDebugImplementations: MissingDebugImplementations::default(),
+
+            ArrayIntoIter: ArrayIntoIter,
         ]);
     )
 }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index aa6dfa50ddd..65e0940920b 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -4,7 +4,7 @@ use rustc::hir::{ExprKind, Node};
 use crate::hir::def_id::DefId;
 use rustc::hir::lowering::is_range_literal;
 use rustc::ty::subst::SubstsRef;
-use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
 use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton};
 use rustc::{lint, util};
 use rustc_index::vec::Idx;
@@ -68,7 +68,7 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
     max: u128,
     expr: &'tcx hir::Expr,
     parent_expr: &'tcx hir::Expr,
-    ty: impl std::fmt::Debug,
+    ty: &str,
 ) -> bool {
     // We only want to handle exclusive (`..`) ranges,
     // which are represented as `ExprKind::Struct`.
@@ -83,15 +83,15 @@ fn lint_overflowing_range_endpoint<'a, 'tcx>(
             let mut err = cx.struct_span_lint(
                 OVERFLOWING_LITERALS,
                 parent_expr.span,
-                &format!("range endpoint is out of range for `{:?}`", ty),
+                &format!("range endpoint is out of range for `{}`", ty),
             );
             if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
                 use ast::{LitKind, LitIntType};
                 // We need to preserve the literal's suffix,
                 // as it may determine typing information.
                 let suffix = match lit.node {
-                    LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s),
-                    LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s),
+                    LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s.name_str()),
+                    LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s.name_str()),
                     LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(),
                     _ => bug!(),
                 };
@@ -161,11 +161,11 @@ fn report_bin_hex_error(
     let (t, actually) = match ty {
         attr::IntType::SignedInt(t) => {
             let actually = sign_extend(val, size) as i128;
-            (format!("{:?}", t), actually.to_string())
+            (t.name_str(), actually.to_string())
         }
         attr::IntType::UnsignedInt(t) => {
             let actually = truncate(val, size);
-            (format!("{:?}", t), actually.to_string())
+            (t.name_str(), actually.to_string())
         }
     };
     let mut err = cx.struct_span_lint(
@@ -204,7 +204,7 @@ fn report_bin_hex_error(
 //  - `uX` => `uY`
 //
 // No suggestion for: `isize`, `usize`.
-fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
+fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
     use syntax::ast::IntTy::*;
     use syntax::ast::UintTy::*;
     macro_rules! find_fit {
@@ -215,10 +215,10 @@ fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<String> {
                 match $ty {
                     $($type => {
                         $(if !negative && val <= uint_ty_range($utypes).1 {
-                            return Some(format!("{:?}", $utypes))
+                            return Some($utypes.name_str())
                         })*
                         $(if val <= int_ty_range($itypes).1 as u128 + _neg {
-                            return Some(format!("{:?}", $itypes))
+                            return Some($itypes.name_str())
                         })*
                         None
                     },)+
@@ -281,7 +281,7 @@ fn lint_int_literal<'a, 'tcx>(
         if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
             if let hir::ExprKind::Struct(..) = par_e.kind {
                 if is_range_literal(cx.sess(), par_e)
-                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t)
+                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t.name_str())
                 {
                     // The overflowing literal lint was overridden.
                     return;
@@ -292,7 +292,7 @@ fn lint_int_literal<'a, 'tcx>(
         cx.span_lint(
             OVERFLOWING_LITERALS,
             e.span,
-            &format!("literal out of range for `{:?}`", t),
+            &format!("literal out of range for `{}`", t.name_str()),
         );
     }
 }
@@ -338,6 +338,7 @@ fn lint_uint_literal<'a, 'tcx>(
                 }
                 hir::ExprKind::Struct(..)
                     if is_range_literal(cx.sess(), par_e) => {
+                        let t = t.name_str();
                         if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
                             // The overflowing literal lint was overridden.
                             return;
@@ -353,7 +354,7 @@ fn lint_uint_literal<'a, 'tcx>(
         cx.span_lint(
             OVERFLOWING_LITERALS,
             e.span,
-            &format!("literal out of range for `{:?}`", t),
+            &format!("literal out of range for `{}`", t.name_str()),
         );
     }
 }
@@ -379,8 +380,7 @@ fn lint_literal<'a, 'tcx>(
         }
         ty::Float(t) => {
             let is_infinite = match lit.node {
-                ast::LitKind::Float(v, _) |
-                ast::LitKind::FloatUnsuffixed(v) => {
+                ast::LitKind::Float(v, _) => {
                     match t {
                         ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
                         ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
@@ -389,9 +389,11 @@ fn lint_literal<'a, 'tcx>(
                 _ => bug!(),
             };
             if is_infinite == Ok(true) {
-                cx.span_lint(OVERFLOWING_LITERALS,
-                             e.span,
-                             &format!("literal out of range for `{:?}`", t));
+                cx.span_lint(
+                    OVERFLOWING_LITERALS,
+                    e.span,
+                    &format!("literal out of range for `{}`", t.name_str()),
+                );
             }
         }
         _ => {}
@@ -835,16 +837,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::Array(ty, _) => self.check_type_for_ffi(cache, ty),
 
             ty::FnPtr(sig) => {
-                match sig.abi() {
-                    Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
-                        return FfiUnsafe {
-                            ty,
-                            reason: "this function pointer has Rust-specific calling convention",
-                            help: Some("consider using an `extern fn(...) -> ...` \
-                                        function pointer instead"),
-                        }
-                    }
-                    _ => {}
+                if self.is_internal_abi(sig.abi()) {
+                    return FfiUnsafe {
+                        ty,
+                        reason: "this function pointer has Rust-specific calling convention",
+                        help: Some("consider using an `extern fn(...) -> ...` \
+                                    function pointer instead"),
+                    };
                 }
 
                 let sig = cx.erase_late_bound_regions(&sig);
@@ -871,7 +870,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
             ty::Foreign(..) => FfiSafe,
 
-            ty::Param(..) |
+            // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
+            //  so they are currently ignored for the purposes of this lint, see #65134.
+            ty::Param(..) | ty::Projection(..) => FfiSafe,
+
             ty::Infer(..) |
             ty::Bound(..) |
             ty::Error |
@@ -880,7 +882,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::GeneratorWitness(..) |
             ty::Placeholder(..) |
             ty::UnnormalizedProjection(..) |
-            ty::Projection(..) |
             ty::Opaque(..) |
             ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
         }
@@ -892,11 +893,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         sp: Span,
         note: &str,
         help: Option<&str>,
+        is_foreign_item: bool,
     ) {
         let mut diag = self.cx.struct_span_lint(
             IMPROPER_CTYPES,
             sp,
-            &format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
+            &format!(
+                "`extern` {} uses type `{}`, which is not FFI-safe",
+                if is_foreign_item { "block" } else { "fn" },
+                ty,
+            ),
         );
         diag.span_label(sp, "not FFI-safe");
         if let Some(help) = help {
@@ -911,9 +917,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         diag.emit();
     }
 
-    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
-        use crate::rustc::ty::TypeFoldable;
-
+    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>, is_foreign_item: bool) -> bool {
         struct ProhibitOpaqueTypes<'tcx> {
             ty: Option<Ty<'tcx>>,
         };
@@ -937,6 +941,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 sp,
                 "opaque types have no C equivalent",
                 None,
+                is_foreign_item,
             );
             true
         } else {
@@ -944,42 +949,46 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
     }
 
-    fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
+    fn check_type_for_ffi_and_report_errors(
+        &mut self,
+        sp: Span,
+        ty: Ty<'tcx>,
+        is_foreign_item: bool,
+    ) {
         // We have to check for opaque types before `normalize_erasing_regions`,
         // which will replace opaque types with their underlying concrete type.
-        if self.check_for_opaque_ty(sp, ty) {
+        if self.check_for_opaque_ty(sp, ty, is_foreign_item) {
             // We've already emitted an error due to an opaque type.
             return;
         }
 
-        // it is only OK to use this function because extern fns cannot have
-        // any generic types right now:
-        let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
-
+        let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
         match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
             FfiResult::FfiSafe => {}
             FfiResult::FfiPhantom(ty) => {
-                self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
+                self.emit_ffi_unsafe_type_lint(
+                    ty, sp, "composed only of `PhantomData`", None, is_foreign_item);
             }
             FfiResult::FfiUnsafe { ty, reason, help } => {
-                self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
+                self.emit_ffi_unsafe_type_lint(
+                    ty, sp, reason, help, is_foreign_item);
             }
         }
     }
 
-    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl) {
+    fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl, is_foreign_item: bool) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let sig = self.cx.tcx.fn_sig(def_id);
         let sig = self.cx.tcx.erase_late_bound_regions(&sig);
 
         for (input_ty, input_hir) in sig.inputs().iter().zip(&decl.inputs) {
-            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty);
+            self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, is_foreign_item);
         }
 
         if let hir::Return(ref ret_hir) = decl.output {
             let ret_ty = sig.output();
             if !ret_ty.is_unit() {
-                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
+                self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, is_foreign_item);
             }
         }
     }
@@ -987,7 +996,15 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
         let def_id = self.cx.tcx.hir().local_def_id(id);
         let ty = self.cx.tcx.type_of(def_id);
-        self.check_type_for_ffi_and_report_errors(span, ty);
+        self.check_type_for_ffi_and_report_errors(span, ty, true);
+    }
+
+    fn is_internal_abi(&self, abi: Abi) -> bool {
+        if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
+            true
+        } else {
+            false
+        }
     }
 }
 
@@ -995,12 +1012,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
     fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
         let mut vis = ImproperCTypesVisitor { cx };
         let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
-        if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
-            // Don't worry about types in internal ABIs.
-        } else {
+        if !vis.is_internal_abi(abi) {
             match it.kind {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
-                    vis.check_foreign_fn(it.hir_id, decl);
+                    vis.check_foreign_fn(it.hir_id, decl, true);
                 }
                 hir::ForeignItemKind::Static(ref ty, _) => {
                     vis.check_foreign_static(it.hir_id, ty.span);
@@ -1009,6 +1024,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
             }
         }
     }
+
+    fn check_fn(
+        &mut self,
+        cx: &LateContext<'a, 'tcx>,
+        kind: hir::intravisit::FnKind<'tcx>,
+        decl: &'tcx hir::FnDecl,
+        _: &'tcx hir::Body,
+        _: Span,
+        hir_id: hir::HirId,
+    ) {
+        use hir::intravisit::FnKind;
+
+        let abi = match kind {
+            FnKind::ItemFn(_, _, header, ..) => (header.abi),
+            FnKind::Method(_, sig, ..) => (sig.header.abi),
+            _ => return,
+        };
+
+        let mut vis = ImproperCTypesVisitor { cx };
+        if !vis.is_internal_abi(abi) {
+            vis.check_foreign_fn(hir_id, decl, false);
+        }
+    }
 }
 
 declare_lint_pass!(VariantSizeDifferences => [VARIANT_SIZE_DIFFERENCES]);
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 483b1a40e44..05e3ee3322e 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -2,7 +2,7 @@
 
 use crate::cstore::{self, CStore, MetadataBlob};
 use crate::locator::{self, CratePaths};
-use crate::schema::{CrateRoot, CrateDep};
+use crate::rmeta::{CrateRoot, CrateDep};
 use rustc_data_structures::sync::{Lock, Once, AtomicCell};
 
 use rustc::hir::def_id::CrateNum;
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index b7596d2018f..c6c8ee575a9 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -1,7 +1,7 @@
 // The crate store - a central repo for information collected about external
 // crates and libraries
 
-use crate::schema;
+use crate::rmeta;
 use rustc::dep_graph::DepNodeIndex;
 use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::map::definitions::DefPathTable;
@@ -17,7 +17,7 @@ use syntax_expand::base::SyntaxExtension;
 use syntax_pos;
 use proc_macro::bridge::client::ProcMacro;
 
-pub use crate::cstore_impl::{provide, provide_extern};
+pub use crate::rmeta::{provide, provide_extern};
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
@@ -49,7 +49,7 @@ crate struct CrateMetadata {
     /// lifetime is only used behind `Lazy`, and therefore acts like an
     /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
     /// is being used to decode those values.
-    crate root: schema::CrateRoot<'static>,
+    crate root: rmeta::CrateRoot<'static>,
     /// For each definition in this crate, we encode a key. When the
     /// crate is loaded, we read all the keys and put them in this
     /// hashmap, which gives the reverse mapping. This allows us to
@@ -59,7 +59,7 @@ crate struct CrateMetadata {
     /// Trait impl data.
     /// FIXME: Used only from queries and can use query cache,
     /// so pre-decoding can probably be avoided.
-    crate trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
+    crate trait_impls: FxHashMap<(u32, DefIndex), rmeta::Lazy<[DefIndex]>>,
     /// Proc macro descriptions for this crate, if it's a proc macro crate.
     crate raw_proc_macros: Option<&'static [ProcMacro]>,
     /// Source maps for code from the crate.
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 291ee23ff72..ac9d78e9a51 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -26,15 +26,11 @@ extern crate rustc_data_structures;
 
 pub mod error_codes;
 
-mod encoder;
-mod decoder;
 mod dependency_format;
-mod cstore_impl;
 mod foreign_modules;
 mod link_args;
 mod native_libs;
-mod schema;
-mod table;
+mod rmeta;
 
 pub mod creader;
 pub mod cstore;
diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs
index 4291f3a4ae3..b40d58a6819 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/src/librustc_metadata/link_args.rs
@@ -11,7 +11,7 @@ crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
     tcx.hir().krate().visit_all_item_likes(&mut collector);
 
     for attr in tcx.hir().krate().attrs.iter() {
-        if attr.path == sym::link_args {
+        if attr.has_name(sym::link_args) {
             if let Some(linkarg) = attr.value_str() {
                 collector.add_link_args(&linkarg.as_str());
             }
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 4a263250f9b..88d7595b063 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -214,7 +214,7 @@
 
 use crate::cstore::MetadataBlob;
 use crate::creader::Library;
-use crate::schema::{METADATA_HEADER, rustc_version};
+use crate::rmeta::{METADATA_HEADER, rustc_version};
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::svh::Svh;
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index c5954e1ea1d..40ec04537b0 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -1,8 +1,8 @@
 // Decoding metadata from a single crate's metadata
 
 use crate::cstore::{self, CrateMetadata, MetadataBlob};
-use crate::schema::*;
-use crate::table::{FixedSizeEncoding, PerDefTable};
+use crate::rmeta::*;
+use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
 
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
@@ -40,6 +40,10 @@ use syntax_pos::symbol::{Symbol, sym};
 use log::debug;
 use proc_macro::bridge::client::ProcMacro;
 
+pub use cstore_impl::{provide, provide_extern};
+
+mod cstore_impl;
+
 crate struct DecodeContext<'a, 'tcx> {
     opaque: opaque::Decoder<'a>,
     cdata: Option<&'a CrateMetadata>,
@@ -464,7 +468,7 @@ impl<'tcx> EntryKind<'tcx> {
 }
 
 impl<'a, 'tcx> CrateMetadata {
-    crate fn is_proc_macro_crate(&self) -> bool {
+    fn is_proc_macro_crate(&self) -> bool {
         self.root.proc_macro_decls_static.is_some()
     }
 
@@ -507,7 +511,7 @@ impl<'a, 'tcx> CrateMetadata {
         &self.raw_proc_macros.unwrap()[pos]
     }
 
-    crate fn item_name(&self, item_index: DefIndex) -> Symbol {
+    fn item_name(&self, item_index: DefIndex) -> Symbol {
         if !self.is_proc_macro(item_index) {
             self.def_key(item_index)
                 .disambiguated_data
@@ -519,7 +523,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
+    fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
         if !self.is_proc_macro(index) {
             self.kind(index).def_kind()
         } else {
@@ -529,11 +533,11 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
+    fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
         self.root.per_def.span.get(self, index).unwrap().decode((self, sess))
     }
 
-    crate fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
+    fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
         let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
                 let helper_attrs =
@@ -563,7 +567,7 @@ impl<'a, 'tcx> CrateMetadata {
         )
     }
 
-    crate fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
+    fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
         match self.kind(item_id) {
             EntryKind::Trait(data) => {
                 let data = data.decode((self, sess));
@@ -633,7 +637,7 @@ impl<'a, 'tcx> CrateMetadata {
         )
     }
 
-    crate fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
+    fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
         let kind = self.kind(item_id);
         let did = self.local_def_id(item_id);
 
@@ -658,23 +662,25 @@ impl<'a, 'tcx> CrateMetadata {
         tcx.alloc_adt_def(did, adt_kind, variants, repr)
     }
 
-    crate fn get_predicates(
+    fn get_explicit_predicates(
         &self,
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
     ) -> ty::GenericPredicates<'tcx> {
-        self.root.per_def.predicates.get(self, item_id).unwrap().decode((self, tcx))
+        self.root.per_def.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx))
     }
 
-    crate fn get_predicates_defined_on(
+    fn get_inferred_outlives(
         &self,
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
-    ) -> ty::GenericPredicates<'tcx> {
-        self.root.per_def.predicates_defined_on.get(self, item_id).unwrap().decode((self, tcx))
+    ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
+        self.root.per_def.inferred_outlives.get(self, item_id).map(|predicates| {
+            predicates.decode((self, tcx))
+        }).unwrap_or_default()
     }
 
-    crate fn get_super_predicates(
+    fn get_super_predicates(
         &self,
         item_id: DefIndex,
         tcx: TyCtxt<'tcx>,
@@ -682,28 +688,28 @@ impl<'a, 'tcx> CrateMetadata {
         self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
     }
 
-    crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
+    fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
         self.root.per_def.generics.get(self, item_id).unwrap().decode((self, sess))
     }
 
-    crate fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+    fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         self.root.per_def.ty.get(self, id).unwrap().decode((self, tcx))
     }
 
-    crate fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
+    fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
         match self.is_proc_macro(id) {
             true => self.root.proc_macro_stability.clone(),
             false => self.root.per_def.stability.get(self, id).map(|stab| stab.decode(self)),
         }
     }
 
-    crate fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
+    fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
         self.root.per_def.deprecation.get(self, id)
             .filter(|_| !self.is_proc_macro(id))
             .map(|depr| depr.decode(self))
     }
 
-    crate fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
+    fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
         match self.is_proc_macro(id) {
             true => ty::Visibility::Public,
             false => self.root.per_def.visibility.get(self, id).unwrap().decode(self),
@@ -717,31 +723,31 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
+    fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
         self.get_impl_data(id).parent_impl
     }
 
-    crate fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity {
+    fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity {
         self.get_impl_data(id).polarity
     }
 
-    crate fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
+    fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
         self.get_impl_data(id).defaultness
     }
 
-    crate fn get_coerce_unsized_info(
+    fn get_coerce_unsized_info(
         &self,
         id: DefIndex,
     ) -> Option<ty::adjustment::CoerceUnsizedInfo> {
         self.get_impl_data(id).coerce_unsized_info
     }
 
-    crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
+    fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
         self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
     }
 
     /// Iterates over all the stability attributes in the given crate.
-    crate fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
+    fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
         // FIXME: For a proc macro crate, not sure whether we should return the "host"
         // features or an empty Vec. Both don't cause ICEs.
         tcx.arena.alloc_from_iter(self.root
@@ -750,7 +756,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over the language items in the given crate.
-    crate fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
+    fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not export any lang-items to the target.
             &[]
@@ -763,7 +769,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over the diagnostic items in the given crate.
-    crate fn get_diagnostic_items(
+    fn get_diagnostic_items(
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx FxHashMap<Symbol, DefId> {
@@ -780,7 +786,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over each child of the given item.
-    crate fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
+    fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
         where F: FnMut(def::Export<hir::HirId>)
     {
         if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) {
@@ -919,12 +925,12 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn is_item_mir_available(&self, id: DefIndex) -> bool {
+    fn is_item_mir_available(&self, id: DefIndex) -> bool {
         !self.is_proc_macro(id) &&
             self.root.per_def.mir.get(self, id).is_some()
     }
 
-    crate fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
+    fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
         self.root.per_def.mir.get(self, id)
             .filter(|_| !self.is_proc_macro(id))
             .unwrap_or_else(|| {
@@ -933,7 +939,7 @@ impl<'a, 'tcx> CrateMetadata {
             .decode((self, tcx))
     }
 
-    crate fn get_promoted_mir(
+    fn get_promoted_mir(
         &self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
@@ -946,7 +952,7 @@ impl<'a, 'tcx> CrateMetadata {
             .decode((self, tcx))
     }
 
-    crate fn mir_const_qualif(&self, id: DefIndex) -> u8 {
+    fn mir_const_qualif(&self, id: DefIndex) -> u8 {
         match self.kind(id) {
             EntryKind::Const(qualif, _) |
             EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) |
@@ -957,7 +963,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
+    fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
         let def_key = self.def_key(id);
         let parent = self.local_def_id(def_key.parent.unwrap());
         let name = def_key.disambiguated_data.data.get_opt_name().unwrap();
@@ -990,12 +996,12 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
+    fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
         self.root.per_def.variances.get(self, id).unwrap_or(Lazy::empty())
             .decode(self).collect()
     }
 
-    crate fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
+    fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
         match self.kind(node_id) {
             EntryKind::Struct(data, _) |
             EntryKind::Union(data, _) |
@@ -1004,7 +1010,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
+    fn get_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
         match self.kind(node_id) {
             EntryKind::Struct(data, _) => {
                 data.decode(self).ctor.map(|index| self.local_def_id(index))
@@ -1016,7 +1022,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
+    fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
         // The attributes for a tuple struct/variant are attached to the definition, not the ctor;
         // we assume that someone passing in a tuple struct ctor is actually wanting to
         // look at the definition
@@ -1032,7 +1038,7 @@ impl<'a, 'tcx> CrateMetadata {
             .collect::<Vec<_>>())
     }
 
-    crate fn get_struct_field_names(
+    fn get_struct_field_names(
         &self,
         id: DefIndex,
         sess: &Session,
@@ -1058,7 +1064,7 @@ impl<'a, 'tcx> CrateMetadata {
         None
     }
 
-    crate fn get_inherent_implementations_for_type(
+    fn get_inherent_implementations_for_type(
         &self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
@@ -1070,7 +1076,7 @@ impl<'a, 'tcx> CrateMetadata {
         )
     }
 
-    crate fn get_implementations_for_trait(
+    fn get_implementations_for_trait(
         &self,
         tcx: TyCtxt<'tcx>,
         filter: Option<DefId>,
@@ -1101,7 +1107,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
+    fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
         let def_key = self.def_key(id);
         match def_key.disambiguated_data.data {
             DefPathData::TypeNs(..) | DefPathData::ValueNs(..) => (),
@@ -1118,7 +1124,7 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
 
-    crate fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
+    fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not have any *target* native libraries.
             vec![]
@@ -1127,7 +1133,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
+    fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not have any *target* foreign modules.
             &[]
@@ -1136,7 +1142,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_dylib_dependency_formats(
+    fn get_dylib_dependency_formats(
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> &'tcx [(CrateNum, LinkagePreference)] {
@@ -1150,7 +1156,7 @@ impl<'a, 'tcx> CrateMetadata {
             }))
     }
 
-    crate fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
+    fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
         if self.is_proc_macro_crate() {
             // Proc macro crates do not depend on any target weak lang-items.
             &[]
@@ -1161,7 +1167,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
+    fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
         let param_names = match self.kind(id) {
             EntryKind::Fn(data) |
             EntryKind::ForeignFn(data) => data.decode(self).param_names,
@@ -1171,7 +1177,7 @@ impl<'a, 'tcx> CrateMetadata {
         param_names.decode(self).collect()
     }
 
-    crate fn exported_symbols(
+    fn exported_symbols(
         &self,
         tcx: TyCtxt<'tcx>,
     ) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
@@ -1184,7 +1190,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_rendered_const(&self, id: DefIndex) -> String {
+    fn get_rendered_const(&self, id: DefIndex) -> String {
         match self.kind(id) {
             EntryKind::Const(_, data) |
             EntryKind::AssocConst(_, _, data) => data.decode(self).0,
@@ -1192,14 +1198,14 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn get_macro(&self, id: DefIndex) -> MacroDef {
+    fn get_macro(&self, id: DefIndex) -> MacroDef {
         match self.kind(id) {
             EntryKind::MacroDef(macro_def) => macro_def.decode(self),
             _ => bug!(),
         }
     }
 
-    crate fn is_const_fn_raw(&self, id: DefIndex) -> bool {
+    fn is_const_fn_raw(&self, id: DefIndex) -> bool {
         let constness = match self.kind(id) {
             EntryKind::Method(data) => data.decode(self).fn_data.constness,
             EntryKind::Fn(data) => data.decode(self).constness,
@@ -1209,7 +1215,7 @@ impl<'a, 'tcx> CrateMetadata {
         constness == hir::Constness::Const
     }
 
-    crate fn asyncness(&self, id: DefIndex) -> hir::IsAsync {
+    fn asyncness(&self, id: DefIndex) -> hir::IsAsync {
          match self.kind(id) {
             EntryKind::Fn(data) => data.decode(self).asyncness,
             EntryKind::Method(data) => data.decode(self).fn_data.asyncness,
@@ -1218,7 +1224,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn is_foreign_item(&self, id: DefIndex) -> bool {
+    fn is_foreign_item(&self, id: DefIndex) -> bool {
         match self.kind(id) {
             EntryKind::ForeignImmStatic |
             EntryKind::ForeignMutStatic |
@@ -1227,7 +1233,7 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn static_mutability(&self, id: DefIndex) -> Option<hir::Mutability> {
+    fn static_mutability(&self, id: DefIndex) -> Option<hir::Mutability> {
         match self.kind(id) {
             EntryKind::ImmStatic |
             EntryKind::ForeignImmStatic => Some(hir::MutImmutable),
@@ -1237,12 +1243,12 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
+    fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
         self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx))
     }
 
     #[inline]
-    crate fn def_key(&self, index: DefIndex) -> DefKey {
+    fn def_key(&self, index: DefIndex) -> DefKey {
         let mut key = self.def_path_table.def_key(index);
         if self.is_proc_macro(index) {
             let name = self.raw_proc_macro(index).name();
@@ -1252,13 +1258,13 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     // Returns the path leading to the thing with this `id`.
-    crate fn def_path(&self, id: DefIndex) -> DefPath {
+    fn def_path(&self, id: DefIndex) -> DefPath {
         debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
         DefPath::make(self.cnum, id, |parent| self.def_key(parent))
     }
 
     #[inline]
-    crate fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
+    fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
         self.def_path_table.def_path_hash(index)
     }
 
@@ -1356,7 +1362,7 @@ impl<'a, 'tcx> CrateMetadata {
 
     /// Get the `DepNodeIndex` corresponding this crate. The result of this
     /// method is cached in the `dep_node_index` field.
-    pub(super) fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
+    fn get_crate_dep_node_index(&self, tcx: TyCtxt<'tcx>) -> DepNodeIndex {
         let mut dep_node_index = self.dep_node_index.load();
 
         if unlikely!(dep_node_index == DepNodeIndex::INVALID) {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index c5f830c0d04..6eacfc28de2 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -1,9 +1,8 @@
 use crate::cstore::{self, LoadedMacro};
-use crate::encoder;
 use crate::link_args;
 use crate::native_libs;
 use crate::foreign_modules;
-use crate::schema;
+use crate::rmeta::{self, encoder};
 
 use rustc::ty::query::QueryConfig;
 use rustc::middle::cstore::{CrateSource, CrateStore, DepKind, EncodedMetadata, NativeLibraryKind};
@@ -95,8 +94,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     generics_of => {
         tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess))
     }
-    predicates_of => { cdata.get_predicates(def_id.index, tcx) }
-    predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
+    explicit_predicates_of => { cdata.get_explicit_predicates(def_id.index, tcx) }
+    inferred_outlives_of => { cdata.get_inferred_outlives(def_id.index, tcx) }
     super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
     trait_def => {
         tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess))
@@ -529,6 +528,6 @@ impl CrateStore for cstore::CStore {
 
     fn metadata_encoding_version(&self) -> &[u8]
     {
-        schema::METADATA_HEADER
+        rmeta::METADATA_HEADER
     }
 }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index de00e9920e6..afc81649e37 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1,5 +1,5 @@
-use crate::schema::*;
-use crate::table::{FixedSizeEncoding, PerDefTable};
+use crate::rmeta::*;
+use crate::rmeta::table::{FixedSizeEncoding, PerDefTable};
 
 use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
                             EncodedMetadata, ForeignModule};
@@ -76,8 +76,8 @@ struct PerDefTables<'tcx> {
     inherent_impls: PerDefTable<Lazy<[DefIndex]>>,
     variances: PerDefTable<Lazy<[ty::Variance]>>,
     generics: PerDefTable<Lazy<ty::Generics>>,
-    predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
-    predicates_defined_on: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
+    explicit_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
+    inferred_outlives: PerDefTable<Lazy<&'tcx [(ty::Predicate<'tcx>, Span)]>>,
     super_predicates: PerDefTable<Lazy<ty::GenericPredicates<'tcx>>>,
 
     mir: PerDefTable<Lazy<mir::Body<'tcx>>>,
@@ -524,8 +524,8 @@ impl<'tcx> EncodeContext<'tcx> {
             inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque),
             variances: self.per_def.variances.encode(&mut self.opaque),
             generics: self.per_def.generics.encode(&mut self.opaque),
-            predicates: self.per_def.predicates.encode(&mut self.opaque),
-            predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque),
+            explicit_predicates: self.per_def.explicit_predicates.encode(&mut self.opaque),
+            inferred_outlives: self.per_def.inferred_outlives.encode(&mut self.opaque),
             super_predicates: self.per_def.super_predicates.encode(&mut self.opaque),
 
             mir: self.per_def.mir.encode(&mut self.opaque),
@@ -675,7 +675,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -718,7 +719,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -776,7 +778,8 @@ impl EncodeContext<'tcx> {
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
     }
 
     fn encode_struct_ctor(&mut self, adt_def_id: DefId, def_id: DefId) {
@@ -819,7 +822,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -829,15 +833,18 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.generics[def_id] <- self.tcx.generics_of(def_id));
     }
 
-    fn encode_predicates(&mut self, def_id: DefId) {
-        debug!("EncodeContext::encode_predicates({:?})", def_id);
-        record!(self.per_def.predicates[def_id] <- self.tcx.predicates_of(def_id));
+    fn encode_explicit_predicates(&mut self, def_id: DefId) {
+        debug!("EncodeContext::encode_explicit_predicates({:?})", def_id);
+        record!(self.per_def.explicit_predicates[def_id] <-
+            self.tcx.explicit_predicates_of(def_id));
     }
 
-    fn encode_predicates_defined_on(&mut self, def_id: DefId) {
-        debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
-        record!(self.per_def.predicates_defined_on[def_id] <-
-            self.tcx.predicates_defined_on(def_id))
+    fn encode_inferred_outlives(&mut self, def_id: DefId) {
+        debug!("EncodeContext::encode_inferred_outlives({:?})", def_id);
+        let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
+        if !inferred_outlives.is_empty() {
+            record!(self.per_def.inferred_outlives[def_id] <- inferred_outlives);
+        }
     }
 
     fn encode_super_predicates(&mut self, def_id: DefId) {
@@ -919,7 +926,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -986,7 +994,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         let mir = match ast_item.kind {
             hir::ImplItemKind::Const(..) => true,
             hir::ImplItemKind::Method(ref sig, _) => {
@@ -1260,22 +1269,11 @@ impl EncodeContext<'tcx> {
             hir::ItemKind::Trait(..) |
             hir::ItemKind::TraitAlias(..) => {
                 self.encode_generics(def_id);
-                self.encode_predicates(def_id);
+                self.encode_explicit_predicates(def_id);
+                self.encode_inferred_outlives(def_id);
             }
             _ => {}
         }
-        // The only time that `predicates_defined_on` is used (on
-        // an external item) is for traits, during chalk lowering,
-        // so only encode it in that case as an efficiency
-        // hack. (No reason not to expand it in the future if
-        // necessary.)
-        match item.kind {
-            hir::ItemKind::Trait(..) |
-            hir::ItemKind::TraitAlias(..) => {
-                self.encode_predicates_defined_on(def_id);
-            }
-            _ => {} // not *wrong* for other kinds of items, but not needed
-        }
         match item.kind {
             hir::ItemKind::Trait(..) |
             hir::ItemKind::TraitAlias(..) => {
@@ -1377,7 +1375,8 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
         self.encode_item_type(def_id);
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
         self.encode_optimized_mir(def_id);
         self.encode_promoted_mir(def_id);
     }
@@ -1588,7 +1587,8 @@ impl EncodeContext<'tcx> {
             self.encode_variances_of(def_id);
         }
         self.encode_generics(def_id);
-        self.encode_predicates(def_id);
+        self.encode_explicit_predicates(def_id);
+        self.encode_inferred_outlives(def_id);
     }
 }
 
@@ -1781,7 +1781,7 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
 // will allow us to slice the metadata to the precise length that we just
 // generated regardless of trailing bytes that end up in it.
 
-crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
+pub(super) fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
     let mut encoder = opaque::Encoder::new(vec![]);
     encoder.emit_raw_bytes(METADATA_HEADER);
 
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/rmeta/mod.rs
index 8bece251116..4eabeac6d98 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -1,4 +1,5 @@
-use crate::table::PerDefTable;
+use decoder::Metadata;
+use table::PerDefTable;
 
 use rustc::hir;
 use rustc::hir::def::{self, CtorKind};
@@ -13,7 +14,6 @@ use rustc::ty::{self, Ty, ReprOptions};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
 use rustc_index::vec::IndexVec;
 use rustc_data_structures::svh::Svh;
-
 use rustc_serialize::Encodable;
 use syntax::{ast, attr};
 use syntax::edition::Edition;
@@ -23,6 +23,12 @@ use syntax_pos::{self, Span};
 use std::marker::PhantomData;
 use std::num::NonZeroUsize;
 
+pub use decoder::{provide, provide_extern};
+
+mod decoder;
+mod encoder;
+mod table;
+
 crate fn rustc_version() -> String {
     format!("rustc {}",
             option_env!("CFG_VERSION").unwrap_or("unknown version"))
@@ -104,13 +110,13 @@ crate struct Lazy<T, Meta = <T as LazyMeta>::Meta>
     where T: ?Sized + LazyMeta<Meta = Meta>,
           Meta: 'static + Copy,
 {
-    pub position: NonZeroUsize,
-    pub meta: Meta,
+    position: NonZeroUsize,
+    meta: Meta,
     _marker: PhantomData<T>,
 }
 
 impl<T: ?Sized + LazyMeta> Lazy<T> {
-     crate fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
+     fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
         Lazy {
             position,
             meta,
@@ -120,13 +126,13 @@ impl<T: ?Sized + LazyMeta> Lazy<T> {
 }
 
 impl<T: Encodable> Lazy<T> {
-    crate fn from_position(position: NonZeroUsize) -> Lazy<T> {
+    fn from_position(position: NonZeroUsize) -> Lazy<T> {
         Lazy::from_position_and_meta(position, ())
     }
 }
 
 impl<T: Encodable> Lazy<[T]> {
-    crate fn empty() -> Lazy<[T]> {
+    fn empty() -> Lazy<[T]> {
         Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
     }
 }
@@ -143,7 +149,7 @@ impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedDecodable for Lazy<T>
 
 /// Encoding / decoding state for `Lazy`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
-crate enum LazyState {
+enum LazyState {
     /// Outside of a metadata node.
     NoNode,
 
@@ -171,46 +177,46 @@ macro_rules! Lazy {
 crate struct CrateRoot<'tcx> {
     pub name: Symbol,
     pub triple: TargetTriple,
-    pub extra_filename: String,
+    extra_filename: String,
     pub hash: Svh,
     pub disambiguator: CrateDisambiguator,
     pub panic_strategy: PanicStrategy,
-    pub edition: Edition,
+    edition: Edition,
     pub has_global_allocator: bool,
-    pub has_panic_handler: bool,
+    has_panic_handler: bool,
     pub has_default_lib_allocator: bool,
-    pub plugin_registrar_fn: Option<DefIndex>,
-    pub proc_macro_decls_static: Option<DefIndex>,
-    pub proc_macro_stability: Option<attr::Stability>,
+    plugin_registrar_fn: Option<DefIndex>,
+    proc_macro_decls_static: Option<DefIndex>,
+    proc_macro_stability: Option<attr::Stability>,
 
     pub crate_deps: Lazy<[CrateDep]>,
-    pub dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
-    pub lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
-    pub lang_items: Lazy<[(DefIndex, usize)]>,
-    pub lang_items_missing: Lazy<[lang_items::LangItem]>,
-    pub diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
-    pub native_libraries: Lazy<[NativeLibrary]>,
-    pub foreign_modules: Lazy<[ForeignModule]>,
-    pub source_map: Lazy<[syntax_pos::SourceFile]>,
+    dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
+    lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
+    lang_items: Lazy<[(DefIndex, usize)]>,
+    lang_items_missing: Lazy<[lang_items::LangItem]>,
+    diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
+    native_libraries: Lazy<[NativeLibrary]>,
+    foreign_modules: Lazy<[ForeignModule]>,
+    source_map: Lazy<[syntax_pos::SourceFile]>,
     pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
     pub impls: Lazy<[TraitImpls]>,
-    pub exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
+    exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
     pub interpret_alloc_index: Lazy<[u32]>,
 
-    pub per_def: LazyPerDefTables<'tcx>,
+    per_def: LazyPerDefTables<'tcx>,
 
     /// The DefIndex's of any proc macros delcared by
     /// this crate
     pub proc_macro_data: Option<Lazy<[DefIndex]>>,
 
-    pub compiler_builtins: bool,
+    compiler_builtins: bool,
     pub needs_allocator: bool,
     pub needs_panic_runtime: bool,
-    pub no_builtins: bool,
+    no_builtins: bool,
     pub panic_runtime: bool,
     pub profiler_runtime: bool,
     pub sanitizer_runtime: bool,
-    pub symbol_mangling_version: SymbolManglingVersion,
+    symbol_mangling_version: SymbolManglingVersion,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -230,30 +236,33 @@ crate struct TraitImpls {
 
 #[derive(RustcEncodable, RustcDecodable)]
 crate struct LazyPerDefTables<'tcx> {
-    pub kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
-    pub visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
-    pub span: Lazy!(PerDefTable<Lazy<Span>>),
-    pub attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
-    pub children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
-    pub stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
-    pub deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
-
-    pub ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
-    pub fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
-    pub impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
-    pub inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
-    pub variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
-    pub generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
-    pub predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-    pub predicates_defined_on: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-    pub super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
-
-    pub mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
-    pub promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
+    kind: Lazy!(PerDefTable<Lazy!(EntryKind<'tcx>)>),
+    visibility: Lazy!(PerDefTable<Lazy<ty::Visibility>>),
+    span: Lazy!(PerDefTable<Lazy<Span>>),
+    attributes: Lazy!(PerDefTable<Lazy<[ast::Attribute]>>),
+    children: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
+    stability: Lazy!(PerDefTable<Lazy<attr::Stability>>),
+    deprecation: Lazy!(PerDefTable<Lazy<attr::Deprecation>>),
+    ty: Lazy!(PerDefTable<Lazy!(Ty<'tcx>)>),
+    fn_sig: Lazy!(PerDefTable<Lazy!(ty::PolyFnSig<'tcx>)>),
+    impl_trait_ref: Lazy!(PerDefTable<Lazy!(ty::TraitRef<'tcx>)>),
+    inherent_impls: Lazy!(PerDefTable<Lazy<[DefIndex]>>),
+    variances: Lazy!(PerDefTable<Lazy<[ty::Variance]>>),
+    generics: Lazy!(PerDefTable<Lazy<ty::Generics>>),
+    explicit_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
+    // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
+    // doesn't handle shorthands in its own (de)serialization impls,
+    // as it's an `enum` for which we want to derive (de)serialization,
+    // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
+    // Also, as an optimization, a missing entry indicates an empty `&[]`.
+    inferred_outlives: Lazy!(PerDefTable<Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>),
+    super_predicates: Lazy!(PerDefTable<Lazy!(ty::GenericPredicates<'tcx>)>),
+    mir: Lazy!(PerDefTable<Lazy!(mir::Body<'tcx>)>),
+    promoted_mir: Lazy!(PerDefTable<Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>),
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-crate enum EntryKind<'tcx> {
+enum EntryKind<'tcx> {
     Const(ConstQualif, Lazy<RenderedConst>),
     ImmStatic,
     MutStatic,
@@ -288,58 +297,58 @@ crate enum EntryKind<'tcx> {
 
 /// Additional data for EntryKind::Const and EntryKind::AssocConst
 #[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
-crate struct ConstQualif {
-    pub mir: u8,
+struct ConstQualif {
+    mir: u8,
 }
 
 /// Contains a constant which has been rendered to a String.
 /// Used by rustdoc.
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct RenderedConst(pub String);
+struct RenderedConst(String);
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct ModData {
-    pub reexports: Lazy<[def::Export<hir::HirId>]>,
+struct ModData {
+    reexports: Lazy<[def::Export<hir::HirId>]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct MacroDef {
-    pub body: String,
-    pub legacy: bool,
+struct MacroDef {
+    body: String,
+    legacy: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct FnData {
-    pub asyncness: hir::IsAsync,
-    pub constness: hir::Constness,
-    pub param_names: Lazy<[ast::Name]>,
+struct FnData {
+    asyncness: hir::IsAsync,
+    constness: hir::Constness,
+    param_names: Lazy<[ast::Name]>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct VariantData {
-    pub ctor_kind: CtorKind,
-    pub discr: ty::VariantDiscr,
+struct VariantData {
+    ctor_kind: CtorKind,
+    discr: ty::VariantDiscr,
     /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
-    pub ctor: Option<DefIndex>,
+    ctor: Option<DefIndex>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct TraitData {
-    pub unsafety: hir::Unsafety,
-    pub paren_sugar: bool,
-    pub has_auto_impl: bool,
-    pub is_marker: bool,
+struct TraitData {
+    unsafety: hir::Unsafety,
+    paren_sugar: bool,
+    has_auto_impl: bool,
+    is_marker: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct ImplData {
-    pub polarity: ty::ImplPolarity,
-    pub defaultness: hir::Defaultness,
-    pub parent_impl: Option<DefId>,
+struct ImplData {
+    polarity: ty::ImplPolarity,
+    defaultness: hir::Defaultness,
+    parent_impl: Option<DefId>,
 
     /// This is `Some` only for impls of `CoerceUnsized`.
     // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
-    pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
+    coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
 }
 
 
@@ -347,7 +356,7 @@ crate struct ImplData {
 /// is a trait or an impl and whether, in a trait, it has
 /// a default, or an in impl, whether it's marked "default".
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-crate enum AssocContainer {
+enum AssocContainer {
     TraitRequired,
     TraitWithDefault,
     ImplDefault,
@@ -355,7 +364,7 @@ crate enum AssocContainer {
 }
 
 impl AssocContainer {
-    crate fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
+    fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
         match *self {
             AssocContainer::TraitRequired |
             AssocContainer::TraitWithDefault => ty::TraitContainer(def_id),
@@ -365,7 +374,7 @@ impl AssocContainer {
         }
     }
 
-    crate fn defaultness(&self) -> hir::Defaultness {
+    fn defaultness(&self) -> hir::Defaultness {
         match *self {
             AssocContainer::TraitRequired => hir::Defaultness::Default {
                 has_value: false,
@@ -382,17 +391,17 @@ impl AssocContainer {
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct MethodData {
-    pub fn_data: FnData,
-    pub container: AssocContainer,
-    pub has_self: bool,
+struct MethodData {
+    fn_data: FnData,
+    container: AssocContainer,
+    has_self: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
-crate struct GeneratorData<'tcx> {
-    pub layout: mir::GeneratorLayout<'tcx>,
+struct GeneratorData<'tcx> {
+    layout: mir::GeneratorLayout<'tcx>,
 }
 
 // Tags used for encoding Spans:
-crate const TAG_VALID_SPAN: u8 = 0;
-crate const TAG_INVALID_SPAN: u8 = 1;
+const TAG_VALID_SPAN: u8 = 0;
+const TAG_INVALID_SPAN: u8 = 1;
diff --git a/src/librustc_metadata/table.rs b/src/librustc_metadata/rmeta/table.rs
index e164c28c953..613d92c6d7b 100644
--- a/src/librustc_metadata/table.rs
+++ b/src/librustc_metadata/rmeta/table.rs
@@ -1,5 +1,4 @@
-use crate::decoder::Metadata;
-use crate::schema::*;
+use crate::rmeta::*;
 
 use rustc::hir::def_id::{DefId, DefIndex};
 use rustc_serialize::{Encodable, opaque::Encoder};
@@ -12,7 +11,7 @@ use log::debug;
 /// Used mainly for Lazy positions and lengths.
 /// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`,
 /// but this has no impact on safety.
-crate trait FixedSizeEncoding: Default {
+pub(super) trait FixedSizeEncoding: Default {
     const BYTE_LEN: usize;
 
     // FIXME(eddyb) convert to and from `[u8; Self::BYTE_LEN]` instead,
@@ -126,7 +125,7 @@ impl<T: Encodable> FixedSizeEncoding for Option<Lazy<[T]>> {
 // FIXME(eddyb) replace `Vec` with `[_]` here, such that `Box<Table<T>>` would be used
 // when building it, and `Lazy<Table<T>>` or `&Table<T>` when reading it.
 // (not sure if that is possible given that the `Vec` is being resized now)
-crate struct Table<T> where Option<T>: FixedSizeEncoding {
+pub(super) struct Table<T> where Option<T>: FixedSizeEncoding {
     // FIXME(eddyb) store `[u8; <Option<T>>::BYTE_LEN]` instead of `u8` in `Vec`,
     // once that starts being allowed by the compiler (i.e. lazy normalization).
     bytes: Vec<u8>,
@@ -143,7 +142,7 @@ impl<T> Default for Table<T> where Option<T>: FixedSizeEncoding {
 }
 
 impl<T> Table<T> where Option<T>: FixedSizeEncoding {
-    crate fn set(&mut self, i: usize, value: T) {
+    fn set(&mut self, i: usize, value: T) {
         // FIXME(eddyb) investigate more compact encodings for sparse tables.
         // On the PR @michaelwoerister mentioned:
         // > Space requirements could perhaps be optimized by using the HAMT `popcnt`
@@ -157,7 +156,7 @@ impl<T> Table<T> where Option<T>: FixedSizeEncoding {
         Some(value).write_to_bytes_at(&mut self.bytes, i);
     }
 
-    crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
+    fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
         let pos = buf.position();
         buf.emit_raw_bytes(&self.bytes);
         Lazy::from_position_and_meta(
@@ -178,7 +177,7 @@ impl<T> LazyMeta for Table<T> where Option<T>: FixedSizeEncoding {
 impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
     /// Given the metadata, extract out the value at a particular index (if any).
     #[inline(never)]
-    crate fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
+    fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
         &self,
         metadata: M,
         i: usize,
@@ -194,7 +193,7 @@ impl<T> Lazy<Table<T>> where Option<T>: FixedSizeEncoding {
 /// Like a `Table` but using `DefIndex` instead of `usize` as keys.
 // FIXME(eddyb) replace by making `Table` behave like `IndexVec`,
 // and by using `newtype_index!` to define `DefIndex`.
-crate struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
+pub(super) struct PerDefTable<T>(Table<T>) where Option<T>: FixedSizeEncoding;
 
 impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
     fn default() -> Self {
@@ -203,12 +202,12 @@ impl<T> Default for PerDefTable<T> where Option<T>: FixedSizeEncoding {
 }
 
 impl<T> PerDefTable<T> where Option<T>: FixedSizeEncoding {
-    crate fn set(&mut self, def_id: DefId, value: T) {
+    pub(super) fn set(&mut self, def_id: DefId, value: T) {
         assert!(def_id.is_local());
         self.0.set(def_id.index.index(), value);
     }
 
-    crate fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
+    pub(super) fn encode(&self, buf: &mut Encoder) -> Lazy<Self> {
         let lazy = self.0.encode(buf);
         Lazy::from_position_and_meta(lazy.position, lazy.meta)
     }
@@ -229,7 +228,7 @@ impl<T> Lazy<PerDefTable<T>> where Option<T>: FixedSizeEncoding {
 
     /// Given the metadata, extract out the value at a particular DefIndex (if any).
     #[inline(never)]
-    crate fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
+    pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(
         &self,
         metadata: M,
         def_index: DefIndex,
diff --git a/src/librustc_mir/hair/constant.rs b/src/librustc_mir/hair/constant.rs
index 956716f8cea..b9e75a576ca 100644
--- a/src/librustc_mir/hair/constant.rs
+++ b/src/librustc_mir/hair/constant.rs
@@ -45,10 +45,7 @@ crate fn lit_to_const<'tcx>(
             trunc(n as u128)?
         },
         LitKind::Int(n, _) => trunc(n)?,
-        LitKind::Float(n, fty) => {
-            parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
-        }
-        LitKind::FloatUnsuffixed(n) => {
+        LitKind::Float(n, _) => {
             let fty = match ty.kind {
                 ty::Float(fty) => fty,
                 _ => bug!()
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 1ecc78ba227..477ad10460f 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -293,10 +293,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                 match self.ty.kind {
                     ty::Adt(def, _) if def.is_box() => write!(f, "box ")?,
                     ty::Ref(_, _, mutbl) => {
-                        write!(f, "&")?;
-                        if mutbl == hir::MutMutable {
-                            write!(f, "mut ")?;
-                        }
+                        write!(f, "&{}", mutbl.prefix_str())?;
                     }
                     _ => bug!("{} is a bad Deref pattern type", self.ty)
                 }
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 9ab347957f9..2037305580a 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -260,7 +260,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         match (&src_pointee_ty.kind, &dest_pointee_ty.kind) {
             (&ty::Array(_, length), &ty::Slice(_)) => {
-                let ptr = self.read_immediate(src)?.to_scalar_ptr()?;
+                let ptr = self.read_immediate(src)?.to_scalar()?;
                 // u64 cast is from usize to u64, which is always good
                 let val = Immediate::new_slice(
                     ptr,
@@ -279,7 +279,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             (_, &ty::Dynamic(ref data, _)) => {
                 // Initial cast from sized to dyn trait
                 let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
-                let ptr = self.read_immediate(src)?.to_scalar_ptr()?;
+                let ptr = self.read_immediate(src)?.to_scalar()?;
                 let val = Immediate::new_dyn_trait(ptr, vtable);
                 self.write_immediate(val, dest)
             }
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 924529d7f55..2171ceaa452 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -192,20 +192,18 @@ for
         let ty = mplace.layout.ty;
         if let ty::Ref(_, referenced_ty, mutability) = ty.kind {
             let value = self.ecx.read_immediate(mplace.into())?;
+            let mplace = self.ecx.ref_to_mplace(value)?;
             // Handle trait object vtables
-            if let Ok(meta) = value.to_meta() {
-                if let ty::Dynamic(..) =
-                    self.ecx.tcx.struct_tail_erasing_lifetimes(
-                        referenced_ty, self.ecx.param_env).kind
-                {
-                    if let Ok(vtable) = meta.unwrap().to_ptr() {
-                        // explitly choose `Immutable` here, since vtables are immutable, even
-                        // if the reference of the fat pointer is mutable
-                        self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
-                    }
+            if let ty::Dynamic(..) =
+                self.ecx.tcx.struct_tail_erasing_lifetimes(
+                    referenced_ty, self.ecx.param_env).kind
+            {
+                if let Ok(vtable) = mplace.meta.unwrap().to_ptr() {
+                    // explitly choose `Immutable` here, since vtables are immutable, even
+                    // if the reference of the fat pointer is mutable
+                    self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
                 }
             }
-            let mplace = self.ecx.ref_to_mplace(value)?;
             // Check if we have encountered this pointer+layout combination before.
             // Only recurse for allocation-backed pointers.
             if let Scalar::Ptr(ptr) = mplace.ptr {
@@ -230,7 +228,7 @@ for
                             ty::Array(_, n)
                                 if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
                             ty::Slice(_)
-                                if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
+                                if mplace.meta.unwrap().to_usize(self.ecx)? == 0 => {}
                             _ => bug!("const qualif failed to prevent mutable references"),
                         }
                     },
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index ae23971849e..d80ad3848d2 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -82,26 +82,6 @@ impl<'tcx, Tag> Immediate<Tag> {
             Immediate::ScalarPair(a, b) => Ok((a.not_undef()?, b.not_undef()?))
         }
     }
-
-    /// Converts the immediate into a pointer (or a pointer-sized integer).
-    /// Throws away the second half of a ScalarPair!
-    #[inline]
-    pub fn to_scalar_ptr(self) -> InterpResult<'tcx, Scalar<Tag>> {
-        match self {
-            Immediate::Scalar(ptr) |
-            Immediate::ScalarPair(ptr, _) => ptr.not_undef(),
-        }
-    }
-
-    /// Converts the value into its metadata.
-    /// Throws away the first half of a ScalarPair!
-    #[inline]
-    pub fn to_meta(self) -> InterpResult<'tcx, Option<Scalar<Tag>>> {
-        Ok(match self {
-            Immediate::Scalar(_) => None,
-            Immediate::ScalarPair(_, meta) => Some(meta.not_undef()?),
-        })
-    }
 }
 
 // ScalarPair needs a type to interpret, so we often have an immediate and a type together
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 0289c52fd37..36e58d356d1 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -287,17 +287,23 @@ where
         &self,
         val: ImmTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
-        let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
+        let pointee_type = val.layout.ty.builtin_deref(true)
+            .expect("`ref_to_mplace` called on non-ptr type")
+            .ty;
         let layout = self.layout_of(pointee_type)?;
+        let (ptr, meta) = match *val {
+            Immediate::Scalar(ptr) => (ptr.not_undef()?, None),
+            Immediate::ScalarPair(ptr, meta) => (ptr.not_undef()?, Some(meta.not_undef()?)),
+        };
 
         let mplace = MemPlace {
-            ptr: val.to_scalar_ptr()?,
+            ptr,
             // We could use the run-time alignment here. For now, we do not, because
             // the point of tracking the alignment here is to make sure that the *static*
             // alignment information emitted with the loads is correct. The run-time
             // alignment can only be more restrictive.
             align: layout.align.abi,
-            meta: val.to_meta()?,
+            meta,
         };
         Ok(MPlaceTy { mplace, layout })
     }
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 82b8b28d72b..8cb2f6c3462 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -388,44 +388,31 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 }
             }
             ty::RawPtr(..) => {
-                // Check pointer part.
-                if self.ref_tracking_for_consts.is_some() {
-                    // Integers/floats in CTFE: For consistency with integers, we do not
-                    // accept undef.
-                    let _ptr = try_validation!(value.to_scalar_ptr(),
-                        "undefined address in raw pointer", self.path);
-                } else {
-                    // Remain consistent with `usize`: Accept anything.
-                }
-
-                // Check metadata.
-                let meta = try_validation!(value.to_meta(),
-                    "uninitialized data in wide pointer metadata", self.path);
-                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
-                if layout.is_unsized() {
-                    self.check_wide_ptr_meta(meta, layout)?;
+                // We are conservative with undef for integers, but try to
+                // actually enforce our current rules for raw pointers.
+                let place = try_validation!(self.ecx.ref_to_mplace(value),
+                    "undefined pointer", self.path);
+                if place.layout.is_unsized() {
+                    self.check_wide_ptr_meta(place.meta, place.layout)?;
                 }
             }
             _ if ty.is_box() || ty.is_region_ptr() => {
                 // Handle wide pointers.
                 // Check metadata early, for better diagnostics
-                let ptr = try_validation!(value.to_scalar_ptr(),
-                    "undefined address in pointer", self.path);
-                let meta = try_validation!(value.to_meta(),
-                    "uninitialized data in wide pointer metadata", self.path);
-                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
-                if layout.is_unsized() {
-                    self.check_wide_ptr_meta(meta, layout)?;
+                let place = try_validation!(self.ecx.ref_to_mplace(value),
+                    "undefined pointer", self.path);
+                if place.layout.is_unsized() {
+                    self.check_wide_ptr_meta(place.meta, place.layout)?;
                 }
                 // Make sure this is dereferencable and all.
-                let (size, align) = self.ecx.size_and_align_of(meta, layout)?
+                let (size, align) = self.ecx.size_and_align_of(place.meta, place.layout)?
                     // for the purpose of validity, consider foreign types to have
                     // alignment and size determined by the layout (size will be 0,
                     // alignment should take attributes into account).
-                    .unwrap_or_else(|| (layout.size, layout.align.abi));
+                    .unwrap_or_else(|| (place.layout.size, place.layout.align.abi));
                 let ptr: Option<_> = match
                     self.ecx.memory.check_ptr_access_align(
-                        ptr,
+                        place.ptr,
                         size,
                         Some(align),
                         CheckInAllocMsg::InboundsTest,
@@ -435,7 +422,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                     Err(err) => {
                         info!(
                             "{:?} did not pass access check for size {:?}, align {:?}",
-                            ptr, size, align
+                            place.ptr, size, align
                         );
                         match err.kind {
                             err_unsup!(InvalidNullPointerUsage) =>
@@ -459,7 +446,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 };
                 // Recursive checking
                 if let Some(ref mut ref_tracking) = self.ref_tracking_for_consts {
-                    let place = self.ecx.ref_to_mplace(value)?;
                     if let Some(ptr) = ptr { // not a ZST
                         // Skip validation entirely for some external statics
                         let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
@@ -627,7 +613,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 // reject it.  However, that's good: We don't inherently want
                 // to reject those pointers, we just do not have the machinery to
                 // talk about parts of a pointer.
-                // We also accept undef, for consistency with the type-based checks.
+                // We also accept undef, for consistency with the slow path.
                 match self.ecx.memory.get(ptr.alloc_id)?.check_bytes(
                     self.ecx,
                     ptr,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 76899dad41a..6a7058f1930 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -6,7 +6,6 @@
 
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::IndexVec;
-use rustc_data_structures::fx::FxHashSet;
 use rustc_target::spec::abi::Abi;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -20,7 +19,6 @@ use rustc::mir::traversal::ReversePostorder;
 use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
 use rustc::middle::lang_items;
 use rustc::session::config::nightly_options;
-use syntax::ast::LitKind;
 use syntax::feature_gate::{emit_feature_err, GateIssue};
 use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
@@ -71,7 +69,7 @@ impl fmt::Display for Mode {
     }
 }
 
-const QUALIF_COUNT: usize = 4;
+const QUALIF_COUNT: usize = 2;
 
 // FIXME(eddyb) once we can use const generics, replace this array with
 // something like `IndexVec` but for fixed-size arrays (`IndexArray`?).
@@ -80,20 +78,20 @@ struct PerQualif<T>([T; QUALIF_COUNT]);
 
 impl<T: Clone> PerQualif<T> {
     fn new(x: T) -> Self {
-        PerQualif([x.clone(), x.clone(), x.clone(), x])
+        PerQualif([x.clone(), x])
     }
 }
 
 impl<T> PerQualif<T> {
     fn as_mut(&mut self) -> PerQualif<&mut T> {
-        let [x0, x1, x2, x3] = &mut self.0;
-        PerQualif([x0, x1, x2, x3])
+        let [x0, x1] = &mut self.0;
+        PerQualif([x0, x1])
     }
 
     fn zip<U>(self, other: PerQualif<U>) -> PerQualif<(T, U)> {
-        let [x0, x1, x2, x3] = self.0;
-        let [y0, y1, y2, y3] = other.0;
-        PerQualif([(x0, y0), (x1, y1), (x2, y2), (x3, y3)])
+        let [x0, x1] = self.0;
+        let [y0, y1] = other.0;
+        PerQualif([(x0, y0), (x1, y1)])
     }
 }
 
@@ -429,195 +427,6 @@ impl Qualif for NeedsDrop {
     }
 }
 
-/// Not promotable at all - non-`const fn` calls, `asm!`,
-/// pointer comparisons, ptr-to-int casts, etc.
-/// Inside a const context all constness rules apply, so promotion simply has to follow the regular
-/// constant rules (modulo interior mutability or `Drop` rules which are handled `HasMutInterior`
-/// and `NeedsDrop` respectively). Basically this duplicates the checks that the const-checking
-/// visitor enforces by emitting errors when working in const context.
-struct IsNotPromotable;
-
-impl Qualif for IsNotPromotable {
-    const IDX: usize = 2;
-
-    fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
-        match static_.kind {
-            StaticKind::Promoted(_, _) => unreachable!(),
-            StaticKind::Static => {
-                // Only allow statics (not consts) to refer to other statics.
-                // FIXME(eddyb) does this matter at all for promotion?
-                let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut;
-
-                !allowed ||
-                    cx.tcx.get_attrs(static_.def_id).iter().any(
-                        |attr| attr.check_name(sym::thread_local)
-                    )
-            }
-        }
-    }
-
-    fn in_projection(
-        cx: &ConstCx<'_, 'tcx>,
-        place: PlaceRef<'_, 'tcx>,
-    ) -> bool {
-        if let [proj_base @ .., elem] = place.projection {
-            match elem {
-                ProjectionElem::Deref |
-                ProjectionElem::Downcast(..) => return true,
-
-                ProjectionElem::ConstantIndex {..} |
-                ProjectionElem::Subslice {..} |
-                ProjectionElem::Index(_) => {}
-
-                ProjectionElem::Field(..) => {
-                    if cx.mode == Mode::NonConstFn {
-                        let base_ty = Place::ty_from(place.base, proj_base, cx.body, cx.tcx).ty;
-                        if let Some(def) = base_ty.ty_adt_def() {
-                            // No promotion of union field accesses.
-                            if def.is_union() {
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-
-            Self::in_projection_structurally(cx, place)
-        } else {
-            bug!("This should be called if projection is not empty");
-        }
-    }
-
-    fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {
-        match *rvalue {
-            Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) if cx.mode == Mode::NonConstFn => {
-                let operand_ty = operand.ty(cx.body, cx.tcx);
-                let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
-                let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
-                match (cast_in, cast_out) {
-                    (CastTy::Ptr(_), CastTy::Int(_)) |
-                    (CastTy::FnPtr, CastTy::Int(_)) => {
-                        // in normal functions, mark such casts as not promotable
-                        return true;
-                    }
-                    _ => {}
-                }
-            }
-
-            Rvalue::BinaryOp(op, ref lhs, _) if cx.mode == Mode::NonConstFn => {
-                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(cx.body, cx.tcx).kind {
-                    assert!(op == BinOp::Eq || op == BinOp::Ne ||
-                            op == BinOp::Le || op == BinOp::Lt ||
-                            op == BinOp::Ge || op == BinOp::Gt ||
-                            op == BinOp::Offset);
-
-                    // raw pointer operations are not allowed inside promoteds
-                    return true;
-                }
-            }
-
-            Rvalue::NullaryOp(NullOp::Box, _) => return true,
-
-            _ => {}
-        }
-
-        Self::in_rvalue_structurally(cx, rvalue)
-    }
-
-    fn in_call(
-        cx: &ConstCx<'_, 'tcx>,
-        callee: &Operand<'tcx>,
-        args: &[Operand<'tcx>],
-        _return_ty: Ty<'tcx>,
-    ) -> bool {
-        let fn_ty = callee.ty(cx.body, cx.tcx);
-        match fn_ty.kind {
-            ty::FnDef(def_id, _) => {
-                match cx.tcx.fn_sig(def_id).abi() {
-                    Abi::RustIntrinsic |
-                    Abi::PlatformIntrinsic => {
-                        assert!(!cx.tcx.is_const_fn(def_id));
-                        match &*cx.tcx.item_name(def_id).as_str() {
-                            | "size_of"
-                            | "min_align_of"
-                            | "needs_drop"
-                            | "type_id"
-                            | "bswap"
-                            | "bitreverse"
-                            | "ctpop"
-                            | "cttz"
-                            | "cttz_nonzero"
-                            | "ctlz"
-                            | "ctlz_nonzero"
-                            | "wrapping_add"
-                            | "wrapping_sub"
-                            | "wrapping_mul"
-                            | "unchecked_shl"
-                            | "unchecked_shr"
-                            | "rotate_left"
-                            | "rotate_right"
-                            | "add_with_overflow"
-                            | "sub_with_overflow"
-                            | "mul_with_overflow"
-                            | "saturating_add"
-                            | "saturating_sub"
-                            | "transmute"
-                            | "simd_insert"
-                            | "simd_extract"
-                            | "ptr_offset_from"
-                            => return true,
-
-                            _ => {}
-                        }
-                    }
-                    _ => {
-                        let is_const_fn =
-                            cx.tcx.is_const_fn(def_id) ||
-                            cx.tcx.is_unstable_const_fn(def_id).is_some() ||
-                            cx.is_const_panic_fn(def_id);
-                        if !is_const_fn {
-                            return true;
-                        }
-                    }
-                }
-            }
-            _ => return true,
-        }
-
-        Self::in_operand(cx, callee) || args.iter().any(|arg| Self::in_operand(cx, arg))
-    }
-}
-
-/// Refers to temporaries which cannot be promoted *implicitly*.
-/// Explicit promotion happens e.g. for constant arguments declared via `rustc_args_required_const`.
-/// Implicit promotion has almost the same rules, except that disallows `const fn` except for
-/// those marked `#[rustc_promotable]`. This is to avoid changing a legitimate run-time operation
-/// into a failing compile-time operation e.g. due to addresses being compared inside the function.
-struct IsNotImplicitlyPromotable;
-
-impl Qualif for IsNotImplicitlyPromotable {
-    const IDX: usize = 3;
-
-    fn in_call(
-        cx: &ConstCx<'_, 'tcx>,
-        callee: &Operand<'tcx>,
-        args: &[Operand<'tcx>],
-        _return_ty: Ty<'tcx>,
-    ) -> bool {
-        if cx.mode == Mode::NonConstFn {
-            if let ty::FnDef(def_id, _) = callee.ty(cx.body, cx.tcx).kind {
-                // Never promote runtime `const fn` calls of
-                // functions without `#[rustc_promotable]`.
-                if !cx.tcx.is_promotable_const_fn(def_id) {
-                    return true;
-                }
-            }
-        }
-
-        Self::in_operand(cx, callee) || args.iter().any(|arg| Self::in_operand(cx, arg))
-    }
-}
-
 // Ensure the `IDX` values are sequential (`0..QUALIF_COUNT`).
 macro_rules! static_assert_seq_qualifs {
     ($i:expr => $first:ident $(, $rest:ident)*) => {
@@ -632,7 +441,7 @@ macro_rules! static_assert_seq_qualifs {
     };
 }
 static_assert_seq_qualifs!(
-    0 => HasMutInterior, NeedsDrop, IsNotPromotable, IsNotImplicitlyPromotable
+    0 => HasMutInterior, NeedsDrop
 );
 
 impl ConstCx<'_, 'tcx> {
@@ -640,9 +449,6 @@ impl ConstCx<'_, 'tcx> {
         let mut qualifs = PerQualif::default();
         qualifs[HasMutInterior] = HasMutInterior::in_any_value_of_ty(self, ty).unwrap_or(false);
         qualifs[NeedsDrop] = NeedsDrop::in_any_value_of_ty(self, ty).unwrap_or(false);
-        qualifs[IsNotPromotable] = IsNotPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
-        qualifs[IsNotImplicitlyPromotable] =
-            IsNotImplicitlyPromotable::in_any_value_of_ty(self, ty).unwrap_or(false);
         qualifs
     }
 
@@ -650,8 +456,6 @@ impl ConstCx<'_, 'tcx> {
         let mut qualifs = PerQualif::default();
         qualifs[HasMutInterior] = HasMutInterior::in_local(self, local);
         qualifs[NeedsDrop] = NeedsDrop::in_local(self, local);
-        qualifs[IsNotPromotable] = IsNotPromotable::in_local(self, local);
-        qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_local(self, local);
         qualifs
     }
 
@@ -659,8 +463,6 @@ impl ConstCx<'_, 'tcx> {
         let mut qualifs = PerQualif::default();
         qualifs[HasMutInterior] = HasMutInterior::in_value(self, source);
         qualifs[NeedsDrop] = NeedsDrop::in_value(self, source);
-        qualifs[IsNotPromotable] = IsNotPromotable::in_value(self, source);
-        qualifs[IsNotImplicitlyPromotable] = IsNotImplicitlyPromotable::in_value(self, source);
         qualifs
     }
 }
@@ -678,7 +480,6 @@ struct Checker<'a, 'tcx> {
     rpo: ReversePostorder<'a, 'tcx>,
 
     temp_promotion_state: IndexVec<Local, TempState>,
-    promotion_candidates: Vec<Candidate>,
     unchecked_promotion_candidates: Vec<Candidate>,
 
     /// If `true`, do not emit errors to the user, merely collect them in `errors`.
@@ -732,14 +533,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     }
                 }
             }
-            if !temps[local].is_promotable() {
-                cx.per_local[IsNotPromotable].insert(local);
-            }
-            if let LocalKind::Var = body.local_kind(local) {
-                // Sanity check to prevent implicit and explicit promotion of
-                // named locals
-                assert!(cx.per_local[IsNotPromotable].contains(local));
-            }
         }
 
         Checker {
@@ -748,7 +541,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
             def_id,
             rpo,
             temp_promotion_state: temps,
-            promotion_candidates: vec![],
             unchecked_promotion_candidates,
             errors: vec![],
             suppress_errors: false,
@@ -794,16 +586,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
         let mut qualifs = self.qualifs_in_value(source);
 
         match source {
-            ValueSource::Rvalue(&Rvalue::Ref(_, kind, ref place)) => {
+            ValueSource::Rvalue(&Rvalue::Ref(_, kind, _)) => {
                 // Getting `true` from `HasMutInterior::in_rvalue` means
                 // the borrowed place is disallowed from being borrowed,
                 // due to either a mutable borrow (with some exceptions),
                 // or an shared borrow of a value with interior mutability.
-                // Then `HasMutInterior` is replaced with `IsNotPromotable`,
+                // Then `HasMutInterior` is cleared
                 // to avoid duplicate errors (e.g. from reborrowing).
                 if qualifs[HasMutInterior] {
                     qualifs[HasMutInterior] = false;
-                    qualifs[IsNotPromotable] = true;
 
                     debug!("suppress_errors: {}", self.suppress_errors);
                     if self.mode.requires_const_checking() && !self.suppress_errors {
@@ -833,57 +624,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                             }
                         }
                     }
-                } else if let BorrowKind::Mut { .. } | BorrowKind::Shared = kind {
-                    // Don't promote BorrowKind::Shallow borrows, as they don't
-                    // reach codegen.
-                    // FIXME(eddyb) the two other kinds of borrow (`Shallow` and `Unique`)
-                    // aren't promoted here but *could* be promoted as part of a larger
-                    // value because `IsNotPromotable` isn't being set for them,
-                    // need to figure out what is the intended behavior.
-
-                    // We might have a candidate for promotion.
-                    let candidate = Candidate::Ref(location);
-                    // Start by traversing to the "base", with non-deref projections removed.
-                    let deref_proj =
-                        place.projection.iter().rev().find(|&elem| *elem == ProjectionElem::Deref);
-
-                    debug!(
-                        "qualify_consts: promotion candidate: place={:?} {:?}",
-                        place.base, deref_proj
-                    );
-                    // We can only promote interior borrows of promotable temps (non-temps
-                    // don't get promoted anyway).
-                    // (If we bailed out of the loop due to a `Deref` above, we will definitely
-                    // not enter the conditional here.)
-                    if let (PlaceBase::Local(local), None) = (&place.base, deref_proj) {
-                        if self.body.local_kind(*local) == LocalKind::Temp {
-                            debug!("qualify_consts: promotion candidate: local={:?}", local);
-                            // The borrowed place doesn't have `HasMutInterior`
-                            // (from `in_rvalue`), so we can safely ignore
-                            // `HasMutInterior` from the local's qualifications.
-                            // This allows borrowing fields which don't have
-                            // `HasMutInterior`, from a type that does, e.g.:
-                            // `let _: &'static _ = &(Cell::new(1), 2).1;`
-                            let mut local_qualifs = self.qualifs_in_local(*local);
-                            // Any qualifications, except HasMutInterior (see above), disqualify
-                            // from promotion.
-                            // This is, in particular, the "implicit promotion" version of
-                            // the check making sure that we don't run drop glue during const-eval.
-                            local_qualifs[HasMutInterior] = false;
-                            if !local_qualifs.0.iter().any(|&qualif| qualif) {
-                                debug!("qualify_consts: promotion candidate: {:?}", candidate);
-                                self.promotion_candidates.push(candidate);
-                            }
-                        }
-                    }
-                }
-            },
-            ValueSource::Rvalue(&Rvalue::Repeat(ref operand, _)) => {
-                debug!("assign: self.cx.mode={:?} self.def_id={:?} location={:?} operand={:?}",
-                       self.cx.mode, self.def_id, location, operand);
-                if self.should_promote_repeat_expression(operand) &&
-                        self.tcx.features().const_in_array_repeat_expressions {
-                    self.promotion_candidates.push(Candidate::Repeat(location));
                 }
             },
             _ => {},
@@ -939,18 +679,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                 per_local.insert(index);
             }
         }
-
-        // Ensure the `IsNotPromotable` qualification is preserved.
-        // NOTE(eddyb) this is actually unnecessary right now, as
-        // we never replace the local's qualif, but we might in
-        // the future, and so it serves to catch changes that unset
-        // important bits (in which case, asserting `contains` could
-        // be replaced with calling `insert` to re-set the bit).
-        if kind == LocalKind::Temp {
-            if !self.temp_promotion_state[index].is_promotable() {
-                assert!(self.cx.per_local[IsNotPromotable].contains(index));
-            }
-        }
     }
 
     /// Check a whole const, static initializer or const fn.
@@ -1047,115 +775,48 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
         // Collect all the temps we need to promote.
         let mut promoted_temps = BitSet::new_empty(self.temp_promotion_state.len());
 
-        // HACK(eddyb) don't try to validate promotion candidates if any
-        // parts of the control-flow graph were skipped due to an error.
-        let promotion_candidates = if has_controlflow_error {
-            let unleash_miri = self
-                .tcx
-                .sess
-                .opts
-                .debugging_opts
-                .unleash_the_miri_inside_of_you;
-            if !unleash_miri {
-                self.tcx.sess.delay_span_bug(
-                    body.span,
-                    "check_const: expected control-flow error(s)",
-                );
-            }
-            self.promotion_candidates.clone()
+        // HACK: if parts of the control-flow graph were skipped due to an error, don't try to
+        // promote anything, since that can cause errors in a `const` if e.g. rvalue static
+        // promotion is attempted within a loop body.
+        let unleash_miri = self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you;
+        let promotion_candidates = if has_controlflow_error && !unleash_miri {
+            self.tcx.sess.delay_span_bug(
+                body.span,
+                "check_const: expected control-flow error(s)",
+            );
+
+            vec![]
         } else {
-            self.valid_promotion_candidates()
+            promote_consts::validate_candidates(
+                self.tcx,
+                self.body,
+                self.def_id,
+                &self.temp_promotion_state,
+                &self.unchecked_promotion_candidates,
+            )
         };
+
         debug!("qualify_const: promotion_candidates={:?}", promotion_candidates);
         for candidate in promotion_candidates {
             match candidate {
-                Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => {
-                    if let StatementKind::Assign(box(_, Rvalue::Repeat(
-                        Operand::Move(place),
-                        _
-                    ))) = &self.body[bb].statements[stmt_idx].kind {
-                        if let Some(index) = place.as_local() {
-                            promoted_temps.insert(index);
-                        }
-                    }
-                }
                 Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
-                    if let StatementKind::Assign(
-                        box(
-                            _,
-                            Rvalue::Ref(_, _, place)
-                        )
-                    ) = &self.body[bb].statements[stmt_idx].kind {
-                        if let Some(index) = place.as_local() {
-                            promoted_temps.insert(index);
+                    if let StatementKind::Assign(box( _, Rvalue::Ref(_, _, place)))
+                        = &self.body[bb].statements[stmt_idx].kind
+                    {
+                        if let PlaceBase::Local(local) = place.base {
+                            promoted_temps.insert(local);
                         }
                     }
                 }
-                Candidate::Argument { .. } => {}
-            }
-        }
-
-        let mut qualifs = self.qualifs_in_local(RETURN_PLACE);
-
-        // Account for errors in consts by using the
-        // conservative type qualification instead.
-        if qualifs[IsNotPromotable] {
-            qualifs = self.qualifs_in_any_value_of_ty(body.return_ty());
-        }
 
-        (qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
-    }
-
-    /// Get the subset of `unchecked_promotion_candidates` that are eligible
-    /// for promotion.
-    // FIXME(eddyb) replace the old candidate gathering with this.
-    fn valid_promotion_candidates(&self) -> Vec<Candidate> {
-        // Sanity-check the promotion candidates.
-        let candidates = promote_consts::validate_candidates(
-            self.tcx,
-            self.body,
-            self.def_id,
-            &self.temp_promotion_state,
-            &self.unchecked_promotion_candidates,
-        );
-
-        if candidates != self.promotion_candidates {
-            let report = |msg, candidate| {
-                let span = match candidate {
-                    Candidate::Ref(loc) |
-                    Candidate::Repeat(loc) => self.body.source_info(loc).span,
-                    Candidate::Argument { bb, .. } => {
-                        self.body[bb].terminator().source_info.span
-                    }
-                };
-                self.tcx.sess.span_err(span, &format!("{}: {:?}", msg, candidate));
-            };
-
-            for &c in &self.promotion_candidates {
-                if !candidates.contains(&c) {
-                    report("invalidated old candidate", c);
-                }
-            }
-
-            for &c in &candidates {
-                if !self.promotion_candidates.contains(&c) {
-                    report("extra new candidate", c);
-                }
+                // Only rvalue-static promotion requires extending the lifetime of the promoted
+                // local.
+                Candidate::Argument { .. } | Candidate::Repeat(_) => {}
             }
-
-            bug!("promotion candidate validation mismatches (see above)");
         }
 
-        candidates
-    }
-
-    /// Returns `true` if the operand of a repeat expression is promotable.
-    fn should_promote_repeat_expression(&self, operand: &Operand<'tcx>) -> bool {
-        let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
-                             IsNotPromotable::in_operand(self, operand);
-        debug!("should_promote_repeat_expression: operand={:?} not_promotable={:?}",
-               operand, not_promotable);
-        !not_promotable
+        let qualifs = self.qualifs_in_local(RETURN_PLACE);
+        (qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
     }
 }
 
@@ -1468,11 +1129,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
             }
 
             let fn_ty = func.ty(self.body, self.tcx);
-            let mut callee_def_id = None;
-            let mut is_shuffle = false;
             match fn_ty.kind {
                 ty::FnDef(def_id, _) => {
-                    callee_def_id = Some(def_id);
                     match self.tcx.fn_sig(def_id).abi() {
                         Abi::RustIntrinsic |
                         Abi::PlatformIntrinsic => {
@@ -1496,10 +1154,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                                     }
                                 }
 
-                                name if name.starts_with("simd_shuffle") => {
-                                    is_shuffle = true;
-                                }
-
                                 // no need to check feature gates, intrinsics are only callable
                                 // from the libstd or with forever unstable feature gates
                                 _ => {}
@@ -1587,36 +1241,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                 }
             }
 
-            // No need to do anything in constants and statics, as everything is "constant" anyway
-            // so promotion would be useless.
-            if self.mode != Mode::Static && self.mode != Mode::Const {
-                let constant_args = callee_def_id.and_then(|id| {
-                    args_required_const(self.tcx, id)
-                }).unwrap_or_default();
-                for (i, arg) in args.iter().enumerate() {
-                    if !(is_shuffle && i == 2 || constant_args.contains(&i)) {
-                        continue;
-                    }
-
-                    let candidate = Candidate::Argument { bb: location.block, index: i };
-                    // Since the argument is required to be constant,
-                    // we care about constness, not promotability.
-                    // If we checked for promotability, we'd miss out on
-                    // the results of function calls (which are never promoted
-                    // in runtime code).
-                    // This is not a problem, because the argument explicitly
-                    // requests constness, in contrast to regular promotion
-                    // which happens even without the user requesting it.
-                    //
-                    // `promote_consts` is responsible for emitting the error if
-                    // the argument is not promotable.
-                    if !IsNotPromotable::in_operand(self, arg) {
-                        debug!("visit_terminator_kind: candidate={:?}", candidate);
-                        self.promotion_candidates.push(candidate);
-                    }
-                }
-            }
-
             // Check callee and argument operands.
             self.visit_operand(func, location);
             for arg in args {
@@ -1720,7 +1344,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 
 // FIXME(eddyb) this is only left around for the validation logic
 // in `promote_consts`, see the comment in `validate_operand`.
-pub(super) const QUALIF_ERROR_BIT: u8 = 1 << IsNotPromotable::IDX;
+pub(super) const QUALIF_ERROR_BIT: u8 = 1 << 2;
 
 fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
     // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
@@ -1768,39 +1392,42 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
 
         debug!("run_pass: mode={:?}", mode);
         if let Mode::NonConstFn | Mode::ConstFn = mode {
-            // This is ugly because Checker holds onto mir,
-            // which can't be mutated until its scope ends.
-            let (temps, candidates) = {
-                let mut checker = Checker::new(tcx, def_id, body, mode);
-                if let Mode::ConstFn = mode {
-                    let use_min_const_fn_checks =
-                        !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you &&
-                        tcx.is_min_const_fn(def_id);
-                    if use_min_const_fn_checks {
-                        // Enforce `min_const_fn` for stable `const fn`s.
-                        use super::qualify_min_const_fn::is_min_const_fn;
-                        if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
-                            error_min_const_fn_violation(tcx, span, err);
-                            return;
-                        }
-
-                        // `check_const` should not produce any errors, but better safe than sorry
-                        // FIXME(#53819)
-                        // NOTE(eddyb) `check_const` is actually needed for promotion inside
-                        // `min_const_fn` functions.
+            let mut checker = Checker::new(tcx, def_id, body, mode);
+            if let Mode::ConstFn = mode {
+                let use_min_const_fn_checks =
+                    !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you &&
+                    tcx.is_min_const_fn(def_id);
+                if use_min_const_fn_checks {
+                    // Enforce `min_const_fn` for stable `const fn`s.
+                    use super::qualify_min_const_fn::is_min_const_fn;
+                    if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
+                        error_min_const_fn_violation(tcx, span, err);
+                        return;
                     }
 
-                    // Enforce a constant-like CFG for `const fn`.
-                    checker.check_const();
-                } else {
-                    while let Some((bb, data)) = checker.rpo.next() {
-                        checker.visit_basic_block_data(bb, data);
-                    }
+                    // `check_const` should not produce any errors, but better safe than sorry
+                    // FIXME(#53819)
+                    // NOTE(eddyb) `check_const` is actually needed for promotion inside
+                    // `min_const_fn` functions.
                 }
 
-                let promotion_candidates = checker.valid_promotion_candidates();
-                (checker.temp_promotion_state, promotion_candidates)
-            };
+                // Enforce a constant-like CFG for `const fn`.
+                checker.check_const();
+            } else {
+                while let Some((bb, data)) = checker.rpo.next() {
+                    checker.visit_basic_block_data(bb, data);
+                }
+            }
+
+            // Promote only the promotable candidates.
+            let temps = checker.temp_promotion_state;
+            let candidates = promote_consts::validate_candidates(
+                tcx,
+                body,
+                def_id,
+                &temps,
+                &checker.unchecked_promotion_candidates,
+            );
 
             // Do the actual promotion, now that we know what's viable.
             self.promoted.set(
@@ -1921,19 +1548,6 @@ fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId)
     });
 }
 
-fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize>> {
-    let attrs = tcx.get_attrs(def_id);
-    let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;
-    let mut ret = FxHashSet::default();
-    for meta in attr.meta_item_list()? {
-        match meta.literal()?.kind {
-            LitKind::Int(a, _) => { ret.insert(a as usize); }
-            _ => return None,
-        }
-    }
-    Some(ret)
-}
-
 fn validator_mismatch(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 4577b6e1e07..4cf2a5f3584 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -253,7 +253,7 @@ impl<'a> AstValidator<'a> {
                 let arr = [sym::allow, sym::cfg, sym::cfg_attr, sym::deny, sym::forbid, sym::warn];
                 !arr.contains(&attr.name_or_empty()) && is_builtin_attr(attr)
             })
-            .for_each(|attr| if attr.is_sugared_doc {
+            .for_each(|attr| if attr.is_doc_comment() {
                 let mut err = self.err_handler().struct_span_err(
                     attr.span,
                     "documentation comments cannot be applied to function parameters"
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index f2aef2c12c7..2aeec029cc3 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -569,8 +569,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         if self.should_warn_about_item(item) {
-            // For items that have a definition with a signature followed by a
-            // block, point only at the signature.
+            // For most items, we want to highlight its identifier
             let span = match item.kind {
                 hir::ItemKind::Fn(..) |
                 hir::ItemKind::Mod(..) |
@@ -578,7 +577,19 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
                 hir::ItemKind::Struct(..) |
                 hir::ItemKind::Union(..) |
                 hir::ItemKind::Trait(..) |
-                hir::ItemKind::Impl(..) => self.tcx.sess.source_map().def_span(item.span),
+                hir::ItemKind::Impl(..) => {
+                    // FIXME(66095): Because item.span is annotated with things
+                    // like expansion data, and ident.span isn't, we use the
+                    // def_span method if it's part of a macro invocation
+                    // (and thus has asource_callee set).
+                    // We should probably annotate ident.span with the macro
+                    // context, but that's a larger change.
+                    if item.span.source_callee().is_some() {
+                        self.tcx.sess.source_map().def_span(item.span)
+                    } else {
+                        item.ident.span
+                    }
+                },
                 _ => item.span,
             };
             let participle = match item.kind {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 648c5104b1a..4239518b879 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -33,7 +33,7 @@ use syntax::attr;
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
 use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind};
 use syntax::feature_gate::is_builtin_attr;
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::print::pprust;
 use syntax::{span_err, struct_span_err};
 use syntax::source_map::{respan, Spanned};
@@ -1229,8 +1229,10 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
     }
 
     fn visit_attribute(&mut self, attr: &'b ast::Attribute) {
-        if !attr.is_sugared_doc && is_builtin_attr(attr) {
-            self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope));
+        if !attr.is_doc_comment() && is_builtin_attr(attr) {
+            self.r.builtin_attrs.push(
+                (attr.get_normal_item().path.segments[0].ident, self.parent_scope)
+            );
         }
         visit::walk_attribute(self, attr);
     }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 0fbd6b0e5d3..3d5a7f26eda 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -179,7 +179,10 @@ impl<'a> base::Resolver for Resolver<'a> {
 
         let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
-                (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive),
+                (&attr.get_normal_item().path,
+                 MacroKind::Attr,
+                 self.arenas.alloc_ast_paths(derives),
+                 after_derive),
             InvocationKind::Bang { ref mac, .. } =>
                 (&mac.path, MacroKind::Bang, &[][..], false),
             InvocationKind::Derive { ref path, .. } =>
diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml
index b89c83d630b..2d93585e50e 100644
--- a/src/librustc_save_analysis/Cargo.toml
+++ b/src/librustc_save_analysis/Cargo.toml
@@ -13,7 +13,6 @@ log = "0.4"
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_codegen_utils = { path = "../librustc_codegen_utils" }
-rustc_target = { path = "../librustc_target" }
 serde_json = "1"
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index a372106d379..5c5fbcc07de 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -24,7 +24,7 @@ use std::path::Path;
 use std::env;
 
 use syntax::ast::{self, Attribute, NodeId, PatKind};
-use syntax::parse::token;
+use syntax::token;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{
     bounds_to_string,
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 1cfb84bb511..a2f8837c581 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -29,7 +29,7 @@ use std::path::{Path, PathBuf};
 
 use syntax::ast::{self, Attribute, DUMMY_NODE_ID, NodeId, PatKind};
 use syntax::source_map::Spanned;
-use syntax::parse::lexer::comments::strip_doc_comment_decoration;
+use syntax::util::comments::strip_doc_comment_decoration;
 use syntax::print::pprust;
 use syntax::visit::{self, Visitor};
 use syntax::print::pprust::{param_to_string, ty_to_string};
@@ -885,7 +885,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
         for attr in attrs {
             if attr.check_name(sym::doc) {
                 if let Some(val) = attr.value_str() {
-                    if attr.is_sugared_doc {
+                    if attr.is_doc_comment() {
                         result.push_str(&strip_doc_comment_decoration(&val.as_str()));
                     } else {
                         result.push_str(&val.as_str());
@@ -1195,7 +1195,7 @@ fn null_id() -> rls_data::Id {
 fn lower_attributes(attrs: Vec<Attribute>, scx: &SaveContext<'_, '_>) -> Vec<rls_data::Attribute> {
     attrs.into_iter()
     // Only retain real attributes. Doc comments are lowered separately.
-    .filter(|attr| attr.path != sym::doc)
+    .filter(|attr| !attr.has_name(sym::doc))
     .map(|mut attr| {
         // Remove the surrounding '#[..]' or '#![..]' of the pretty printed
         // attribute. First normalize all inner attribute (#![..]) to outer
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 203bd4d4167..019e92717b5 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -32,7 +32,7 @@ use rls_data::{SigElement, Signature};
 use rustc::hir::def::{Res, DefKind};
 use syntax::ast::{self, NodeId};
 use syntax::print::pprust;
-
+use syntax_pos::sym;
 
 pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option<Signature> {
     if !scx.config.signatures {
@@ -157,6 +157,12 @@ fn text_sig(text: String) -> Signature {
     }
 }
 
+fn push_abi(text: &mut String, abi: ast::Abi) {
+    if abi.symbol != sym::Rust {
+        text.push_str(&format!("extern \"{}\" ", abi.symbol));
+    }
+}
+
 impl Sig for ast::Ty {
     fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
         let id = Some(self.id);
@@ -231,11 +237,7 @@ impl Sig for ast::Ty {
                 if f.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                if f.abi != rustc_target::spec::abi::Abi::Rust {
-                    text.push_str("extern");
-                    text.push_str(&f.abi.to_string());
-                    text.push(' ');
-                }
+                push_abi(&mut text, f.abi);
                 text.push_str("fn(");
 
                 let mut defs = vec![];
@@ -385,11 +387,7 @@ impl Sig for ast::Item {
                 if header.unsafety == ast::Unsafety::Unsafe {
                     text.push_str("unsafe ");
                 }
-                if header.abi != rustc_target::spec::abi::Abi::Rust {
-                    text.push_str("extern");
-                    text.push_str(&header.abi.to_string());
-                    text.push(' ');
-                }
+                push_abi(&mut text, header.abi);
                 text.push_str("fn ");
 
                 let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
@@ -948,11 +946,7 @@ fn make_method_signature(
     if m.header.unsafety == ast::Unsafety::Unsafe {
         text.push_str("unsafe ");
     }
-    if m.header.abi != rustc_target::spec::abi::Abi::Rust {
-        text.push_str("extern");
-        text.push_str(&m.header.abi.to_string());
-        text.push(' ');
-    }
+    push_abi(&mut text, m.header.abi);
     text.push_str("fn ");
 
     let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?;
diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs
index fb9919d777d..4d0780cf94d 100644
--- a/src/librustc_save_analysis/span_utils.rs
+++ b/src/librustc_save_analysis/span_utils.rs
@@ -3,7 +3,7 @@ use rustc::session::Session;
 use crate::generated_code;
 
 use syntax::parse::lexer::{self, StringReader};
-use syntax::parse::token::{self, TokenKind};
+use syntax::token::{self, TokenKind};
 use syntax_pos::*;
 
 #[derive(Clone)]
diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs
index db34d366212..18b121f9c5b 100644
--- a/src/librustc_target/abi/call/mips64.rs
+++ b/src/librustc_target/abi/call/mips64.rs
@@ -23,8 +23,8 @@ fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option<Reg>
 {
     match ret.layout.field(cx, i).abi {
         abi::Abi::Scalar(ref scalar) => match scalar.value {
-            abi::Float(abi::FloatTy::F32) => Some(Reg::f32()),
-            abi::Float(abi::FloatTy::F64) => Some(Reg::f64()),
+            abi::F32 => Some(Reg::f32()),
+            abi::F64 => Some(Reg::f64()),
             _ => None
         },
         _ => None
@@ -107,7 +107,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
 
                 // We only care about aligned doubles
                 if let abi::Abi::Scalar(ref scalar) = field.abi {
-                    if let abi::Float(abi::FloatTy::F64) = scalar.value {
+                    if let abi::F64 = scalar.value {
                         if offset.is_aligned(dl.f64_align.abi) {
                             // Insert enough integers to cover [last_offset, offset)
                             assert!(last_offset.is_aligned(dl.f64_align.abi));
diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs
index 396b9620038..6029b00aa31 100644
--- a/src/librustc_target/abi/call/mod.rs
+++ b/src/librustc_target/abi/call/mod.rs
@@ -287,7 +287,7 @@ impl<'a, Ty> TyLayout<'a, Ty> {
                 let kind = match scalar.value {
                     abi::Int(..) |
                     abi::Pointer => RegKind::Integer,
-                    abi::Float(_) => RegKind::Float,
+                    abi::F32 | abi::F64 => RegKind::Float,
                 };
                 HomogeneousAggregate::Homogeneous(Reg {
                     kind,
diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs
index 96fd077ec00..452ca024e61 100644
--- a/src/librustc_target/abi/call/x86_64.rs
+++ b/src/librustc_target/abi/call/x86_64.rs
@@ -45,7 +45,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &ArgAbi<'a, Ty>)
                 match scalar.value {
                     abi::Int(..) |
                     abi::Pointer => Class::Int,
-                    abi::Float(_) => Class::Sse
+                    abi::F32 | abi::F64 => Class::Sse
                 }
             }
 
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index fde5c5bed4d..a19bb6807f1 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -3,11 +3,9 @@ pub use Primitive::*;
 
 use crate::spec::Target;
 
-use std::fmt;
 use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive};
 
 use rustc_index::vec::{Idx, IndexVec};
-use syntax_pos::symbol::{sym, Symbol};
 use syntax_pos::Span;
 
 pub mod call;
@@ -534,49 +532,6 @@ impl Integer {
     }
 }
 
-
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy,
-         PartialOrd, Ord)]
-pub enum FloatTy {
-    F32,
-    F64,
-}
-
-impl fmt::Debug for FloatTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Display for FloatTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ty_to_string())
-    }
-}
-
-impl FloatTy {
-    pub fn ty_to_string(self) -> &'static str {
-        match self {
-            FloatTy::F32 => "f32",
-            FloatTy::F64 => "f64",
-        }
-    }
-
-    pub fn to_symbol(self) -> Symbol {
-        match self {
-            FloatTy::F32 => sym::f32,
-            FloatTy::F64 => sym::f64,
-        }
-    }
-
-    pub fn bit_width(self) -> usize {
-        match self {
-            FloatTy::F32 => 32,
-            FloatTy::F64 => 64,
-        }
-    }
-}
-
 /// Fundamental unit of memory access and layout.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum Primitive {
@@ -588,7 +543,8 @@ pub enum Primitive {
     /// a negative integer passed by zero-extension will appear positive in
     /// the callee, and most operations on it will produce the wrong values.
     Int(Integer, bool),
-    Float(FloatTy),
+    F32,
+    F64,
     Pointer
 }
 
@@ -598,8 +554,8 @@ impl Primitive {
 
         match self {
             Int(i, _) => i.size(),
-            Float(FloatTy::F32) => Size::from_bits(32),
-            Float(FloatTy::F64) => Size::from_bits(64),
+            F32 => Size::from_bits(32),
+            F64 => Size::from_bits(64),
             Pointer => dl.pointer_size
         }
     }
@@ -609,15 +565,15 @@ impl Primitive {
 
         match self {
             Int(i, _) => i.align(dl),
-            Float(FloatTy::F32) => dl.f32_align,
-            Float(FloatTy::F64) => dl.f64_align,
+            F32 => dl.f32_align,
+            F64 => dl.f64_align,
             Pointer => dl.pointer_align
         }
     }
 
     pub fn is_float(self) -> bool {
         match self {
-            Float(_) => true,
+            F32 | F64 => true,
             _ => false
         }
     }
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 9cbde276ae9..ded655c1ae3 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -341,10 +341,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                                          tstr);
         match self.expr_ty.kind {
             ty::Ref(_, _, mt) => {
-                let mtstr = match mt {
-                    hir::MutMutable => "mut ",
-                    hir::MutImmutable => "",
-                };
+                let mtstr = mt.prefix_str();
                 if self.cast_ty.is_trait() {
                     match fcx.tcx.sess.source_map().span_to_snippet(self.cast_span) {
                         Ok(s) => {
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 35870abbaef..bc1189e443e 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -592,20 +592,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             cause.span,
                             target_id,
                         );
-                        let val = match ty.kind {
-                            ty::Bool => "true",
-                            ty::Char => "'a'",
-                            ty::Int(_) | ty::Uint(_) => "42",
-                            ty::Float(_) => "3.14159",
-                            ty::Error | ty::Never => return,
-                            _ => "value",
-                        };
-                        let msg = "give it a value of the expected type";
-                        let label = destination.label
-                            .map(|l| format!(" {}", l.ident))
-                            .unwrap_or_else(String::new);
-                        let sugg = format!("break{} {}", label, val);
-                        err.span_suggestion(expr.span, msg, sugg, Applicability::HasPlaceholders);
+                        if let Some(val) = ty_kind_suggestion(ty) {
+                            let label = destination.label
+                                .map(|l| format!(" {}", l.ident))
+                                .unwrap_or_else(String::new);
+                            err.span_suggestion(
+                                expr.span,
+                                "give it a value of the expected type",
+                                format!("break{} {}", label, val),
+                                Applicability::HasPlaceholders,
+                            );
+                        }
                     }, false);
                 }
             } else {
@@ -1725,3 +1722,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.tcx.mk_unit()
     }
 }
+
+pub(super) fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
+    Some(match ty.kind {
+        ty::Bool => "true",
+        ty::Char => "'a'",
+        ty::Int(_) | ty::Uint(_) => "42",
+        ty::Float(_) => "3.14159",
+        ty::Error | ty::Never => return None,
+        _ => "value",
+    })
+}
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 33dc85fc68a..693f6f05fab 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -67,11 +67,13 @@ fn equate_intrinsic_type<'tcx>(
 pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
     match intrinsic {
         "size_of" | "min_align_of" | "needs_drop" | "caller_location" |
+        "size_of_val" | "min_align_of_val" |
         "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
         "wrapping_add" | "wrapping_sub" | "wrapping_mul" |
         "saturating_add" | "saturating_sub" |
         "rotate_left" | "rotate_right" |
         "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" |
+        "discriminant_value" | "type_id" | "likely" | "unlikely" |
         "minnumf32" | "minnumf64" | "maxnumf32" | "maxnumf64" | "type_name"
         => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 26f04081046..fe2c7a200d2 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -127,7 +127,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::source_map::{DUMMY_SP, original_sp};
-use syntax::symbol::{kw, sym};
+use syntax::symbol::{kw, sym, Ident};
 use syntax::util::parser::ExprPrecedence;
 
 use std::cell::{Cell, RefCell, Ref, RefMut};
@@ -1800,12 +1800,12 @@ fn check_specialization_validity<'tcx>(
 
 fn check_impl_items_against_trait<'tcx>(
     tcx: TyCtxt<'tcx>,
-    impl_span: Span,
+    full_impl_span: Span,
     impl_id: DefId,
     impl_trait_ref: ty::TraitRef<'tcx>,
     impl_item_refs: &[hir::ImplItemRef],
 ) {
-    let impl_span = tcx.sess.source_map().def_span(impl_span);
+    let impl_span = tcx.sess.source_map().def_span(full_impl_span);
 
     // If the trait reference itself is erroneous (so the compilation is going
     // to fail), skip checking the items here -- the `impl_item` table in `tcx`
@@ -1925,35 +1925,132 @@ fn check_impl_items_against_trait<'tcx>(
     }
 
     if !missing_items.is_empty() {
-        let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
-            "not all trait items implemented, missing: `{}`",
-            missing_items.iter()
-                .map(|trait_item| trait_item.ident.to_string())
-                .collect::<Vec<_>>().join("`, `"));
-        err.span_label(impl_span, format!("missing `{}` in implementation",
-                missing_items.iter()
-                    .map(|trait_item| trait_item.ident.to_string())
-                    .collect::<Vec<_>>().join("`, `")));
-        for trait_item in missing_items {
-            if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
-                err.span_label(span, format!("`{}` from trait", trait_item.ident));
-            } else {
-                err.note_trait_signature(trait_item.ident.to_string(),
-                                         trait_item.signature(tcx));
-            }
-        }
-        err.emit();
+        missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
     }
 
     if !invalidated_items.is_empty() {
         let invalidator = overridden_associated_type.unwrap();
-        span_err!(tcx.sess, invalidator.span, E0399,
-                  "the following trait items need to be reimplemented \
-                   as `{}` was overridden: `{}`",
-                  invalidator.ident,
-                  invalidated_items.iter()
-                                   .map(|name| name.to_string())
-                                   .collect::<Vec<_>>().join("`, `"))
+        span_err!(
+            tcx.sess,
+            invalidator.span,
+            E0399,
+            "the following trait items need to be reimplemented as `{}` was overridden: `{}`",
+            invalidator.ident,
+            invalidated_items.iter()
+                .map(|name| name.to_string())
+                .collect::<Vec<_>>().join("`, `")
+        )
+    }
+}
+
+fn missing_items_err(
+    tcx: TyCtxt<'_>,
+    impl_span: Span,
+    missing_items: &[ty::AssocItem],
+    full_impl_span: Span,
+) {
+    let missing_items_msg = missing_items.iter()
+        .map(|trait_item| trait_item.ident.to_string())
+        .collect::<Vec<_>>().join("`, `");
+
+    let mut err = struct_span_err!(
+        tcx.sess,
+        impl_span,
+        E0046,
+        "not all trait items implemented, missing: `{}`",
+        missing_items_msg
+    );
+    err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
+
+    // `Span` before impl block closing brace.
+    let hi = full_impl_span.hi() - BytePos(1);
+    // Point at the place right before the closing brace of the relevant `impl` to suggest
+    // adding the associated item at the end of its body.
+    let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
+    // Obtain the level of indentation ending in `sugg_sp`.
+    let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
+    // Make the whitespace that will make the suggestion have the right indentation.
+    let padding: String = (0..indentation).map(|_| " ").collect();
+
+    for trait_item in missing_items {
+        let snippet = suggestion_signature(&trait_item, tcx);
+        let code = format!("{}{}\n{}", padding, snippet, padding);
+        let msg = format!("implement the missing item: `{}`", snippet);
+        let appl = Applicability::HasPlaceholders;
+        if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
+            err.span_label(span, format!("`{}` from trait", trait_item.ident));
+            err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
+        } else {
+            err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
+        }
+    }
+    err.emit();
+}
+
+/// Return placeholder code for the given function.
+fn fn_sig_suggestion(sig: &ty::FnSig<'_>, ident: Ident) -> String {
+    let args = sig.inputs()
+        .iter()
+        .map(|ty| Some(match ty.kind {
+            ty::Param(param) if param.name == kw::SelfUpper => "self".to_string(),
+            ty::Ref(reg, ref_ty, mutability) => {
+                let reg = match &format!("{}", reg)[..] {
+                    "'_" | "" => String::new(),
+                    reg => format!("{} ", reg),
+                };
+                match ref_ty.kind {
+                    ty::Param(param) if param.name == kw::SelfUpper => {
+                        format!("&{}{}self", reg, mutability.prefix_str())
+                    }
+                    _ => format!("_: {:?}", ty),
+                }
+            }
+            _ => format!("_: {:?}", ty),
+        }))
+        .chain(std::iter::once(if sig.c_variadic {
+            Some("...".to_string())
+        } else {
+            None
+        }))
+        .filter_map(|arg| arg)
+        .collect::<Vec<String>>()
+        .join(", ");
+    let output = sig.output();
+    let output = if !output.is_unit() {
+        format!(" -> {:?}", output)
+    } else {
+        String::new()
+    };
+
+    let unsafety = sig.unsafety.prefix_str();
+    // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
+    // not be present in the `fn` definition, not will we account for renamed
+    // lifetimes between the `impl` and the `trait`, but this should be good enough to
+    // fill in a significant portion of the missing code, and other subsequent
+    // suggestions can help the user fix the code.
+    format!("{}fn {}({}){} {{ unimplemented!() }}", unsafety, ident, args, output)
+}
+
+/// Return placeholder code for the given associated item.
+/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
+/// structured suggestion.
+fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
+    match assoc.kind {
+        ty::AssocKind::Method => {
+            // We skip the binder here because the binder would deanonymize all
+            // late-bound regions, and we don't want method signatures to show up
+            // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
+            // regions just fine, showing `fn(&MyType)`.
+            fn_sig_suggestion(tcx.fn_sig(assoc.def_id).skip_binder(), assoc.ident)
+        }
+        ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
+        // FIXME(type_alias_impl_trait): we should print bounds here too.
+        ty::AssocKind::OpaqueTy => format!("type {} = Type;", assoc.ident),
+        ty::AssocKind::Const => {
+            let ty = tcx.type_of(assoc.def_id);
+            let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
+            format!("const {}: {:?} = {};", assoc.ident, ty, val)
+        }
     }
 }
 
@@ -3660,8 +3757,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 });
                 opt_ty.unwrap_or_else(|| self.next_int_var())
             }
-            ast::LitKind::Float(_, t) => tcx.mk_mach_float(t),
-            ast::LitKind::FloatUnsuffixed(_) => {
+            ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => tcx.mk_mach_float(t),
+            ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
                 let opt_ty = expected.to_option(self).and_then(|ty| {
                     match ty.kind {
                         ty::Float(_) => Some(ty),
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index ffe034759a8..ef84f1cb20f 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1146,10 +1146,6 @@ fn report_assoc_ty_on_inherent_impl(tcx: TyCtxt<'_>, span: Span) {
     );
 }
 
-fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
-    checked_type_of(tcx, def_id, true).unwrap()
-}
-
 fn infer_placeholder_type(
     tcx: TyCtxt<'_>,
     def_id: DefId,
@@ -1193,26 +1189,14 @@ fn infer_placeholder_type(
     ty
 }
 
-/// Same as [`type_of`] but returns [`Option`] instead of failing.
-///
-/// If you want to fail anyway, you can set the `fail` parameter to true, but in this case,
-/// you'd better just call [`type_of`] directly.
-pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<'_>> {
+fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     use rustc::hir::*;
 
-    let hir_id = match tcx.hir().as_local_hir_id(def_id) {
-        Some(hir_id) => hir_id,
-        None => {
-            if !fail {
-                return None;
-            }
-            bug!("invalid node");
-        }
-    };
+    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
 
     let icx = ItemCtxt::new(tcx, def_id);
 
-    Some(match tcx.hir().get(hir_id) {
+    match tcx.hir().get(hir_id) {
         Node::TraitItem(item) => match item.kind {
             TraitItemKind::Method(..) => {
                 let substs = InternalSubsts::identity_for_item(tcx, def_id);
@@ -1229,9 +1213,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
             },
             TraitItemKind::Type(_, Some(ref ty)) => icx.to_ty(ty),
             TraitItemKind::Type(_, None) => {
-                if !fail {
-                    return None;
-                }
                 span_bug!(item.span, "associated type missing default");
             }
         },
@@ -1325,9 +1306,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                 | ItemKind::GlobalAsm(..)
                 | ItemKind::ExternCrate(..)
                 | ItemKind::Use(..) => {
-                    if !fail {
-                        return None;
-                    }
                     span_bug!(
                         item.span,
                         "compute_type_of_item: unexpected item type: {:?}",
@@ -1365,7 +1343,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
             ..
         }) => {
             if gen.is_some() {
-                return Some(tcx.typeck_tables_of(def_id).node_type(hir_id));
+                return tcx.typeck_tables_of(def_id).node_type(hir_id);
             }
 
             let substs = InternalSubsts::identity_for_item(tcx, def_id);
@@ -1440,13 +1418,9 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                     .map(|(index, _)| index)
                                     .next()
                             })
-                            .or_else(|| {
-                                if !fail {
-                                    None
-                                } else {
-                                    bug!("no arg matching AnonConst in path")
-                                }
-                            })?;
+                            .unwrap_or_else(|| {
+                                bug!("no arg matching AnonConst in path");
+                            });
 
                         // We've encountered an `AnonConst` in some path, so we need to
                         // figure out which generic parameter it corresponds to and return
@@ -1456,8 +1430,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                 tcx.generics_of(tcx.parent(def_id).unwrap())
                             }
                             Res::Def(_, def_id) => tcx.generics_of(def_id),
-                            Res::Err => return Some(tcx.types.err),
-                            _ if !fail => return None,
+                            Res::Err => return tcx.types.err,
                             res => {
                                 tcx.sess.delay_span_bug(
                                     DUMMY_SP,
@@ -1466,7 +1439,7 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                         res,
                                     ),
                                 );
-                                return Some(tcx.types.err);
+                                return tcx.types.err;
                             }
                         };
 
@@ -1484,9 +1457,6 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                             // probably from an extra arg where one is not needed.
                             .unwrap_or(tcx.types.err)
                     } else {
-                        if !fail {
-                            return None;
-                        }
                         tcx.sess.delay_span_bug(
                             DUMMY_SP,
                             &format!(
@@ -1494,14 +1464,11 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                                 parent_node,
                             ),
                         );
-                        return Some(tcx.types.err);
+                        return tcx.types.err;
                     }
                 }
 
                 x => {
-                    if !fail {
-                        return None;
-                    }
                     tcx.sess.delay_span_bug(
                         DUMMY_SP,
                         &format!(
@@ -1551,21 +1518,13 @@ pub fn checked_type_of(tcx: TyCtxt<'_>, def_id: DefId, fail: bool) -> Option<Ty<
                 }
                 ty
             }
-            x => {
-                if !fail {
-                    return None;
-                }
-                bug!("unexpected non-type Node::GenericParam: {:?}", x)
-            },
+            x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
         },
 
         x => {
-            if !fail {
-                return None;
-            }
             bug!("unexpected sort of node in type_of_def_id(): {:?}", x);
         }
-    })
+    }
 }
 
 fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
@@ -2075,10 +2034,7 @@ fn explicit_predicates_of(
         }
     }
 
-    let hir_id = match tcx.hir().as_local_hir_id(def_id) {
-        Some(hir_id) => hir_id,
-        None => return tcx.predicates_of(def_id),
-    };
+    let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let node = tcx.hir().get(hir_id);
 
     let mut is_trait = None;
@@ -2706,7 +2662,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
     }
 
     codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
-        if attr.path != sym::inline {
+        if !attr.has_name(sym::inline) {
             return ia;
         }
         match attr.meta().map(|i| i.kind) {
@@ -2746,7 +2702,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
     });
 
     codegen_fn_attrs.optimize = attrs.iter().fold(OptimizeAttr::None, |ia, attr| {
-        if attr.path != sym::optimize {
+        if !attr.has_name(sym::optimize) {
             return ia;
         }
         let err = |sp, s| span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s);
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9374113e1c9..a5a4cfa2bab 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -109,8 +109,6 @@ use util::common::time;
 use std::iter;
 
 use astconv::{AstConv, Bounds};
-pub use collect::checked_type_of;
-
 pub struct TypeAndSubsts<'tcx> {
     substs: SubstsRef<'tcx>,
     ty: Ty<'tcx>,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e7f76155252..f6cac8ca48d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -26,9 +26,9 @@ use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
 use rustc::ty::fold::TypeFolder;
 use rustc::ty::layout::VariantIdx;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
-use syntax::ast::{self, Attribute, AttrStyle, AttrItem, Ident};
+use syntax::ast::{self, Attribute, AttrStyle, AttrKind, Ident};
 use syntax::attr;
-use syntax::parse::lexer::comments;
+use syntax::util::comments;
 use syntax::source_map::DUMMY_SP;
 use syntax_pos::symbol::{Symbol, kw, sym};
 use syntax_pos::hygiene::MacroKind;
@@ -859,31 +859,32 @@ impl Attributes {
         let mut cfg = Cfg::True;
         let mut doc_line = 0;
 
-        /// Converts `attr` to a normal `#[doc="foo"]` comment, if it is a
-        /// comment like `///` or `/** */`. (Returns `attr` unchanged for
-        /// non-sugared doc attributes.)
-        pub fn with_desugared_doc<T>(attr: &Attribute, f: impl FnOnce(&Attribute) -> T) -> T {
-            if attr.is_sugared_doc {
-                let comment = attr.value_str().unwrap();
-                let meta = attr::mk_name_value_item_str(
-                    Ident::with_dummy_span(sym::doc),
-                    Symbol::intern(&comments::strip_doc_comment_decoration(&comment.as_str())),
-                    DUMMY_SP,
-                );
-                f(&Attribute {
-                    item: AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) },
-                    id: attr.id,
-                    style: attr.style,
-                    is_sugared_doc: true,
-                    span: attr.span,
-                })
-            } else {
-                f(attr)
+        /// If `attr` is a doc comment, strips the leading and (if present)
+        /// trailing comments symbols, e.g. `///`, `/**`, and `*/`. Otherwise,
+        /// returns `attr` unchanged.
+        pub fn with_doc_comment_markers_stripped<T>(
+            attr: &Attribute,
+            f: impl FnOnce(&Attribute) -> T
+        ) -> T {
+            match attr.kind {
+                AttrKind::Normal(_) => {
+                    f(attr)
+                }
+                AttrKind::DocComment(comment) => {
+                    let comment =
+                        Symbol::intern(&comments::strip_doc_comment_decoration(&comment.as_str()));
+                    f(&Attribute {
+                        kind: AttrKind::DocComment(comment),
+                        id: attr.id,
+                        style: attr.style,
+                        span: attr.span,
+                    })
+                }
             }
         }
 
         let other_attrs = attrs.iter().filter_map(|attr| {
-            with_desugared_doc(attr, |attr| {
+            with_doc_comment_markers_stripped(attr, |attr| {
                 if attr.check_name(sym::doc) {
                     if let Some(mi) = attr.meta() {
                         if let Some(value) = mi.value_str() {
@@ -892,7 +893,7 @@ impl Attributes {
                             let line = doc_line;
                             doc_line += value.lines().count();
 
-                            if attr.is_sugared_doc {
+                            if attr.is_doc_comment() {
                                 doc_strings.push(DocFragment::SugaredDoc(line, attr.span, value));
                             } else {
                                 doc_strings.push(DocFragment::RawDoc(line, attr.span, value));
@@ -1491,12 +1492,13 @@ impl GenericParamDefKind {
         }
     }
 
-    pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> {
-        match *self {
-            GenericParamDefKind::Type { did, .. } => {
-                rustc_typeck::checked_type_of(cx.tcx, did, false).map(|t| t.clean(cx))
-            }
-            GenericParamDefKind::Const { ref ty, .. } => Some(ty.clone()),
+    // FIXME(eddyb) this either returns the default of a type parameter, or the
+    // type of a `const` parameter. It seems that the intention is to *visit*
+    // any embedded types, but `get_type` seems to be the wrong name for that.
+    pub fn get_type(&self) -> Option<Type> {
+        match self {
+            GenericParamDefKind::Type { default, .. } => default.clone(),
+            GenericParamDefKind::Const { ty, .. } => Some(ty.clone()),
             GenericParamDefKind::Lifetime => None,
         }
     }
@@ -1522,8 +1524,8 @@ impl GenericParamDef {
         self.kind.is_type()
     }
 
-    pub fn get_type(&self, cx: &DocContext<'_>) -> Option<Type> {
-        self.kind.get_type(cx)
+    pub fn get_type(&self) -> Option<Type> {
+        self.kind.get_type()
     }
 
     pub fn get_bounds(&self) -> Option<&[GenericBound]> {
@@ -1891,7 +1893,7 @@ fn get_real_types(
                             if !x.is_type() {
                                 continue
                             }
-                            if let Some(ty) = x.get_type(cx) {
+                            if let Some(ty) = x.get_type() {
                                 let adds = get_real_types(generics, &ty, cx, recurse + 1);
                                 if !adds.is_empty() {
                                     res.extend(adds);
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 0b8d4d6c302..255d5f9f35d 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -615,10 +615,6 @@ fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
         let mut parts = arg.splitn(2, '=');
         let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
         let location = parts.next().map(|s| s.to_string());
-        if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
-            return Err("the `-Z unstable-options` flag must also be passed to \
-                        enable `--extern crate_name` without `=path`".to_string());
-        }
         let name = name.to_string();
         // For Rustdoc purposes, we can treat all externs as public
         externs.entry(name)
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 88ba13f2796..4bd72f7e61c 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -13,7 +13,7 @@ use std::io::prelude::*;
 
 use syntax::source_map::SourceMap;
 use syntax::parse::lexer;
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym};
 use syntax_pos::{Span, FileName};
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 29f0b99d8ee..9a87bcc10db 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1230,18 +1230,87 @@ impl AllTypes {
     }
 }
 
+#[derive(Debug)]
+enum Setting {
+    Section {
+        description: &'static str,
+        sub_settings: Vec<Setting>,
+    },
+    Entry {
+        js_data_name: &'static str,
+        description: &'static str,
+        default_value: bool,
+    }
+}
+
+impl Setting {
+    fn display(&self) -> String {
+        match *self {
+            Setting::Section { ref description, ref sub_settings } => {
+                format!(
+                    "<div class='setting-line'>\
+                        <div class='title'>{}</div>\
+                        <div class='sub-settings'>{}</div>
+                    </div>",
+                    description,
+                    sub_settings.iter().map(|s| s.display()).collect::<String>()
+                )
+            }
+            Setting::Entry { ref js_data_name, ref description, ref default_value } => {
+                format!(
+                    "<div class='setting-line'>\
+                        <label class='toggle'>\
+                        <input type='checkbox' id='{}' {}>\
+                        <span class='slider'></span>\
+                        </label>\
+                        <div>{}</div>\
+                    </div>",
+                    js_data_name,
+                    if *default_value { " checked" } else { "" },
+                    description,
+                )
+            }
+        }
+    }
+}
+
+impl From<(&'static str, &'static str, bool)> for Setting {
+    fn from(values: (&'static str, &'static str, bool)) -> Setting {
+        Setting::Entry {
+            js_data_name: values.0,
+            description: values.1,
+            default_value: values.2,
+        }
+    }
+}
+
+impl<T: Into<Setting>> From<(&'static str, Vec<T>)> for Setting {
+    fn from(values: (&'static str, Vec<T>)) -> Setting {
+        Setting::Section {
+            description: values.0,
+            sub_settings: values.1.into_iter().map(|v| v.into()).collect::<Vec<_>>(),
+        }
+    }
+}
+
 fn settings(root_path: &str, suffix: &str) -> String {
     // (id, explanation, default value)
-    let settings = [
-        ("item-declarations", "Auto-hide item declarations.", true),
-        ("item-attributes", "Auto-hide item attributes.", true),
-        ("trait-implementations", "Auto-hide trait implementations documentation",
-            true),
-        ("method-docs", "Auto-hide item methods' documentation", false),
+    let settings: &[Setting] = &[
+        ("Auto-hide item declarations", vec![
+            ("auto-hide-struct", "Auto-hide structs declaration", true),
+            ("auto-hide-enum", "Auto-hide enums declaration", false),
+            ("auto-hide-union", "Auto-hide unions declaration", true),
+            ("auto-hide-trait", "Auto-hide traits declaration", true),
+            ("auto-hide-macro", "Auto-hide macros declaration", false),
+        ]).into(),
+        ("auto-hide-attributes", "Auto-hide item attributes.", true).into(),
+        ("auto-hide-method-docs", "Auto-hide item methods' documentation", false).into(),
+        ("auto-hide-trait-implementations", "Auto-hide trait implementations documentation",
+            true).into(),
         ("go-to-only-result", "Directly go to item in search if there is only one result",
-            false),
-        ("line-numbers", "Show line numbers on code examples", false),
-        ("disable-shortcuts", "Disable keyboard shortcuts", false),
+            false).into(),
+        ("line-numbers", "Show line numbers on code examples", false).into(),
+        ("disable-shortcuts", "Disable keyboard shortcuts", false).into(),
     ];
     format!(
 "<h1 class='fqn'>\
@@ -1249,17 +1318,7 @@ fn settings(root_path: &str, suffix: &str) -> String {
 </h1>\
 <div class='settings'>{}</div>\
 <script src='{}settings{}.js'></script>",
-            settings.iter()
-                        .map(|(id, text, enabled)| {
-                            format!("<div class='setting-line'>\
-                                            <label class='toggle'>\
-                                            <input type='checkbox' id='{}' {}>\
-                                            <span class='slider'></span>\
-                                            </label>\
-                                            <div>{}</div>\
-                                        </div>", id, if *enabled { " checked" } else { "" }, text)
-                        })
-                        .collect::<String>(),
+            settings.iter().map(|s| s.display()).collect::<String>(),
             root_path,
             suffix)
 }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 53e16978ff1..04c0a0f005b 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -3,7 +3,7 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass */
-/* global isHidden, onEach, removeClass, updateLocalStorage */
+/* global onEach, removeClass, updateLocalStorage */
 
 if (!String.prototype.startsWith) {
     String.prototype.startsWith = function(searchString, position) {
@@ -161,17 +161,18 @@ function getSearchElement() {
         return window.history && typeof window.history.pushState === "function";
     }
 
+    function isHidden(elem) {
+        return elem.offsetHeight === 0;
+    }
+
     var main = document.getElementById("main");
+    var savedHash = "";
 
-    function onHashChange(ev) {
-        // If we're in mobile mode, we should hide the sidebar in any case.
-        hideSidebar();
-        var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
-        if (match) {
-            return highlightSourceLines(match, ev);
-        }
+    function handleHashes(ev) {
         var search = getSearchElement();
         if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
+            // This block occurs when clicking on an element in the navbar while
+            // in a search.
             addClass(search, "hidden");
             removeClass(main, "hidden");
             var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
@@ -183,6 +184,35 @@ function getSearchElement() {
                 elem.scrollIntoView();
             }
         }
+        // This part is used in case an element is not visible.
+        if (savedHash !== window.location.hash) {
+            savedHash = window.location.hash;
+            if (savedHash.length === 0) {
+                return;
+            }
+            var elem = document.getElementById(savedHash.slice(1)); // we remove the '#'
+            if (!elem || !isHidden(elem)) {
+                return;
+            }
+            var parent = elem.parentNode;
+            if (parent && hasClass(parent, "impl-items")) {
+                // In case this is a trait implementation item, we first need to toggle
+                // the "Show hidden undocumented items".
+                onEachLazy(parent.getElementsByClassName("collapsed"), function(e) {
+                    if (e.parentNode === parent) {
+                        // Only click on the toggle we're looking for.
+                        e.click();
+                        return true;
+                    }
+                });
+                if (isHidden(elem)) {
+                    // The whole parent is collapsed. We need to click on its toggle as well!
+                    if (hasClass(parent.lastElementChild, "collapse-toggle")) {
+                        parent.lastElementChild.click();
+                    }
+                }
+            }
+        }
     }
 
     function highlightSourceLines(match, ev) {
@@ -228,6 +258,16 @@ function getSearchElement() {
         }
     }
 
+    function onHashChange(ev) {
+        // If we're in mobile mode, we should hide the sidebar in any case.
+        hideSidebar();
+        var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
+        if (match) {
+            return highlightSourceLines(match, ev);
+        }
+        handleHashes(ev);
+    }
+
     function expandSection(id) {
         var elem = document.getElementById(id);
         if (elem && isHidden(elem)) {
@@ -246,9 +286,6 @@ function getSearchElement() {
         }
     }
 
-    highlightSourceLines();
-    window.onhashchange = onHashChange;
-
     // Gets the human-readable string for the virtual-key code of the
     // given KeyboardEvent, ev.
     //
@@ -2118,7 +2155,7 @@ function getSearchElement() {
     function autoCollapse(pageId, collapse) {
         if (collapse) {
             toggleAllDocs(pageId, true);
-        } else if (getCurrentValue("rustdoc-trait-implementations") !== "false") {
+        } else if (getCurrentValue("rustdoc-auto-hide-trait-implementations") !== "false") {
             var impl_list = document.getElementById("implementations-list");
 
             if (impl_list !== null) {
@@ -2156,7 +2193,7 @@ function getSearchElement() {
     }
 
     var toggle = createSimpleToggle(false);
-    var hideMethodDocs = getCurrentValue("rustdoc-method-docs") === "true";
+    var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
     var pageId = getPageId();
 
     var func = function(e) {
@@ -2286,7 +2323,31 @@ function getSearchElement() {
         return wrapper;
     }
 
-    var showItemDeclarations = getCurrentValue("rustdoc-item-declarations") === "false";
+    var currentType = document.getElementsByClassName("type-decl")[0];
+    var className = null;
+    if (currentType) {
+        currentType = currentType.getElementsByClassName("rust")[0];
+        if (currentType) {
+            currentType.classList.forEach(function(item) {
+                if (item !== "main") {
+                    className = item;
+                    return true;
+                }
+            });
+        }
+    }
+    var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
+    if (showItemDeclarations === null) {
+        if (className === "enum" || className === "macro") {
+            showItemDeclarations = "false";
+        } else if (className === "struct" || className === "union" || className === "trait") {
+            showItemDeclarations = "true";
+        } else {
+            // In case we found an unknown type, we just use the "parent" value.
+            showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
+        }
+    }
+    showItemDeclarations = showItemDeclarations === "false";
     function buildToggleWrapper(e) {
         if (hasClass(e, "autohide")) {
             var wrap = e.previousElementSibling;
@@ -2369,7 +2430,7 @@ function getSearchElement() {
 
     // To avoid checking on "rustdoc-item-attributes" value on every loop...
     var itemAttributesFunc = function() {};
-    if (getCurrentValue("rustdoc-item-attributes") !== "false") {
+    if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
         itemAttributesFunc = function(x) {
             collapseDocs(x.previousSibling.childNodes[0], "toggle");
         };
@@ -2615,6 +2676,9 @@ function getSearchElement() {
         insertAfter(popup, getSearchElement());
     }
 
+    onHashChange();
+    window.onhashchange = onHashChange;
+
     buildHelperPopup();
 }());
 
diff --git a/src/librustdoc/html/static/settings.css b/src/librustdoc/html/static/settings.css
index b31ad96fa54..d03cf7fcc45 100644
--- a/src/librustdoc/html/static/settings.css
+++ b/src/librustdoc/html/static/settings.css
@@ -1,5 +1,6 @@
 .setting-line {
 	padding: 5px;
+	position: relative;
 }
 
 .setting-line > div {
@@ -10,6 +11,13 @@
 	padding-top: 2px;
 }
 
+.setting-line > .title {
+	font-size: 19px;
+	width: 100%;
+	max-width: none;
+	border-bottom: 1px solid;
+}
+
 .toggle {
 	position: relative;
 	display: inline-block;
@@ -59,3 +67,9 @@ input:checked + .slider:before {
 	-ms-transform: translateX(19px);
 	transform: translateX(19px);
 }
+
+.setting-line > .sub-settings {
+	padding-left: 42px;
+	width: 100%;
+	display: block;
+}
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index eae998ca3ec..d142d99ac70 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -24,10 +24,6 @@ function removeClass(elem, className) {
     elem.classList.remove(className);
 }
 
-function isHidden(elem) {
-    return elem.offsetParent === null;
-}
-
 function onEach(arr, func, reversed) {
     if (arr && arr.length > 0 && func) {
         var length = arr.length;
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index c3116dbe7a2..a60d543a539 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -425,3 +425,6 @@ div.files > a:hover, div.name:hover {
 div.files > .selected {
 	background-color: #333;
 }
+.setting-line > .title {
+	border-bottom-color: #ddd;
+}
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index e2bf9f9d2f2..351f027b942 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -419,3 +419,6 @@ div.files > a:hover, div.name:hover {
 div.files > .selected {
 	background-color: #fff;
 }
+.setting-line > .title {
+	border-bottom-color: #D5D5D5;
+}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8cd32a3d1b5..13b8809e23e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -140,7 +140,7 @@ fn opts() -> Vec<RustcOptGroup> {
         }),
         stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")),
         stable("extern", |o| {
-            o.optmulti("", "extern", "pass an --extern to rustc", "NAME=PATH")
+            o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")
         }),
         unstable("extern-html-root-url", |o| {
             o.optmulti("", "extern-html-root-url",
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 10e15ab8881..4603e77b0fd 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,6 +1,6 @@
 use errors::Applicability;
 use syntax::parse::lexer::{StringReader as Lexer};
-use syntax::parse::token;
+use syntax::token;
 use syntax::sess::ParseSess;
 use syntax::source_map::FilePathMapping;
 use syntax_pos::{InnerSpan, FileName};
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 44d25f1b476..0588373dcdc 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -409,10 +409,10 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// let five = 5.0_f64;
+    /// let twenty_five = 25.0_f64;
     ///
-    /// // log5(5) - 1 == 0
-    /// let abs_difference = (five.log(5.0) - 1.0).abs();
+    /// // log5(25) - 2 == 0
+    /// let abs_difference = (twenty_five.log(5.0) - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -425,10 +425,10 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// let two = 2.0_f64;
+    /// let four = 4.0_f64;
     ///
-    /// // log2(2) - 1 == 0
-    /// let abs_difference = (two.log2() - 1.0).abs();
+    /// // log2(4) - 2 == 0
+    /// let abs_difference = (four.log2() - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -448,10 +448,10 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// let ten = 10.0_f64;
+    /// let hundred = 100.0_f64;
     ///
-    /// // log10(10) - 1 == 0
-    /// let abs_difference = (ten.log10() - 1.0).abs();
+    /// // log10(100) - 2 == 0
+    /// let abs_difference = (hundred.log10() - 2.0).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 9593a1bae0a..ad567c97c2c 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -24,7 +24,9 @@ use crate::memchr;
 ///
 /// When the `BufReader<R>` is dropped, the contents of its buffer will be
 /// discarded. Creating multiple instances of a `BufReader<R>` on the same
-/// stream can cause data loss.
+/// stream can cause data loss. Reading from the underlying reader after
+/// unwrapping the `BufReader<R>` with `BufReader::into_inner` can also cause
+/// data loss.
 ///
 /// [`Read`]: ../../std/io/trait.Read.html
 /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
@@ -179,7 +181,8 @@ impl<R> BufReader<R> {
 
     /// Unwraps this `BufReader<R>`, returning the underlying reader.
     ///
-    /// Note that any leftover data in the internal buffer is lost.
+    /// Note that any leftover data in the internal buffer is lost. Therefore,
+    /// a following read from the underlying reader may lead to data loss.
     ///
     /// # Examples
     ///
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c7adad896a5..927fd2a6b0b 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -284,7 +284,7 @@
 #![feature(never_type)]
 #![feature(nll)]
 #![cfg_attr(bootstrap, feature(non_exhaustive))]
-#![feature(on_unimplemented)]
+#![cfg_attr(bootstrap, feature(on_unimplemented))]
 #![feature(optin_builtin_traits)]
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 4b0cf8312f1..b1274a08cbe 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1661,7 +1661,7 @@ mod tests {
     // FIXME(#10380) these tests should not all be ignored on android.
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn smoke() {
         let p = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 0"]).spawn()
@@ -1683,7 +1683,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn exit_reported_right() {
         let p = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).spawn()
@@ -1698,7 +1698,7 @@ mod tests {
 
     #[test]
     #[cfg(unix)]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn signal_reported_right() {
         use crate::os::unix::process::ExitStatusExt;
 
@@ -1726,7 +1726,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn stdout_works() {
         if cfg!(target_os = "windows") {
             let mut cmd = Command::new("cmd");
@@ -1740,7 +1740,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(any(windows, target_os = "android"), ignore)]
+    #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
     fn set_current_dir_works() {
         let mut cmd = Command::new("/bin/sh");
         cmd.arg("-c").arg("pwd")
@@ -1750,7 +1750,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(any(windows, target_os = "android"), ignore)]
+    #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
     fn stdin_works() {
         let mut p = Command::new("/bin/sh")
                             .arg("-c").arg("read line; echo $line")
@@ -1766,7 +1766,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_process_status() {
         let mut status = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
@@ -1792,7 +1792,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_process_output_output() {
         let Output {status, stdout, stderr}
              = if cfg!(target_os = "windows") {
@@ -1808,7 +1808,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_process_output_error() {
         let Output {status, stdout, stderr}
              = if cfg!(target_os = "windows") {
@@ -1823,7 +1823,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_finish_once() {
         let mut prog = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
@@ -1834,7 +1834,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_finish_twice() {
         let mut prog = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
@@ -1846,7 +1846,7 @@ mod tests {
     }
 
     #[test]
-    #[cfg_attr(target_os = "android", ignore)]
+    #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
     fn test_wait_with_output_once() {
         let prog = if cfg!(target_os = "windows") {
             Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
@@ -1881,6 +1881,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_override_env() {
         use crate::env;
 
@@ -1901,6 +1902,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_add_to_env() {
         let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
         let output = String::from_utf8_lossy(&result.stdout).to_string();
@@ -1910,6 +1912,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_capture_env_at_spawn() {
         use crate::env;
 
@@ -1965,6 +1968,7 @@ mod tests {
 
     // Regression tests for #30862.
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_interior_nul_in_env_key_is_error() {
         match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
@@ -1973,6 +1977,7 @@ mod tests {
     }
 
     #[test]
+    #[cfg_attr(target_os = "vxworks", ignore)]
     fn test_interior_nul_in_env_value_is_error() {
         match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
diff --git a/src/libstd/sys/sgx/abi/mod.rs b/src/libstd/sys/sgx/abi/mod.rs
index 0f107de83f0..3a9b1fc8684 100644
--- a/src/libstd/sys/sgx/abi/mod.rs
+++ b/src/libstd/sys/sgx/abi/mod.rs
@@ -53,6 +53,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
 // (main function exists). If this is a library, the crate author should be
 // able to specify this
 #[cfg(not(test))]
+#[allow(improper_ctypes)]
 #[no_mangle]
 extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> (u64, u64) {
     // FIXME: how to support TLS in library mode?
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
index e2f94b1d928..c32e6dd3786 100644
--- a/src/libstd/sys/sgx/rwlock.rs
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -172,6 +172,7 @@ const EINVAL: i32 = 22;
 
 #[cfg(not(test))]
 #[no_mangle]
+#[allow(improper_ctypes)]
 pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
         return EINVAL;
@@ -181,6 +182,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
 }
 
 #[cfg(not(test))]
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
@@ -190,6 +192,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
     return 0;
 }
 #[cfg(not(test))]
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
     if p.is_null() {
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index cfaab4e22e9..46453b47fca 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -149,7 +149,7 @@ macro_rules! thread_local {
 #[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
 #[allow_internal_unsafe]
 macro_rules! __thread_local_inner {
-    (@key $(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
+    (@key $t:ty, $init:expr) => {
         {
             #[inline]
             fn __init() -> $t { $init }
@@ -184,7 +184,7 @@ macro_rules! __thread_local_inner {
     };
     ($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
         $(#[$attr])* $vis const $name: $crate::thread::LocalKey<$t> =
-            $crate::__thread_local_inner!(@key $(#[$attr])* $vis $name, $t, $init);
+            $crate::__thread_local_inner!(@key $t, $init);
     }
 }
 
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 0ffa6ace2e4..0c632d2afbd 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -1271,6 +1271,18 @@ impl fmt::Debug for Thread {
 ///
 /// Indicates the manner in which a thread exited.
 ///
+/// The value contained in the `Result::Err` variant
+/// is the value the thread panicked with;
+/// that is, the argument the `panic!` macro was called with.
+/// Unlike with normal errors, this value doesn't implement
+/// the [`Error`](crate::error::Error) trait.
+///
+/// Thus, a sensible way to handle a thread panic is to either:
+/// 1. `unwrap` the `Result<T>`, propagating the panic
+/// 2. or in case the thread is intended to be a subsystem boundary
+/// that is supposed to isolate system-level failures,
+/// match on the `Err` variant and handle the panic in an appropriate way.
+///
 /// A thread that completes without panicking is considered to exit successfully.
 ///
 /// # Examples
diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml
index b1839cc05cd..3e17e7949ea 100644
--- a/src/libsyntax/Cargo.toml
+++ b/src/libsyntax/Cargo.toml
@@ -20,5 +20,4 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_index = { path = "../librustc_index" }
 rustc_lexer = { path = "../librustc_lexer" }
-rustc_target = { path = "../librustc_target" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8af38507b48..18151a1586c 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -22,12 +22,11 @@ pub use GenericArgs::*;
 pub use UnsafeSource::*;
 pub use crate::util::parser::ExprPrecedence;
 
-pub use rustc_target::abi::FloatTy;
 pub use syntax_pos::symbol::{Ident, Symbol as Name};
 
-use crate::parse::token::{self, DelimToken};
 use crate::ptr::P;
 use crate::source_map::{dummy_spanned, respan, Spanned};
+use crate::token::{self, DelimToken};
 use crate::tokenstream::TokenStream;
 
 use syntax_pos::symbol::{kw, sym, Symbol};
@@ -38,7 +37,6 @@ use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_index::vec::Idx;
 use rustc_serialize::{self, Decoder, Encoder};
-use rustc_target::spec::abi::Abi;
 
 #[cfg(target_arch = "x86_64")]
 use rustc_data_structures::static_assert_size;
@@ -1401,7 +1399,7 @@ pub struct Lit {
 
 // Clippy uses Hash and PartialEq
 /// Type of the integer literal based on provided suffix.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, Hash, PartialEq)]
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
 pub enum LitIntType {
     /// e.g. `42_i32`.
     Signed(IntTy),
@@ -1411,6 +1409,15 @@ pub enum LitIntType {
     Unsuffixed,
 }
 
+/// Type of the float literal based on provided suffix.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, Hash, PartialEq)]
+pub enum LitFloatType {
+    /// A float literal with a suffix (`1f32` or `1E10f32`).
+    Suffixed(FloatTy),
+    /// A float literal without a suffix (`1.0 or 1.0E10`).
+    Unsuffixed,
+}
+
 /// Literal kind.
 ///
 /// E.g., `"foo"`, `42`, `12.34`, or `bool`.
@@ -1428,9 +1435,7 @@ pub enum LitKind {
     /// An integer literal (`1`).
     Int(u128, LitIntType),
     /// A float literal (`1f64` or `1E10f64`).
-    Float(Symbol, FloatTy),
-    /// A float literal without a suffix (`1.0 or 1.0E10`).
-    FloatUnsuffixed(Symbol),
+    Float(Symbol, LitFloatType),
     /// A boolean literal.
     Bool(bool),
     /// Placeholder for a literal that wasn't well-formed in some way.
@@ -1457,7 +1462,7 @@ impl LitKind {
     /// Returns `true` if this is a numeric literal.
     pub fn is_numeric(&self) -> bool {
         match *self {
-            LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => true,
+            LitKind::Int(..) | LitKind::Float(..) => true,
             _ => false,
         }
     }
@@ -1474,14 +1479,14 @@ impl LitKind {
             // suffixed variants
             LitKind::Int(_, LitIntType::Signed(..))
             | LitKind::Int(_, LitIntType::Unsigned(..))
-            | LitKind::Float(..) => true,
+            | LitKind::Float(_, LitFloatType::Suffixed(..)) => true,
             // unsuffixed variants
             LitKind::Str(..)
             | LitKind::ByteStr(..)
             | LitKind::Byte(..)
             | LitKind::Char(..)
             | LitKind::Int(_, LitIntType::Unsuffixed)
-            | LitKind::FloatUnsuffixed(..)
+            | LitKind::Float(_, LitFloatType::Unsuffixed)
             | LitKind::Bool(..)
             | LitKind::Err(..) => false,
         }
@@ -1553,7 +1558,36 @@ pub enum ImplItemKind {
     Macro(Mac),
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
+pub enum FloatTy {
+    F32,
+    F64,
+}
+
+impl FloatTy {
+    pub fn name_str(self) -> &'static str {
+        match self {
+            FloatTy::F32 => "f32",
+            FloatTy::F64 => "f64",
+        }
+    }
+
+    pub fn name(self) -> Symbol {
+        match self {
+            FloatTy::F32 => sym::f32,
+            FloatTy::F64 => sym::f64,
+        }
+    }
+
+    pub fn bit_width(self) -> usize {
+        match self {
+            FloatTy::F32 => 32,
+            FloatTy::F64 => 64,
+        }
+    }
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)]
 pub enum IntTy {
     Isize,
     I8,
@@ -1563,20 +1597,8 @@ pub enum IntTy {
     I128,
 }
 
-impl fmt::Debug for IntTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Display for IntTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ty_to_string())
-    }
-}
-
 impl IntTy {
-    pub fn ty_to_string(&self) -> &'static str {
+    pub fn name_str(&self) -> &'static str {
         match *self {
             IntTy::Isize => "isize",
             IntTy::I8 => "i8",
@@ -1587,7 +1609,7 @@ impl IntTy {
         }
     }
 
-    pub fn to_symbol(&self) -> Symbol {
+    pub fn name(&self) -> Symbol {
         match *self {
             IntTy::Isize => sym::isize,
             IntTy::I8 => sym::i8,
@@ -1602,7 +1624,7 @@ impl IntTy {
         // Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
         // are parsed as `u128`, so we wouldn't want to print an extra negative
         // sign.
-        format!("{}{}", val as u128, self.ty_to_string())
+        format!("{}{}", val as u128, self.name_str())
     }
 
     pub fn bit_width(&self) -> Option<usize> {
@@ -1617,7 +1639,7 @@ impl IntTy {
     }
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Copy, Debug)]
 pub enum UintTy {
     Usize,
     U8,
@@ -1628,7 +1650,7 @@ pub enum UintTy {
 }
 
 impl UintTy {
-    pub fn ty_to_string(&self) -> &'static str {
+    pub fn name_str(&self) -> &'static str {
         match *self {
             UintTy::Usize => "usize",
             UintTy::U8 => "u8",
@@ -1639,7 +1661,7 @@ impl UintTy {
         }
     }
 
-    pub fn to_symbol(&self) -> Symbol {
+    pub fn name(&self) -> Symbol {
         match *self {
             UintTy::Usize => sym::usize,
             UintTy::U8 => sym::u8,
@@ -1651,7 +1673,7 @@ impl UintTy {
     }
 
     pub fn val_to_string(&self, val: u128) -> String {
-        format!("{}{}", val, self.ty_to_string())
+        format!("{}{}", val, self.name_str())
     }
 
     pub fn bit_width(&self) -> Option<usize> {
@@ -1666,18 +1688,6 @@ impl UintTy {
     }
 }
 
-impl fmt::Debug for UintTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(self, f)
-    }
-}
-
-impl fmt::Display for UintTy {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.ty_to_string())
-    }
-}
-
 /// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
 /// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -2190,22 +2200,29 @@ pub struct AttrItem {
 }
 
 /// Metadata associated with an item.
-/// Doc-comments are promoted to attributes that have `is_sugared_doc = true`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Attribute {
-    pub item: AttrItem,
+    pub kind: AttrKind,
     pub id: AttrId,
     /// Denotes if the attribute decorates the following construct (outer)
     /// or the construct this attribute is contained within (inner).
     pub style: AttrStyle,
-    pub is_sugared_doc: bool,
     pub span: Span,
 }
 
-// Compatibility impl to avoid churn, consider removing.
-impl std::ops::Deref for Attribute {
-    type Target = AttrItem;
-    fn deref(&self) -> &Self::Target { &self.item }
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+pub enum AttrKind {
+    /// A normal attribute.
+    Normal(AttrItem),
+
+    /// A doc comment (e.g. `/// ...`, `//! ...`, `/** ... */`, `/*! ... */`).
+    /// Doc attributes (e.g. `#[doc="..."]`) are represented with the `Normal`
+    /// variant (which is much less compact and thus more expensive).
+    ///
+    /// Note: `self.has_name(sym::doc)` and `self.check_name(sym::doc)` succeed
+    /// for this variant, but this may change in the future.
+    /// ```
+    DocComment(Symbol),
 }
 
 /// `TraitRef`s appear in impls.
@@ -2351,6 +2368,27 @@ impl Item {
     }
 }
 
+/// A reference to an ABI.
+///
+/// In AST our notion of an ABI is still syntactic unlike in `rustc_target::spec::abi::Abi`.
+#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, PartialEq)]
+pub struct Abi {
+    pub symbol: Symbol,
+    pub span: Span,
+}
+
+impl Abi {
+    pub fn new(symbol: Symbol, span: Span) -> Self {
+        Self { symbol, span }
+    }
+}
+
+impl Default for Abi {
+    fn default() -> Self {
+        Self::new(sym::Rust, DUMMY_SP)
+    }
+}
+
 /// A function header.
 ///
 /// All the information between the visibility and the name of the function is
@@ -2369,7 +2407,7 @@ impl Default for FnHeader {
             unsafety: Unsafety::Normal,
             asyncness: dummy_spanned(IsAsync::NotAsync),
             constness: dummy_spanned(Constness::NotConst),
-            abi: Abi::Rust,
+            abi: Abi::default(),
         }
     }
 }
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 84c86c9651f..787d69f5e99 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -228,7 +228,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
             sym::stable,
             sym::rustc_promotable,
             sym::rustc_allow_const_fn_ptr,
-        ].iter().any(|&s| attr.path == s) {
+        ].iter().any(|&s| attr.has_name(s)) {
             continue // not a stability level
         }
 
@@ -236,10 +236,10 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
 
         let meta = attr.meta();
 
-        if attr.path == sym::rustc_promotable {
+        if attr.has_name(sym::rustc_promotable) {
             promotable = true;
         }
-        if attr.path == sym::rustc_allow_const_fn_ptr {
+        if attr.has_name(sym::rustc_allow_const_fn_ptr) {
             allow_const_fn_ptr = true;
         }
         // attributes with data
@@ -778,7 +778,7 @@ pub fn find_repr_attrs(sess: &ParseSess, attr: &Attribute) -> Vec<ReprAttr> {
 
     let mut acc = Vec::new();
     let diagnostic = &sess.span_diagnostic;
-    if attr.path == sym::repr {
+    if attr.has_name(sym::repr) {
         if let Some(items) = attr.meta_item_list() {
             mark_used(attr);
             for item in items {
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 3e240a855e2..c639431794c 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -9,15 +9,13 @@ pub use StabilityLevel::*;
 pub use crate::ast::Attribute;
 
 use crate::ast;
-use crate::ast::{AttrItem, AttrId, AttrStyle, Name, Ident, Path, PathSegment};
+use crate::ast::{AttrItem, AttrId, AttrKind, AttrStyle, Name, Ident, Path, PathSegment};
 use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem};
 use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam};
 use crate::mut_visit::visit_clobber;
 use crate::source_map::{BytePos, Spanned};
-use crate::parse::lexer::comments::doc_comment_style;
 use crate::parse;
-use crate::parse::PResult;
-use crate::parse::token::{self, Token};
+use crate::token::{self, Token};
 use crate::ptr::P;
 use crate::sess::ParseSess;
 use crate::symbol::{sym, Symbol};
@@ -25,6 +23,8 @@ use crate::ThinVec;
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 use crate::GLOBALS;
 
+use errors::PResult;
+
 use log::debug;
 use syntax_pos::Span;
 
@@ -145,12 +145,17 @@ impl NestedMetaItem {
 }
 
 impl Attribute {
+    pub fn has_name(&self, name: Symbol) -> bool {
+        match self.kind {
+            AttrKind::Normal(ref item) => item.path == name,
+            AttrKind::DocComment(_) => name == sym::doc,
+        }
+    }
+
     /// Returns `true` if the attribute's path matches the argument. If it matches, then the
     /// attribute is marked as used.
-    ///
-    /// To check the attribute name without marking it used, use the `path` field directly.
     pub fn check_name(&self, name: Symbol) -> bool {
-        let matches = self.path == name;
+        let matches = self.has_name(name);
         if matches {
             mark_used(self);
         }
@@ -159,10 +164,15 @@ impl Attribute {
 
     /// For a single-segment attribute, returns its name; otherwise, returns `None`.
     pub fn ident(&self) -> Option<Ident> {
-        if self.path.segments.len() == 1 {
-            Some(self.path.segments[0].ident)
-        } else {
-            None
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                if item.path.segments.len() == 1 {
+                    Some(item.path.segments[0].ident)
+                } else {
+                    None
+                }
+            }
+            AttrKind::DocComment(_) => Some(Ident::new(sym::doc, self.span)),
         }
     }
     pub fn name_or_empty(&self) -> Symbol {
@@ -170,18 +180,32 @@ impl Attribute {
     }
 
     pub fn value_str(&self) -> Option<Symbol> {
-        self.meta().and_then(|meta| meta.value_str())
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                item.meta(self.span).and_then(|meta| meta.value_str())
+            }
+            AttrKind::DocComment(comment) => Some(comment),
+        }
     }
 
     pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> {
-        match self.meta() {
-            Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
-            _ => None
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                match item.meta(self.span) {
+                    Some(MetaItem { kind: MetaItemKind::List(list), .. }) => Some(list),
+                    _ => None
+                }
+            }
+            AttrKind::DocComment(_) => None,
         }
     }
 
     pub fn is_word(&self) -> bool {
-        self.tokens.is_empty()
+        if let AttrKind::Normal(item) = &self.kind {
+            item.tokens.is_empty()
+        } else {
+            false
+        }
     }
 
     pub fn is_meta_item_list(&self) -> bool {
@@ -275,17 +299,49 @@ impl AttrItem {
 }
 
 impl Attribute {
+    pub fn is_doc_comment(&self) -> bool {
+        match self.kind {
+            AttrKind::Normal(_) => false,
+            AttrKind::DocComment(_) => true,
+        }
+    }
+
+    pub fn get_normal_item(&self) -> &AttrItem {
+        match self.kind {
+            AttrKind::Normal(ref item) => item,
+            AttrKind::DocComment(_) => panic!("unexpected sugared doc"),
+        }
+    }
+
+    pub fn unwrap_normal_item(self) -> AttrItem {
+        match self.kind {
+            AttrKind::Normal(item) => item,
+            AttrKind::DocComment(_) => panic!("unexpected sugared doc"),
+        }
+    }
+
     /// Extracts the MetaItem from inside this Attribute.
     pub fn meta(&self) -> Option<MetaItem> {
-        self.item.meta(self.span)
+        match self.kind {
+            AttrKind::Normal(ref item) => item.meta(self.span),
+            AttrKind::DocComment(comment) =>
+                Some(mk_name_value_item_str(Ident::new(sym::doc, self.span), comment, self.span)),
+        }
     }
 
     pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
-        Ok(MetaItem {
-            path: self.path.clone(),
-            kind: parse::parse_in_attr(sess, self, |p| p.parse_meta_item_kind())?,
-            span: self.span,
-        })
+        match self.kind {
+            AttrKind::Normal(ref item) => {
+                Ok(MetaItem {
+                    path: item.path.clone(),
+                    kind: parse::parse_in_attr(sess, self, |parser| parser.parse_meta_item_kind())?,
+                    span: self.span,
+                })
+            }
+            AttrKind::DocComment(comment) => {
+                Ok(mk_name_value_item_str(Ident::new(sym::doc, self.span), comment, self.span))
+            }
+        }
     }
 }
 
@@ -327,10 +383,9 @@ crate fn mk_attr_id() -> AttrId {
 
 pub fn mk_attr(style: AttrStyle, path: Path, tokens: TokenStream, span: Span) -> Attribute {
     Attribute {
-        item: AttrItem { path, tokens },
+        kind: AttrKind::Normal(AttrItem { path, tokens }),
         id: mk_attr_id(),
         style,
-        is_sugared_doc: false,
         span,
     }
 }
@@ -345,18 +400,11 @@ pub fn mk_attr_outer(item: MetaItem) -> Attribute {
     mk_attr(AttrStyle::Outer, item.path, item.kind.tokens(item.span), item.span)
 }
 
-pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute {
-    let style = doc_comment_style(&text.as_str());
-    let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked);
-    let lit = Lit::from_lit_kind(lit_kind, span);
+pub fn mk_doc_comment(style: AttrStyle, comment: Symbol, span: Span) -> Attribute {
     Attribute {
-        item: AttrItem {
-            path: Path::from_ident(Ident::with_dummy_span(sym::doc).with_span_pos(span)),
-            tokens: MetaItemKind::NameValue(lit).tokens(span),
-        },
+        kind: AttrKind::DocComment(comment),
         id: mk_attr_id(),
         style,
-        is_sugared_doc: true,
         span,
     }
 }
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 6003fd1d286..5f89ed36e2a 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -93,10 +93,10 @@ impl<'a> StripUnconfigured<'a> {
     /// is in the original source file. Gives a compiler error if the syntax of
     /// the attribute is incorrect.
     fn process_cfg_attr(&mut self, attr: ast::Attribute) -> Vec<ast::Attribute> {
-        if attr.path != sym::cfg_attr {
+        if !attr.has_name(sym::cfg_attr) {
             return vec![attr];
         }
-        if attr.tokens.is_empty() {
+        if attr.get_normal_item().tokens.is_empty() {
             self.sess.span_diagnostic
                 .struct_span_err(
                     attr.span,
@@ -136,10 +136,9 @@ impl<'a> StripUnconfigured<'a> {
             //  `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
             expanded_attrs.into_iter()
             .flat_map(|(item, span)| self.process_cfg_attr(ast::Attribute {
-                item,
+                kind: ast::AttrKind::Normal(item),
                 id: attr::mk_attr_id(),
                 style: attr.style,
-                is_sugared_doc: false,
                 span,
             }))
             .collect()
@@ -212,7 +211,7 @@ impl<'a> StripUnconfigured<'a> {
                                       GateIssue::Language,
                                       EXPLAIN_STMT_ATTR_SYNTAX);
 
-            if attr.is_sugared_doc {
+            if attr.is_doc_comment() {
                 err.help("`///` is for documentation comments. For a plain comment, use `//`.");
             }
 
diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs
index 941df5ea570..c23c8d65a7f 100644
--- a/src/libsyntax/error_codes.rs
+++ b/src/libsyntax/error_codes.rs
@@ -540,6 +540,5 @@ equivalent in Rust would be to use macros directly.
     E0630,
     E0693, // incorrect `repr(align)` attribute format
 //  E0694, // an unknown tool name found in scoped attributes
-    E0703, // invalid ABI
     E0717, // rustc_promotable without stability attribute
 }
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 736a363bbfc..1e77eaaae88 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -134,9 +134,6 @@ declare_features! (
     /// Allows using `rustc_*` attributes (RFC 572).
     (active, rustc_attrs, "1.0.0", Some(29642), None),
 
-    /// Allows using `#[on_unimplemented(..)]` on traits.
-    (active, on_unimplemented, "1.0.0", Some(29628), None),
-
     /// Allows using the `box $expr` syntax.
     (active, box_syntax, "1.0.0", Some(49733), None),
 
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index eb811c3e0ff..b32a887c6b2 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -166,7 +166,7 @@ macro_rules! experimental {
 }
 
 const IMPL_DETAIL: &str = "internal implementation detail";
-const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
+const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
 
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
@@ -418,14 +418,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
         "the `linkage` attribute is experimental and not portable across platforms",
     ),
-    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Macro related:
     // ==========================================================================
 
     rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
     rustc_attr!(
         rustc_macro_transparency, Whitelisted,
         template!(NameValueStr: "transparent|semitransparent|opaque"),
@@ -436,17 +436,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Internal attributes, Diagnostics related:
     // ==========================================================================
 
-    gated!(
+    rustc_attr!(
         rustc_on_unimplemented, Whitelisted,
         template!(
             List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
             NameValueStr: "message"
         ),
-        on_unimplemented,
-        experimental!(rustc_on_unimplemented),
+        INTERNAL_UNSTABLE
     ),
     // Whitelists "identity-like" conversion methods to suggest on type mismatch.
-    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Const related:
@@ -454,7 +453,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL),
     rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Layout related:
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index d9cc5f6c169..ecff89ad59b 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -11,14 +11,13 @@ 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;
+use crate::token;
 use crate::sess::ParseSess;
 use crate::symbol::{Symbol, sym};
 use crate::tokenstream::TokenTree;
 
 use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
 
@@ -192,62 +191,70 @@ macro_rules! gate_feature_post {
 }
 
 impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: Abi, span: Span) {
-        match abi {
-            Abi::RustIntrinsic => {
+    fn check_abi(&self, abi: ast::Abi) {
+        let ast::Abi { symbol, span } = abi;
+
+        match &*symbol.as_str() {
+            // Stable
+            "Rust" |
+            "C" |
+            "cdecl" |
+            "stdcall" |
+            "fastcall" |
+            "aapcs" |
+            "win64" |
+            "sysv64" |
+            "system" => {}
+            "rust-intrinsic" => {
                 gate_feature_post!(&self, intrinsics, span,
                                    "intrinsics are subject to change");
             },
-            Abi::PlatformIntrinsic => {
+            "platform-intrinsic" => {
                 gate_feature_post!(&self, platform_intrinsics, span,
                                    "platform intrinsics are experimental and possibly buggy");
             },
-            Abi::Vectorcall => {
+            "vectorcall" => {
                 gate_feature_post!(&self, abi_vectorcall, span,
                                    "vectorcall is experimental and subject to change");
             },
-            Abi::Thiscall => {
+            "thiscall" => {
                 gate_feature_post!(&self, abi_thiscall, span,
                                    "thiscall is experimental and subject to change");
             },
-            Abi::RustCall => {
+            "rust-call" => {
                 gate_feature_post!(&self, unboxed_closures, span,
                                    "rust-call ABI is subject to change");
             },
-            Abi::PtxKernel => {
+            "ptx-kernel" => {
                 gate_feature_post!(&self, abi_ptx, span,
                                    "PTX ABIs are experimental and subject to change");
             },
-            Abi::Unadjusted => {
+            "unadjusted" => {
                 gate_feature_post!(&self, abi_unadjusted, span,
                                    "unadjusted ABI is an implementation detail and perma-unstable");
             },
-            Abi::Msp430Interrupt => {
+            "msp430-interrupt" => {
                 gate_feature_post!(&self, abi_msp430_interrupt, span,
                                    "msp430-interrupt ABI is experimental and subject to change");
             },
-            Abi::X86Interrupt => {
+            "x86-interrupt" => {
                 gate_feature_post!(&self, abi_x86_interrupt, span,
                                    "x86-interrupt ABI is experimental and subject to change");
             },
-            Abi::AmdGpuKernel => {
+            "amdgpu-kernel" => {
                 gate_feature_post!(&self, abi_amdgpu_kernel, span,
                                    "amdgpu-kernel ABI is experimental and subject to change");
             },
-            Abi::EfiApi => {
+            "efiapi" => {
                 gate_feature_post!(&self, abi_efiapi, span,
                                    "efiapi ABI is experimental and subject to change");
             },
-            // Stable
-            Abi::Cdecl |
-            Abi::Stdcall |
-            Abi::Fastcall |
-            Abi::Aapcs |
-            Abi::Win64 |
-            Abi::SysV64 |
-            Abi::Rust |
-            Abi::C |
-            Abi::System => {}
+            abi => {
+                self.parse_sess.span_diagnostic.delay_span_bug(
+                    span,
+                    &format!("unrecognized ABI not caught in lowering: {}", abi),
+                )
+            }
         }
     }
 
@@ -329,7 +336,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
             Some((name, _, template, _)) if name != sym::rustc_dummy =>
                 check_builtin_attribute(self.parse_sess, attr, name, template),
-            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
+            _ => if let Some(TokenTree::Token(token)) =
+                    attr.get_normal_item().tokens.trees().next() {
                 if token == token::Eq {
                     // All key-value attributes are restricted to meta-item syntax.
                     attr.parse_meta(self.parse_sess).map_err(|mut err| err.emit()).ok();
@@ -372,7 +380,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_item(&mut self, i: &'a ast::Item) {
         match i.kind {
             ast::ItemKind::ForeignMod(ref foreign_module) => {
-                self.check_abi(foreign_module.abi, i.span);
+                self.check_abi(foreign_module.abi);
             }
 
             ast::ItemKind::Fn(..) => {
@@ -502,7 +510,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
         match ty.kind {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_abi(bare_fn_ty.abi, ty.span);
+                self.check_abi(bare_fn_ty.abi);
             }
             ast::TyKind::Never => {
                 gate_feature_post!(&self, never_type, ty.span,
@@ -596,7 +604,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             // Stability of const fn methods are covered in
             // `visit_trait_item` and `visit_impl_item` below; this is
             // because default methods don't pass through this point.
-            self.check_abi(header.abi, span);
+            self.check_abi(header.abi);
         }
 
         if fn_decl.c_variadic() {
@@ -630,7 +638,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match ti.kind {
             ast::TraitItemKind::Method(ref sig, ref block) => {
                 if block.is_none() {
-                    self.check_abi(sig.header.abi, ti.span);
+                    self.check_abi(sig.header.abi);
                 }
                 if sig.decl.c_variadic() {
                     gate_feature_post!(&self, c_variadic, ti.span,
@@ -862,18 +870,17 @@ pub fn check_crate(krate: &ast::Crate,
     maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
     let mut visitor = PostExpansionVisitor { parse_sess, features };
 
+    let spans = parse_sess.gated_spans.spans.borrow();
     macro_rules! gate_all {
-        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
-        ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*parse_sess.gated_spans.$spans.borrow() {
+        ($gate:ident, $msg:literal) => {
+            for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                 gate_feature!(&visitor, $gate, *span, $msg);
             }
         }
     }
-
     gate_all!(let_chains, "`let` expressions in this position are experimental");
     gate_all!(async_closure, "async closures are unstable");
-    gate_all!(yields, generators, "yield syntax is experimental");
+    gate_all!(generators, "yield syntax is experimental");
     gate_all!(or_patterns, "or-patterns syntax is experimental");
     gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");
 
@@ -884,7 +891,7 @@ pub fn check_crate(krate: &ast::Crate,
             // FIXME(eddyb) do something more useful than always
             // disabling these uses of early feature-gatings.
             if false {
-                for span in &*parse_sess.gated_spans.$gate.borrow() {
+                for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                     gate_feature!(&visitor, $gate, *span, $msg);
                 }
             }
@@ -901,7 +908,6 @@ pub fn check_crate(krate: &ast::Crate,
     gate_all!(try_blocks, "`try` blocks are unstable");
     gate_all!(label_break_value, "labels on blocks are unstable");
     gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
-
     // To avoid noise about type ascription in common syntax errors,
     // only emit if it is the *only* error. (Also check it last.)
     if parse_sess.span_diagnostic.err_count() == 0 {
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 2c29e1ebf14..c7b931a6f70 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -99,6 +99,9 @@ declare_features! (
     /// + `__register_diagnostic`
     /// +`__build_diagnostic_array`
     (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
+    /// Allows using `#[on_unimplemented(..)]` on traits.
+    /// (Moved to `rustc_attrs`.)
+    (removed, on_unimplemented, "1.40.0", None, None, None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 7be6e6c7e18..1b17de529c4 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -85,7 +85,10 @@ pub mod diagnostics {
 pub mod error_codes;
 
 pub mod util {
+    crate mod classify;
+    pub mod comments;
     pub mod lev_distance;
+    crate mod literal;
     pub mod node_count;
     pub mod parser;
     pub mod map_in_place;
@@ -107,6 +110,7 @@ pub mod show_span;
 pub use syntax_pos::edition;
 pub use syntax_pos::symbol;
 pub mod sess;
+pub mod token;
 pub mod tokenstream;
 pub mod visit;
 
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 60ee17d09b7..0c90652526d 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -9,7 +9,7 @@
 
 use crate::ast::*;
 use crate::source_map::{Spanned, respan};
-use crate::parse::token::{self, Token};
+use crate::token::{self, Token};
 use crate::ptr::P;
 use crate::ThinVec;
 use crate::tokenstream::*;
@@ -550,10 +550,14 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
 }
 
 pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
-    let Attribute { item: AttrItem { path, tokens }, id: _, style: _, is_sugared_doc: _, span }
-        = attr;
-    vis.visit_path(path);
-    vis.visit_tts(tokens);
+    let Attribute { kind, id: _, style: _, span } = attr;
+    match kind {
+        AttrKind::Normal(AttrItem { path, tokens }) => {
+            vis.visit_path(path);
+            vis.visit_tts(tokens);
+        }
+        AttrKind::DocComment(_) => {}
+    }
     vis.visit_span(span);
 }
 
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index e2a7ea28b9b..b1b7b08c78a 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,7 +1,7 @@
-use crate::parse::token::{self, Token, TokenKind};
+use crate::token::{self, Token, TokenKind};
 use crate::sess::ParseSess;
 use crate::symbol::{sym, Symbol};
-use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
+use crate::util::comments;
 
 use errors::{FatalError, DiagnosticBuilder};
 use syntax_pos::{BytePos, Pos, Span};
@@ -16,9 +16,10 @@ use log::debug;
 #[cfg(test)]
 mod tests;
 
-pub mod comments;
 mod tokentrees;
 mod unicode_chars;
+mod unescape_error_reporting;
+use unescape_error_reporting::{emit_unescape_error, push_escaped_char};
 
 #[derive(Clone, Debug)]
 pub struct UnmatchedBrace {
@@ -178,7 +179,7 @@ impl<'a> StringReader<'a> {
             rustc_lexer::TokenKind::LineComment => {
                 let string = self.str_from(start);
                 // comments with only more "/"s are not doc comments
-                let tok = if is_doc_comment(string) {
+                let tok = if comments::is_line_doc_comment(string) {
                     self.forbid_bare_cr(start, string, "bare CR not allowed in doc-comment");
                     token::DocComment(Symbol::intern(string))
                 } else {
@@ -191,7 +192,7 @@ impl<'a> StringReader<'a> {
                 let string = self.str_from(start);
                 // block comments starting with "/**" or "/*!" are doc-comments
                 // but comments with only "*"s between two "/"s are not
-                let is_doc_comment = is_block_doc_comment(string);
+                let is_doc_comment = comments::is_block_doc_comment(string);
 
                 if !terminated {
                     let msg = if is_doc_comment {
@@ -642,18 +643,3 @@ impl<'a> StringReader<'a> {
         }
     }
 }
-
-fn is_doc_comment(s: &str) -> bool {
-    let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/') ||
-              s.starts_with("//!");
-    debug!("is {:?} a doc comment? {}", s, res);
-    res
-}
-
-fn is_block_doc_comment(s: &str) -> bool {
-    // Prevent `/**/` from being parsed as a doc comment
-    let res = ((s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*') ||
-               s.starts_with("/*!")) && s.len() >= 5;
-    debug!("is {:?} a doc comment? {}", s, res);
-    res
-}
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index de301b1fc49..baa6fb59537 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -2,7 +2,8 @@ use super::*;
 
 use crate::symbol::Symbol;
 use crate::source_map::{SourceMap, FilePathMapping};
-use crate::parse::token;
+use crate::token;
+use crate::util::comments::is_doc_comment;
 use crate::with_default_globals;
 
 use errors::{Handler, emitter::EmitterWriter};
diff --git a/src/libsyntax/parse/lexer/tokentrees.rs b/src/libsyntax/parse/lexer/tokentrees.rs
index de8ac2c71e8..2b056434d4d 100644
--- a/src/libsyntax/parse/lexer/tokentrees.rs
+++ b/src/libsyntax/parse/lexer/tokentrees.rs
@@ -4,10 +4,11 @@ use syntax_pos::Span;
 use super::{StringReader, UnmatchedBrace};
 
 use crate::print::pprust::token_to_string;
-use crate::parse::token::{self, Token};
-use crate::parse::PResult;
+use crate::token::{self, Token};
 use crate::tokenstream::{DelimSpan, IsJoint::{self, *}, TokenStream, TokenTree, TreeAndJoint};
 
+use errors::PResult;
+
 impl<'a> StringReader<'a> {
     crate fn into_token_trees(self) -> (PResult<'a, TokenStream>, Vec<UnmatchedBrace>) {
         let mut tt_reader = TokenTreesReader {
diff --git a/src/libsyntax/parse/unescape_error_reporting.rs b/src/libsyntax/parse/lexer/unescape_error_reporting.rs
index 5565015179c..5565015179c 100644
--- a/src/libsyntax/parse/unescape_error_reporting.rs
+++ b/src/libsyntax/parse/lexer/unescape_error_reporting.rs
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index 525b4215aff..6eb995b61d3 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -4,7 +4,7 @@
 use super::StringReader;
 use errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::{BytePos, Pos, Span, symbol::kw};
-use crate::parse::token;
+use crate::token;
 
 #[rustfmt::skip] // for line breaks
 const UNICODE_ARRAY: &[(char, &str, char)] = &[
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 59f4a4d22d6..b54f4862f12 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -2,14 +2,12 @@
 
 use crate::ast;
 use crate::parse::parser::{Parser, emit_unclosed_delims, make_unclosed_delims_error};
-use crate::parse::token::Nonterminal;
+use crate::token::{self, Nonterminal};
 use crate::tokenstream::{self, TokenStream, TokenTree};
 use crate::print::pprust;
 use crate::sess::ParseSess;
 
-use errors::{FatalError, Level, Diagnostic, DiagnosticBuilder};
-#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert_size;
+use errors::{PResult, FatalError, Level, Diagnostic};
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{Span, SourceFile, FileName};
 
@@ -25,18 +23,6 @@ mod tests;
 #[macro_use]
 pub mod parser;
 pub mod lexer;
-pub mod token;
-
-crate mod classify;
-crate mod literal;
-crate mod unescape_error_reporting;
-
-pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
-
-// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
-// (See also the comment on `DiagnosticBuilderInner`.)
-#[cfg(target_arch = "x86_64")]
-static_assert_size!(PResult<'_, bool>, 16);
 
 #[derive(Clone)]
 pub struct Directory<'a> {
@@ -287,7 +273,7 @@ pub fn parse_in_attr<'a, T>(
 ) -> PResult<'a, T> {
     let mut parser = Parser::new(
         sess,
-        attr.tokens.clone(),
+        attr.get_normal_item().tokens.clone(),
         None,
         false,
         false,
@@ -393,18 +379,22 @@ fn prepend_attrs(
 
         let source = pprust::attribute_to_string(attr);
         let macro_filename = FileName::macro_expansion_source_code(&source);
-        if attr.is_sugared_doc {
-            let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
-            builder.push(stream);
-            continue
-        }
+
+        let item = match attr.kind {
+            ast::AttrKind::Normal(ref item) => item,
+            ast::AttrKind::DocComment(_) => {
+                let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
+                builder.push(stream);
+                continue
+            }
+        };
 
         // synthesize # [ $path $tokens ] manually here
         let mut brackets = tokenstream::TokenStreamBuilder::new();
 
         // For simple paths, push the identifier directly
-        if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() {
-            let ident = attr.path.segments[0].ident;
+        if item.path.segments.len() == 1 && item.path.segments[0].args.is_none() {
+            let ident = item.path.segments[0].ident;
             let token = token::Ident(ident.name, ident.as_str().starts_with("r#"));
             brackets.push(tokenstream::TokenTree::token(token, ident.span));
 
@@ -415,7 +405,7 @@ fn prepend_attrs(
             brackets.push(stream);
         }
 
-        brackets.push(attr.tokens.clone());
+        brackets.push(item.tokens.clone());
 
         // The span we list here for `#` and for `[ ... ]` are both wrong in
         // that it encompasses more than each token, but it hopefully is "good
diff --git a/src/libsyntax/parse/parser/attr.rs b/src/libsyntax/parse/parser/attr.rs
index 188a144cac9..31f0a02a483 100644
--- a/src/libsyntax/parse/parser/attr.rs
+++ b/src/libsyntax/parse/parser/attr.rs
@@ -1,10 +1,14 @@
-use super::{SeqSep, PResult, Parser, TokenType, PathStyle};
+use super::{SeqSep, Parser, TokenType, PathStyle};
 use crate::attr;
 use crate::ast;
-use crate::parse::token::{self, Nonterminal, DelimToken};
+use crate::util::comments;
+use crate::token::{self, Nonterminal, DelimToken};
 use crate::tokenstream::{TokenStream, TokenTree};
 use crate::source_map::Span;
 
+use syntax_pos::Symbol;
+use errors::PResult;
+
 use log::debug;
 
 #[derive(Debug)]
@@ -43,7 +47,7 @@ impl<'a> Parser<'a> {
                     just_parsed_doc_comment = false;
                 }
                 token::DocComment(s) => {
-                    let attr = attr::mk_sugared_doc_attr(s, self.token.span);
+                    let attr = self.mk_doc_comment(s);
                     if attr.style != ast::AttrStyle::Outer {
                         let mut err = self.fatal("expected outer doc comment");
                         err.note("inner doc comments like this (starting with \
@@ -60,6 +64,11 @@ impl<'a> Parser<'a> {
         Ok(attrs)
     }
 
+    fn mk_doc_comment(&self, s: Symbol) -> ast::Attribute {
+        let style = comments::doc_comment_style(&s.as_str());
+        attr::mk_doc_comment(style, s, self.token.span)
+    }
+
     /// Matches `attribute = # ! [ meta_item ]`.
     ///
     /// If `permit_inner` is `true`, then a leading `!` indicates an inner
@@ -150,10 +159,9 @@ impl<'a> Parser<'a> {
         };
 
         Ok(ast::Attribute {
-            item,
+            kind: ast::AttrKind::Normal(item),
             id: attr::mk_attr_id(),
             style,
-            is_sugared_doc: false,
             span,
         })
     }
@@ -229,7 +237,7 @@ impl<'a> Parser<'a> {
                 }
                 token::DocComment(s) => {
                     // We need to get the position of this token before we bump.
-                    let attr = attr::mk_sugared_doc_attr(s, self.token.span);
+                    let attr = self.mk_doc_comment(s);
                     if attr.style == ast::AttrStyle::Inner {
                         attrs.push(attr);
                         self.bump();
diff --git a/src/libsyntax/parse/parser/diagnostics.rs b/src/libsyntax/parse/parser/diagnostics.rs
index 49a517a5c44..26d7f48025e 100644
--- a/src/libsyntax/parse/parser/diagnostics.rs
+++ b/src/libsyntax/parse/parser/diagnostics.rs
@@ -1,18 +1,16 @@
-use super::{
-    BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType,
-    SeqSep, PResult, Parser
-};
+use super::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType, SeqSep, Parser};
 use crate::ast::{
     self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
     Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
 };
-use crate::parse::token::{self, TokenKind, token_can_begin_expr};
+use crate::token::{self, TokenKind, token_can_begin_expr};
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::symbol::{kw, sym};
 use crate::ThinVec;
 use crate::util::parser::AssocOp;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralize};
+
+use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, pluralize};
 use rustc_data_structures::fx::FxHashSet;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
 use log::{debug, trace};
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 97b1092452a..800074035ce 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1,25 +1,24 @@
-use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode};
+use super::{Parser, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode};
 use super::{SemiColonMode, SeqSep, TokenExpectType};
 use super::pat::{GateOr, PARAM_EXPECTED};
 use super::diagnostics::Error;
 
-use crate::parse::literal::LitError;
-
 use crate::ast::{
     self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode,
     Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind,
     FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit,
 };
 use crate::maybe_recover_from_interpolated_ty_qpath;
-use crate::parse::classify;
-use crate::parse::token::{self, Token, TokenKind};
+use crate::token::{self, Token, TokenKind};
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::source_map::{self, Span};
-use crate::symbol::{kw, sym};
+use crate::util::classify;
+use crate::util::literal::LitError;
 use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
 
-use errors::Applicability;
+use errors::{PResult, Applicability};
+use syntax_pos::symbol::{kw, sym};
 use syntax_pos::Symbol;
 use std::mem;
 use rustc_data_structures::thin_vec::ThinVec;
@@ -252,7 +251,7 @@ impl<'a> Parser<'a> {
                 self.last_type_ascription = Some((self.prev_span, maybe_path));
 
                 lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
-                self.sess.gated_spans.type_ascription.borrow_mut().push(lhs.span);
+                self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
                 continue
             } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
                 // If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
@@ -455,7 +454,7 @@ impl<'a> Parser<'a> {
                 let e = self.parse_prefix_expr(None);
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 let span = lo.to(span);
-                self.sess.gated_spans.box_syntax.borrow_mut().push(span);
+                self.sess.gated_spans.gate(sym::box_syntax, span);
                 (span, ExprKind::Box(e))
             }
             token::Ident(..) if self.token.is_ident_named(sym::not) => {
@@ -1045,7 +1044,7 @@ impl<'a> Parser<'a> {
                     }
 
                     let span = lo.to(hi);
-                    self.sess.gated_spans.yields.borrow_mut().push(span);
+                    self.sess.gated_spans.gate(sym::generators, span);
                 } else if self.eat_keyword(kw::Let) {
                     return self.parse_let_expr(attrs);
                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
@@ -1116,7 +1115,11 @@ impl<'a> Parser<'a> {
                 Err(self.span_fatal(token.span, &msg))
             }
             Err(err) => {
-                let (lit, span) = (token.expect_lit(), token.span);
+                let span = token.span;
+                let lit = match token.kind {
+                    token::Literal(lit) => lit,
+                    _ => unreachable!(),
+                };
                 self.bump();
                 self.error_literal_from_token(err, lit, span);
                 // Pack possible quotes and prefixes from the original literal into
@@ -1264,7 +1267,7 @@ impl<'a> Parser<'a> {
         outer_attrs: ThinVec<Attribute>,
     ) -> PResult<'a, P<Expr>> {
         if let Some(label) = opt_label {
-            self.sess.gated_spans.label_break_value.borrow_mut().push(label.ident.span);
+            self.sess.gated_spans.gate(sym::label_break_value, label.ident.span);
         }
 
         self.expect(&token::OpenDelim(token::Brace))?;
@@ -1293,7 +1296,7 @@ impl<'a> Parser<'a> {
         };
         if asyncness.is_async() {
             // Feature-gate `async ||` closures.
-            self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.gate(sym::async_closure, self.prev_span);
         }
 
         let capture_clause = self.parse_capture_clause();
@@ -1415,8 +1418,7 @@ impl<'a> Parser<'a> {
 
         if let ExprKind::Let(..) = cond.kind {
             // Remove the last feature gating of a `let` expression since it's stable.
-            let last = self.sess.gated_spans.let_chains.borrow_mut().pop();
-            debug_assert_eq!(cond.span, last.unwrap());
+            self.sess.gated_spans.ungate_last(sym::let_chains, cond.span);
         }
 
         Ok(cond)
@@ -1433,7 +1435,7 @@ impl<'a> Parser<'a> {
             |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
         )?;
         let span = lo.to(expr.span);
-        self.sess.gated_spans.let_chains.borrow_mut().push(span);
+        self.sess.gated_spans.gate(sym::let_chains, span);
         Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
     }
 
@@ -1654,7 +1656,7 @@ impl<'a> Parser<'a> {
             Err(error)
         } else {
             let span = span_lo.to(body.span);
-            self.sess.gated_spans.try_blocks.borrow_mut().push(span);
+            self.sess.gated_spans.gate(sym::try_blocks, span);
             Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
         }
     }
diff --git a/src/libsyntax/parse/parser/generics.rs b/src/libsyntax/parse/parser/generics.rs
index 51caae69c86..ae9ecd8fe39 100644
--- a/src/libsyntax/parse/parser/generics.rs
+++ b/src/libsyntax/parse/parser/generics.rs
@@ -1,9 +1,12 @@
-use super::{Parser, PResult};
+use super::Parser;
 
 use crate::ast::{self, WhereClause, GenericParam, GenericParamKind, GenericBounds, Attribute};
-use crate::parse::token;
+use crate::token;
 use crate::source_map::DUMMY_SP;
-use crate::symbol::kw;
+
+use syntax_pos::symbol::{kw, sym};
+
+use errors::PResult;
 
 impl<'a> Parser<'a> {
     /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`.
@@ -62,7 +65,7 @@ impl<'a> Parser<'a> {
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
 
-        self.sess.gated_spans.const_generics.borrow_mut().push(lo.to(self.prev_span));
+        self.sess.gated_spans.gate(sym::const_generics, lo.to(self.prev_span));
 
         Ok(GenericParam {
             ident,
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 5b60e7e6dba..3c618d75d34 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -1,10 +1,10 @@
-use super::{Parser, PResult, PathStyle};
+use super::{Parser, PathStyle};
 use super::diagnostics::{Error, dummy_arg, ConsumeClosingDelim};
 
 use crate::maybe_whole;
 use crate::ptr::P;
-use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle, AnonConst, Item, ItemKind};
-use crate::ast::{ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
+use crate::ast::{self, Abi, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
+use crate::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
 use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
 use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
 use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
@@ -17,8 +17,7 @@ use crate::ThinVec;
 
 use log::debug;
 use std::mem;
-use rustc_target::spec::abi::Abi;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
+use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
 use syntax_pos::BytePos;
 
 /// Whether the type alias or associated type is a concrete type or an opaque type.
@@ -111,7 +110,7 @@ impl<'a> Parser<'a> {
                 return Ok(Some(self.parse_item_extern_crate(lo, vis, attrs)?));
             }
 
-            let opt_abi = self.parse_opt_abi()?;
+            let abi = self.parse_opt_abi()?;
 
             if self.eat_keyword(kw::Fn) {
                 // EXTERN FUNCTION ITEM
@@ -120,12 +119,12 @@ impl<'a> Parser<'a> {
                     unsafety: Unsafety::Normal,
                     asyncness: respan(fn_span, IsAsync::NotAsync),
                     constness: respan(fn_span, Constness::NotConst),
-                    abi: opt_abi.unwrap_or(Abi::C),
+                    abi,
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             } else if self.check(&token::OpenDelim(token::Brace)) {
                 return Ok(Some(
-                    self.parse_item_foreign_mod(lo, opt_abi, vis, attrs, extern_sp)?,
+                    self.parse_item_foreign_mod(lo, abi, vis, attrs, extern_sp)?,
                 ));
             }
 
@@ -147,9 +146,7 @@ impl<'a> Parser<'a> {
                 let unsafety = self.parse_unsafety();
 
                 if self.check_keyword(kw::Extern) {
-                    self.sess.gated_spans.const_extern_fn.borrow_mut().push(
-                        lo.to(self.token.span)
-                    );
+                    self.sess.gated_spans.gate(sym::const_extern_fn, lo.to(self.token.span));
                 }
                 let abi = self.parse_extern_abi()?;
                 self.bump(); // `fn`
@@ -201,7 +198,7 @@ impl<'a> Parser<'a> {
                     unsafety,
                     asyncness,
                     constness: respan(fn_span, Constness::NotConst),
-                    abi: Abi::Rust,
+                    abi: Abi::new(sym::Rust, fn_span),
                 };
                 return self.parse_item_fn(lo, vis, attrs, header);
             }
@@ -238,7 +235,7 @@ impl<'a> Parser<'a> {
                 unsafety: Unsafety::Normal,
                 asyncness: respan(fn_span, IsAsync::NotAsync),
                 constness: respan(fn_span, Constness::NotConst),
-                abi: Abi::Rust,
+                abi: Abi::new(sym::Rust, fn_span),
             };
             return self.parse_item_fn(lo, vis, attrs, header);
         }
@@ -483,12 +480,14 @@ impl<'a> Parser<'a> {
     /// Emits an expected-item-after-attributes error.
     fn expected_item_err(&mut self, attrs: &[Attribute]) -> PResult<'a,  ()> {
         let message = match attrs.last() {
-            Some(&Attribute { is_sugared_doc: true, .. }) => "expected item after doc comment",
-            _ => "expected item after attributes",
+            Some(&Attribute { kind: AttrKind::DocComment(_), .. }) =>
+                "expected item after doc comment",
+            _ =>
+                "expected item after attributes",
         };
 
         let mut err = self.diagnostic().struct_span_err(self.prev_span, message);
-        if attrs.last().unwrap().is_sugared_doc {
+        if attrs.last().unwrap().is_doc_comment() {
             err.span_label(self.prev_span, "this doc comment doesn't document anything");
         }
         Err(err)
@@ -830,7 +829,7 @@ impl<'a> Parser<'a> {
                     .emit();
             }
 
-            self.sess.gated_spans.trait_alias.borrow_mut().push(whole_span);
+            self.sess.gated_spans.gate(sym::trait_alias, whole_span);
 
             Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
         } else {
@@ -1113,15 +1112,13 @@ impl<'a> Parser<'a> {
     fn parse_item_foreign_mod(
         &mut self,
         lo: Span,
-        opt_abi: Option<Abi>,
+        abi: Abi,
         visibility: Visibility,
         mut attrs: Vec<Attribute>,
         extern_sp: Span,
     ) -> PResult<'a, P<Item>> {
         self.expect(&token::OpenDelim(token::Brace))?;
 
-        let abi = opt_abi.unwrap_or(Abi::C);
-
         attrs.extend(self.parse_inner_attributes()?);
 
         let mut foreign_items = vec![];
@@ -1712,7 +1709,7 @@ impl<'a> Parser<'a> {
         let span = lo.to(self.prev_span);
 
         if !def.legacy {
-            self.sess.gated_spans.decl_macro.borrow_mut().push(span);
+            self.sess.gated_spans.gate(sym::decl_macro, span);
         }
 
         Ok(Some(self.mk_item(span, ident, ItemKind::MacroDef(def), vis.clone(), attrs.to_vec())))
@@ -1799,7 +1796,7 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, Option<P<Item>>> {
         let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
             is_self_allowed: false,
-            allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe,
+            allow_c_variadic: header.abi.symbol == sym::C && header.unsafety == Unsafety::Unsafe,
             is_name_required: |_| true,
         })?;
         let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
@@ -1928,7 +1925,7 @@ impl<'a> Parser<'a> {
         let asyncness = respan(self.prev_span, asyncness);
         let unsafety = self.parse_unsafety();
         let (constness, unsafety, abi) = if is_const_fn {
-            (respan(const_span, Constness::Const), unsafety, Abi::Rust)
+            (respan(const_span, Constness::Const), unsafety, Abi::default())
         } else {
             let abi = self.parse_extern_abi()?;
             (respan(self.prev_span, Constness::NotConst), unsafety, abi)
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser/mod.rs
index 7652c730e51..455f4172f5f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser/mod.rs
@@ -12,13 +12,13 @@ mod diagnostics;
 use diagnostics::Error;
 
 use crate::ast::{
-    self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
+    self, Abi, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
     IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
 };
-use crate::parse::{PResult, Directory, DirectoryOwnership};
+use crate::parse::{Directory, DirectoryOwnership};
 use crate::parse::lexer::UnmatchedBrace;
-use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
-use crate::parse::token::{self, Token, TokenKind, DelimToken};
+use crate::util::comments::{doc_comment_style, strip_doc_comment_decoration};
+use crate::token::{self, Token, TokenKind, DelimToken};
 use crate::print::pprust;
 use crate::ptr::P;
 use crate::sess::ParseSess;
@@ -27,8 +27,7 @@ use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
 use crate::ThinVec;
 
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
-use rustc_target::spec::abi::{self, Abi};
+use errors::{PResult, Applicability, DiagnosticBuilder, DiagnosticId, FatalError};
 use syntax_pos::{Span, BytePos, DUMMY_SP, FileName};
 use log::debug;
 
@@ -1121,7 +1120,7 @@ impl<'a> Parser<'a> {
         self.expected_tokens.push(TokenType::Keyword(kw::Crate));
         if self.is_crate_vis() {
             self.bump(); // `crate`
-            self.sess.gated_spans.crate_visibility_modifier.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.gate(sym::crate_visibility_modifier, self.prev_span);
             return Ok(respan(self.prev_span, VisibilityKind::Crate(CrateSugar::JustCrate)));
         }
 
@@ -1206,48 +1205,41 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
-    /// Parses `extern` followed by an optional ABI string, or nothing.
+    /// Parses `extern string_literal?`.
+    /// If `extern` is not found, the Rust ABI is used.
+    /// If `extern` is found and a `string_literal` does not follow, the C ABI is used.
     fn parse_extern_abi(&mut self) -> PResult<'a, Abi> {
-        if self.eat_keyword(kw::Extern) {
-            Ok(self.parse_opt_abi()?.unwrap_or(Abi::C))
+        Ok(if self.eat_keyword(kw::Extern) {
+            self.parse_opt_abi()?
         } else {
-            Ok(Abi::Rust)
-        }
+            Abi::default()
+        })
     }
 
-    /// Parses a string as an ABI spec on an extern type or module. Consumes
-    /// the `extern` keyword, if one is found.
-    fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {
-        match self.token.kind {
-            token::Literal(token::Lit { kind: token::Str, symbol, suffix }) |
-            token::Literal(token::Lit { kind: token::StrRaw(..), symbol, suffix }) => {
-                self.expect_no_suffix(self.token.span, "an ABI spec", suffix);
-                self.bump();
-                match abi::lookup(&symbol.as_str()) {
-                    Some(abi) => Ok(Some(abi)),
-                    None => {
-                        self.error_on_invalid_abi(symbol);
-                        Ok(None)
-                    }
+    /// Parses a string literal as an ABI spec.
+    /// If one is not found, the "C" ABI is used.
+    fn parse_opt_abi(&mut self) -> PResult<'a, Abi> {
+        let span = if self.token.can_begin_literal_or_bool() {
+            let ast::Lit { span, kind, .. } = self.parse_lit()?;
+            match kind {
+                ast::LitKind::Str(symbol, _) => return Ok(Abi::new(symbol, span)),
+                ast::LitKind::Err(_) => {}
+                _ => {
+                    self.struct_span_err(span, "non-string ABI literal")
+                        .span_suggestion(
+                            span,
+                            "specify the ABI with a string literal",
+                            "\"C\"".to_string(),
+                            Applicability::MaybeIncorrect,
+                        )
+                        .emit();
                 }
             }
-            _ => Ok(None),
-        }
-    }
-
-    /// Emit an error where `symbol` is an invalid ABI.
-    fn error_on_invalid_abi(&self, symbol: Symbol) {
-        let prev_span = self.prev_span;
-        struct_span_err!(
-            self.sess.span_diagnostic,
-            prev_span,
-            E0703,
-            "invalid ABI: found `{}`",
-            symbol
-        )
-        .span_label(prev_span, "invalid ABI")
-        .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
-        .emit();
+            span
+        } else {
+            self.prev_span
+        };
+        Ok(Abi::new(sym::C, span))
     }
 
     /// We are parsing `async fn`. If we are on Rust 2015, emit an error.
diff --git a/src/libsyntax/parse/parser/module.rs b/src/libsyntax/parse/parser/module.rs
index 958cdae9492..3e5974c2eee 100644
--- a/src/libsyntax/parse/parser/module.rs
+++ b/src/libsyntax/parse/parser/module.rs
@@ -1,14 +1,16 @@
-use super::{Parser, PResult};
+use super::Parser;
 use super::item::ItemInfo;
 use super::diagnostics::Error;
 
 use crate::attr;
 use crate::ast::{self, Ident, Attribute, ItemKind, Mod, Crate};
 use crate::parse::{new_sub_parser_from_file, DirectoryOwnership};
-use crate::parse::token::{self, TokenKind};
+use crate::token::{self, TokenKind};
 use crate::source_map::{SourceMap, Span, DUMMY_SP, FileName};
 use crate::symbol::sym;
 
+use errors::PResult;
+
 use std::path::{self, Path, PathBuf};
 
 /// Information about the path to a module.
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 969d5dd8374..f347300da71 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -1,17 +1,16 @@
-use super::{Parser, PResult, PathStyle};
+use super::{Parser, PathStyle};
 
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use crate::ptr::P;
 use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
 use crate::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind};
 use crate::mut_visit::{noop_visit_pat, noop_visit_mac, MutVisitor};
-use crate::parse::token::{self};
+use crate::token;
 use crate::print::pprust;
 use crate::source_map::{respan, Span, Spanned};
-use crate::symbol::kw;
 use crate::ThinVec;
-
-use errors::{Applicability, DiagnosticBuilder};
+use syntax_pos::symbol::{kw, sym};
+use errors::{PResult, Applicability, DiagnosticBuilder};
 
 type Expected = Option<&'static str>;
 
@@ -52,11 +51,8 @@ impl<'a> Parser<'a> {
         // and no other gated or-pattern has been parsed thus far,
         // then we should really gate the leading `|`.
         // This complicated procedure is done purely for diagnostics UX.
-        if gated_leading_vert {
-            let mut or_pattern_spans = self.sess.gated_spans.or_patterns.borrow_mut();
-            if or_pattern_spans.is_empty() {
-                or_pattern_spans.push(leading_vert_span);
-            }
+        if gated_leading_vert && self.sess.gated_spans.is_ungated(sym::or_patterns) {
+            self.sess.gated_spans.gate(sym::or_patterns, leading_vert_span);
         }
 
         Ok(pat)
@@ -117,7 +113,7 @@ impl<'a> Parser<'a> {
 
         // Feature gate the or-pattern if instructed:
         if gate_or == GateOr::Yes {
-            self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
+            self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
         }
 
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
@@ -325,7 +321,7 @@ impl<'a> Parser<'a> {
             } else if self.eat_keyword(kw::Box) {
                 // Parse `box pat`
                 let pat = self.parse_pat_with_range_pat(false, None)?;
-                self.sess.gated_spans.box_patterns.borrow_mut().push(lo.to(self.prev_span));
+                self.sess.gated_spans.gate(sym::box_patterns, lo.to(self.prev_span));
                 PatKind::Box(pat)
             } else if self.can_be_ident_pat() {
                 // Parse `ident @ pat`
@@ -612,7 +608,7 @@ impl<'a> Parser<'a> {
     }
 
     fn excluded_range_end(&self, span: Span) -> RangeEnd {
-        self.sess.gated_spans.exclusive_range_pattern.borrow_mut().push(span);
+        self.sess.gated_spans.gate(sym::exclusive_range_pattern, span);
         RangeEnd::Excluded
     }
 
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index f9944e36e2f..9ceb3ba1eb4 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -1,15 +1,15 @@
-use super::{Parser, PResult, TokenType};
+use super::{Parser, TokenType};
 
 use crate::{maybe_whole, ThinVec};
 use crate::ast::{self, QSelf, Path, PathSegment, Ident, ParenthesizedArgs, AngleBracketedArgs};
 use crate::ast::{AnonConst, GenericArg, AssocTyConstraint, AssocTyConstraintKind, BlockCheckMode};
-use crate::parse::token::{self, Token};
+use crate::token::{self, Token};
 use crate::source_map::{Span, BytePos};
-use crate::symbol::kw;
+use syntax_pos::symbol::{kw, sym};
 
 use std::mem;
 use log::debug;
-use errors::{Applicability, pluralize};
+use errors::{PResult, Applicability, pluralize};
 
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -426,7 +426,7 @@ impl<'a> Parser<'a> {
 
                 // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
                 if let AssocTyConstraintKind::Bound { .. } = kind {
-                    self.sess.gated_spans.associated_type_bounds.borrow_mut().push(span);
+                    self.sess.gated_spans.gate(sym::associated_type_bounds, span);
                 }
 
                 constraints.push(AssocTyConstraint {
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index 12c530f3cbb..30e47b7a0b2 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -1,4 +1,4 @@
-use super::{Parser, PResult, Restrictions, PrevTokenKind, SemiColonMode, BlockMode};
+use super::{Parser, Restrictions, PrevTokenKind, SemiColonMode, BlockMode};
 use super::expr::LhsExpr;
 use super::path::PathStyle;
 use super::pat::GateOr;
@@ -8,13 +8,14 @@ use crate::ptr::P;
 use crate::{maybe_whole, ThinVec};
 use crate::ast::{self, DUMMY_NODE_ID, Stmt, StmtKind, Local, Block, BlockCheckMode, Expr, ExprKind};
 use crate::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac, MacDelimiter};
-use crate::parse::{classify, DirectoryOwnership};
-use crate::parse::token;
+use crate::parse::DirectoryOwnership;
+use crate::util::classify;
+use crate::token;
 use crate::source_map::{respan, Span};
 use crate::symbol::{kw, sym};
 
 use std::mem;
-use errors::Applicability;
+use errors::{PResult, Applicability};
 
 impl<'a> Parser<'a> {
     /// Parses a statement. This stops just before trailing semicolons on everything but items.
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index b770b90705c..a891634e611 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -1,4 +1,4 @@
-use super::{Parser, PResult, PathStyle, PrevTokenKind, TokenType};
+use super::{Parser, PathStyle, PrevTokenKind, TokenType};
 use super::item::ParamCfg;
 
 use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath};
@@ -6,11 +6,11 @@ use crate::ptr::P;
 use crate::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam, Lifetime, Ident};
 use crate::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef};
 use crate::ast::{Mutability, AnonConst, Mac};
-use crate::parse::token::{self, Token};
+use crate::token::{self, Token};
 use crate::source_map::Span;
 use crate::symbol::{kw};
 
-use errors::{Applicability, pluralize};
+use errors::{PResult, Applicability, pluralize};
 
 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
 /// `IDENT<<u8 as Trait>::AssocTy>`.
diff --git a/src/libsyntax/parse/tests.rs b/src/libsyntax/parse/tests.rs
index 3bdb9227b4e..27ca2b6472f 100644
--- a/src/libsyntax/parse/tests.rs
+++ b/src/libsyntax/parse/tests.rs
@@ -2,9 +2,9 @@ use super::*;
 
 use crate::ast::{self, Name, PatKind};
 use crate::attr::first_attr_value_str_by_name;
-use crate::parse::{ParseSess, PResult};
-use crate::parse::new_parser_from_source_str;
-use crate::parse::token::Token;
+use crate::sess::ParseSess;
+use crate::parse::{PResult, new_parser_from_source_str};
+use crate::token::Token;
 use crate::print::pprust::item_to_string;
 use crate::ptr::P;
 use crate::source_map::FilePathMapping;
@@ -246,7 +246,7 @@ let mut fflags: c_int = wb();
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
         let item = parse_item_from_source_str(name_2, source, &sess)
             .unwrap().unwrap();
-        let docs = item.attrs.iter().filter(|a| a.path == sym::doc)
+        let docs = item.attrs.iter().filter(|a| a.has_name(sym::doc))
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
         let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
         assert_eq!(&docs[..], b);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 74ab5c79019..4ca4bdeb046 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2,19 +2,18 @@ use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
 use crate::ast::{SelfKind, GenericBound, TraitBoundModifier};
 use crate::ast::{Attribute, MacDelimiter, GenericArg};
 use crate::util::parser::{self, AssocOp, Fixity};
+use crate::util::comments;
 use crate::attr;
 use crate::source_map::{self, SourceMap, Spanned};
-use crate::parse::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
-use crate::parse::lexer::comments;
-use crate::parse;
+use crate::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
 use crate::print::pp::{self, Breaks};
 use crate::print::pp::Breaks::{Consistent, Inconsistent};
 use crate::ptr::P;
+use crate::util::classify;
 use crate::sess::ParseSess;
 use crate::symbol::{kw, sym};
 use crate::tokenstream::{self, TokenStream, TokenTree};
 
-use rustc_target::spec::abi::{self, Abi};
 use syntax_pos::{self, BytePos};
 use syntax_pos::{FileName, Span};
 
@@ -622,16 +621,19 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             self.hardbreak_if_not_bol();
         }
         self.maybe_print_comment(attr.span.lo());
-        if attr.is_sugared_doc {
-            self.word(attr.value_str().unwrap().to_string());
-            self.hardbreak()
-        } else {
-            match attr.style {
-                ast::AttrStyle::Inner => self.word("#!["),
-                ast::AttrStyle::Outer => self.word("#["),
+        match attr.kind {
+            ast::AttrKind::Normal(ref item) => {
+                match attr.style {
+                    ast::AttrStyle::Inner => self.word("#!["),
+                    ast::AttrStyle::Outer => self.word("#["),
+                }
+                self.print_attr_item(&item, attr.span);
+                self.word("]");
+            }
+            ast::AttrKind::DocComment(comment) => {
+                self.word(comment.to_string());
+                self.hardbreak()
             }
-            self.print_attr_item(&attr.item, attr.span);
-            self.word("]");
         }
     }
 
@@ -1227,7 +1229,7 @@ impl<'a> State<'a> {
             }
             ast::ItemKind::ForeignMod(ref nmod) => {
                 self.head("extern");
-                self.word_nbsp(nmod.abi.to_string());
+                self.print_abi(nmod.abi);
                 self.bopen();
                 self.print_foreign_mod(nmod, &item.attrs);
                 self.bclose(item.span);
@@ -1657,7 +1659,7 @@ impl<'a> State<'a> {
             ast::StmtKind::Expr(ref expr) => {
                 self.space_if_not_bol();
                 self.print_expr_outer_attr_style(expr, false);
-                if parse::classify::expr_requires_semi_to_be_stmt(expr) {
+                if classify::expr_requires_semi_to_be_stmt(expr) {
                     self.s.word(";");
                 }
             }
@@ -2820,7 +2822,7 @@ impl<'a> State<'a> {
     }
 
     crate fn print_ty_fn(&mut self,
-                       abi: abi::Abi,
+                       abi: ast::Abi,
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
                        name: Option<ast::Ident>,
@@ -2881,14 +2883,18 @@ impl<'a> State<'a> {
         self.print_asyncness(header.asyncness.node);
         self.print_unsafety(header.unsafety);
 
-        if header.abi != Abi::Rust {
+        if header.abi.symbol != sym::Rust {
             self.word_nbsp("extern");
-            self.word_nbsp(header.abi.to_string());
+            self.print_abi(header.abi);
         }
 
         self.s.word("fn")
     }
 
+    fn print_abi(&mut self, abi: ast::Abi) {
+        self.word_nbsp(format!("\"{}\"", abi.symbol));
+    }
+
     crate fn print_unsafety(&mut self, s: ast::Unsafety) {
         match s {
             ast::Unsafety::Normal => {},
diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs
index faa70edbfa2..2c6dd0fb1c6 100644
--- a/src/libsyntax/print/pprust/tests.rs
+++ b/src/libsyntax/print/pprust/tests.rs
@@ -34,12 +34,7 @@ fn test_fun_to_string() {
         assert_eq!(
             fun_to_string(
                 &decl,
-                ast::FnHeader {
-                    unsafety: ast::Unsafety::Normal,
-                    constness: source_map::dummy_spanned(ast::Constness::NotConst),
-                    asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),
-                    abi: Abi::Rust,
-                },
+                ast::FnHeader::default(),
                 abba_ident,
                 &generics
             ),
diff --git a/src/libsyntax/sess.rs b/src/libsyntax/sess.rs
index 30f8c56a056..faad3e4af1e 100644
--- a/src/libsyntax/sess.rs
+++ b/src/libsyntax/sess.rs
@@ -19,39 +19,53 @@ use std::str;
 /// Collected spans during parsing for places where a certain feature was
 /// used and should be feature gated accordingly in `check_crate`.
 #[derive(Default)]
-crate struct GatedSpans {
-    /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
-    crate let_chains: Lock<Vec<Span>>,
-    /// Spans collected for gating `async_closure`, e.g. `async || ..`.
-    crate async_closure: Lock<Vec<Span>>,
-    /// Spans collected for gating `yield e?` expressions (`generators` gate).
-    crate yields: Lock<Vec<Span>>,
-    /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
-    crate or_patterns: Lock<Vec<Span>>,
-    /// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`.
-    crate const_extern_fn: Lock<Vec<Span>>,
-    /// Spans collected for gating `trait_alias`, e.g. `trait Foo = Ord + Eq;`.
-    pub trait_alias: Lock<Vec<Span>>,
-    /// Spans collected for gating `associated_type_bounds`, e.g. `Iterator<Item: Ord>`.
-    pub associated_type_bounds: Lock<Vec<Span>>,
-    /// Spans collected for gating `crate_visibility_modifier`, e.g. `crate fn`.
-    pub crate_visibility_modifier: Lock<Vec<Span>>,
-    /// Spans collected for gating `const_generics`, e.g. `const N: usize`.
-    pub const_generics: Lock<Vec<Span>>,
-    /// Spans collected for gating `decl_macro`, e.g. `macro m() {}`.
-    pub decl_macro: Lock<Vec<Span>>,
-    /// Spans collected for gating `box_patterns`, e.g. `box 0`.
-    pub box_patterns: Lock<Vec<Span>>,
-    /// Spans collected for gating `exclusive_range_pattern`, e.g. `0..2`.
-    pub exclusive_range_pattern: Lock<Vec<Span>>,
-    /// Spans collected for gating `try_blocks`, e.g. `try { a? + b? }`.
-    pub try_blocks: Lock<Vec<Span>>,
-    /// Spans collected for gating `label_break_value`, e.g. `'label: { ... }`.
-    pub label_break_value: Lock<Vec<Span>>,
-    /// Spans collected for gating `box_syntax`, e.g. `box $expr`.
-    pub box_syntax: Lock<Vec<Span>>,
-    /// Spans collected for gating `type_ascription`, e.g. `42: usize`.
-    pub type_ascription: Lock<Vec<Span>>,
+pub struct GatedSpans {
+    pub spans: Lock<FxHashMap<Symbol, Vec<Span>>>,
+}
+
+impl GatedSpans {
+    /// Feature gate the given `span` under the given `feature`
+    /// which is same `Symbol` used in `active.rs`.
+    pub fn gate(&self, feature: Symbol, span: Span) {
+        self.spans
+            .borrow_mut()
+            .entry(feature)
+            .or_default()
+            .push(span);
+    }
+
+    /// Ungate the last span under the given `feature`.
+    /// Panics if the given `span` wasn't the last one.
+    ///
+    /// Using this is discouraged unless you have a really good reason to.
+    pub fn ungate_last(&self, feature: Symbol, span: Span) {
+        let removed_span = self.spans
+            .borrow_mut()
+            .entry(feature)
+            .or_default()
+            .pop()
+            .unwrap();
+        debug_assert_eq!(span, removed_span);
+    }
+
+    /// Is the provided `feature` gate ungated currently?
+    ///
+    /// Using this is discouraged unless you have a really good reason to.
+    pub fn is_ungated(&self, feature: Symbol) -> bool {
+        self.spans
+            .borrow()
+            .get(&feature)
+            .map_or(true, |spans| spans.is_empty())
+    }
+
+    /// Prepend the given set of `spans` onto the set in `self`.
+    pub fn merge(&self, mut spans: FxHashMap<Symbol, Vec<Span>>) {
+        let mut inner = self.spans.borrow_mut();
+        for (gate, mut gate_spans) in inner.drain() {
+            spans.entry(gate).or_default().append(&mut gate_spans);
+        }
+        *inner = spans;
+    }
 }
 
 /// Info about a parsing session.
@@ -72,7 +86,7 @@ pub struct ParseSess {
     /// analysis.
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
     pub injected_crate_name: Once<Symbol>,
-    crate gated_spans: GatedSpans,
+    pub gated_spans: GatedSpans,
     /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
     pub reached_eof: Lock<bool>,
 }
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index e73c8b43bcc..ed457c3627f 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -1,5 +1,5 @@
 use crate::ast;
-use crate::parse::{PResult, source_file_to_stream};
+use crate::parse::source_file_to_stream;
 use crate::parse::new_parser_from_source_str;
 use crate::parse::parser::Parser;
 use crate::sess::ParseSess;
@@ -8,7 +8,7 @@ use crate::tokenstream::TokenStream;
 use crate::with_default_globals;
 
 use errors::emitter::EmitterWriter;
-use errors::Handler;
+use errors::{PResult, Handler};
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{BytePos, Span, MultiSpan};
 
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/token.rs
index 03e77b199cc..6f3da344ccf 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/token.rs
@@ -381,9 +381,7 @@ impl Token {
         match self.kind {
             OpenDelim(Brace) => true,
             Interpolated(ref nt) => match **nt {
-                NtExpr(..) => true,
-                NtBlock(..) => true,
-                NtLiteral(..) => true,
+                NtExpr(..) | NtBlock(..) | NtLiteral(..) => true,
                 _ => false,
             }
             _ => self.can_begin_literal_or_bool(),
@@ -404,13 +402,6 @@ impl Token {
         }
     }
 
-    crate fn expect_lit(&self) -> Lit {
-        match self.kind {
-            Literal(lit) => lit,
-            _ => panic!("`expect_lit` called on non-literal"),
-        }
-    }
-
     /// Returns `true` if the token is any literal, a minus (which can prefix a literal,
     /// for example a '-42', or one of the boolean idents).
     pub fn can_begin_literal_or_bool(&self) -> bool {
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index a51d208704a..6e1bb85ce1a 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -13,7 +13,7 @@
 //! and a borrowed `TokenStream` is sufficient to build an owned `TokenStream` without taking
 //! ownership of the original.
 
-use crate::parse::token::{self, DelimToken, Token, TokenKind};
+use crate::token::{self, DelimToken, Token, TokenKind};
 
 use syntax_pos::{Span, DUMMY_SP};
 #[cfg(target_arch = "x86_64")]
diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/util/classify.rs
index 44560688750..44560688750 100644
--- a/src/libsyntax/parse/classify.rs
+++ b/src/libsyntax/util/classify.rs
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/util/comments.rs
index ac79ce323bf..448b4f3b825 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/util/comments.rs
@@ -2,13 +2,14 @@ pub use CommentStyle::*;
 
 use crate::ast;
 use crate::source_map::SourceMap;
-use crate::parse::lexer::is_block_doc_comment;
-use crate::parse::lexer::ParseSess;
+use crate::sess::ParseSess;
 
 use syntax_pos::{BytePos, CharPos, Pos, FileName};
 
 use std::usize;
 
+use log::debug;
+
 #[cfg(test)]
 mod tests;
 
@@ -31,8 +32,23 @@ pub struct Comment {
     pub pos: BytePos,
 }
 
-fn is_doc_comment(s: &str) -> bool {
-    (s.starts_with("///") && super::is_doc_comment(s)) || s.starts_with("//!") ||
+crate fn is_line_doc_comment(s: &str) -> bool {
+    let res = (s.starts_with("///") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'/') ||
+              s.starts_with("//!");
+    debug!("is {:?} a doc comment? {}", s, res);
+    res
+}
+
+crate fn is_block_doc_comment(s: &str) -> bool {
+    // Prevent `/**/` from being parsed as a doc comment
+    let res = ((s.starts_with("/**") && *s.as_bytes().get(3).unwrap_or(&b' ') != b'*') ||
+               s.starts_with("/*!")) && s.len() >= 5;
+    debug!("is {:?} a doc comment? {}", s, res);
+    res
+}
+
+crate fn is_doc_comment(s: &str) -> bool {
+    (s.starts_with("///") && is_line_doc_comment(s)) || s.starts_with("//!") ||
     (s.starts_with("/**") && is_block_doc_comment(s)) || s.starts_with("/*!")
 }
 
diff --git a/src/libsyntax/parse/lexer/comments/tests.rs b/src/libsyntax/util/comments/tests.rs
index f9cd69fb50d..f9cd69fb50d 100644
--- a/src/libsyntax/parse/lexer/comments/tests.rs
+++ b/src/libsyntax/util/comments/tests.rs
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/util/literal.rs
index c42f4aa25cc..d4c9b7850c5 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/util/literal.rs
@@ -1,8 +1,8 @@
 //! Code related to parsing literals.
 
 use crate::ast::{self, Lit, LitKind};
-use crate::parse::token::{self, Token};
 use crate::symbol::{kw, sym, Symbol};
+use crate::token::{self, Token};
 use crate::tokenstream::TokenTree;
 
 use log::debug;
@@ -157,17 +157,18 @@ impl LitKind {
             }
             LitKind::Int(n, ty) => {
                 let suffix = match ty {
-                    ast::LitIntType::Unsigned(ty) => Some(ty.to_symbol()),
-                    ast::LitIntType::Signed(ty) => Some(ty.to_symbol()),
+                    ast::LitIntType::Unsigned(ty) => Some(ty.name()),
+                    ast::LitIntType::Signed(ty) => Some(ty.name()),
                     ast::LitIntType::Unsuffixed => None,
                 };
                 (token::Integer, sym::integer(n), suffix)
             }
             LitKind::Float(symbol, ty) => {
-                (token::Float, symbol, Some(ty.to_symbol()))
-            }
-            LitKind::FloatUnsuffixed(symbol) => {
-                (token::Float, symbol, None)
+                let suffix = match ty {
+                    ast::LitFloatType::Suffixed(ty) => Some(ty.name()),
+                    ast::LitFloatType::Unsuffixed => None,
+                };
+                (token::Float, symbol, suffix)
             }
             LitKind::Bool(value) => {
                 let symbol = if value { kw::True } else { kw::False };
@@ -244,12 +245,12 @@ fn filtered_float_lit(symbol: Symbol, suffix: Option<Symbol>, base: u32)
         return Err(LitError::NonDecimalFloat(base));
     }
     Ok(match suffix {
-        Some(suf) => match suf {
-            sym::f32 => LitKind::Float(symbol, ast::FloatTy::F32),
-            sym::f64 => LitKind::Float(symbol, ast::FloatTy::F64),
+        Some(suf) => LitKind::Float(symbol, ast::LitFloatType::Suffixed(match suf {
+            sym::f32 => ast::FloatTy::F32,
+            sym::f64 => ast::FloatTy::F64,
             _ => return Err(LitError::InvalidFloatSuffix),
-        }
-        None => LitKind::FloatUnsuffixed(symbol)
+        })),
+        None => LitKind::Float(symbol, ast::LitFloatType::Unsuffixed)
     })
 }
 
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index 982755e8680..edb708d7e97 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -1,4 +1,4 @@
-use crate::parse::token::{self, Token, BinOpToken};
+use crate::token::{self, Token, BinOpToken};
 use crate::symbol::kw;
 use crate::ast::{self, BinOpKind};
 
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index a36783e2b64..cfd160fd577 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -14,7 +14,7 @@
 //! those that are created by the expansion of a macro.
 
 use crate::ast::*;
-use crate::parse::token::Token;
+use crate::token::Token;
 use crate::tokenstream::{TokenTree, TokenStream};
 
 use syntax_pos::Span;
@@ -846,7 +846,10 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) {
 }
 
 pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) {
-    visitor.visit_tts(attr.tokens.clone());
+    match attr.kind {
+        AttrKind::Normal(ref item) => visitor.visit_tts(item.tokens.clone()),
+        AttrKind::DocComment(_) => {}
+    }
 }
 
 pub fn walk_tt<'a, V: Visitor<'a>>(visitor: &mut V, tt: TokenTree) {
diff --git a/src/libsyntax_expand/Cargo.toml b/src/libsyntax_expand/Cargo.toml
index d98b9457a62..02c711bc387 100644
--- a/src/libsyntax_expand/Cargo.toml
+++ b/src/libsyntax_expand/Cargo.toml
@@ -21,6 +21,5 @@ errors = { path = "../librustc_errors", package = "rustc_errors" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_index = { path = "../librustc_index" }
 rustc_lexer = { path = "../librustc_lexer" }
-rustc_target = { path = "../librustc_target" }
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
diff --git a/src/libsyntax_expand/base.rs b/src/libsyntax_expand/base.rs
index d02251eb746..47835c92659 100644
--- a/src/libsyntax_expand/base.rs
+++ b/src/libsyntax_expand/base.rs
@@ -6,11 +6,11 @@ use syntax::source_map::SourceMap;
 use syntax::edition::Edition;
 use syntax::mut_visit::{self, MutVisitor};
 use syntax::parse::{self, parser, DirectoryOwnership};
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Ident, Symbol};
 use syntax::{ThinVec, MACRO_ARGUMENTS};
+use syntax::token;
 use syntax::tokenstream::{self, TokenStream};
 use syntax::visit::Visitor;
 
diff --git a/src/libsyntax_expand/expand.rs b/src/libsyntax_expand/expand.rs
index 8c82e59e528..516b284cecd 100644
--- a/src/libsyntax_expand/expand.rs
+++ b/src/libsyntax_expand/expand.rs
@@ -12,18 +12,18 @@ use syntax::configure;
 use syntax::config::StripUnconfigured;
 use syntax::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
 use syntax::mut_visit::*;
-use syntax::parse::{DirectoryOwnership, PResult};
-use syntax::parse::token;
+use syntax::parse::DirectoryOwnership;
 use syntax::parse::parser::Parser;
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::sess::ParseSess;
 use syntax::symbol::{sym, Symbol};
+use syntax::token;
 use syntax::tokenstream::{TokenStream, TokenTree};
 use syntax::visit::{self, Visitor};
 use syntax::util::map_in_place::MapInPlace;
 
-use errors::{Applicability, FatalError};
+use errors::{PResult, Applicability, FatalError};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{Span, DUMMY_SP, FileName};
 
@@ -419,7 +419,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     }
 
                     let mut item = self.fully_configure(item);
-                    item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
+                    item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive)));
                     let mut helper_attrs = Vec::new();
                     let mut has_copy = false;
                     for ext in exts {
@@ -634,9 +634,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         | Annotatable::Variant(..)
                             => panic!("unexpected annotatable"),
                     })), DUMMY_SP).into();
-                    let input = self.extract_proc_macro_attr_input(attr.item.tokens, span);
+                    let item = attr.unwrap_normal_item();
+                    let input = self.extract_proc_macro_attr_input(item.tokens, span);
                     let tok_result = expander.expand(self.cx, span, input, item_tok);
-                    self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span)
+                    self.parse_ast_fragment(tok_result, fragment_kind, &item.path, span)
                 }
                 SyntaxExtensionKind::LegacyAttr(expander) => {
                     match attr.parse_meta(self.cx.parse_sess) {
@@ -974,7 +975,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                        -> Option<ast::Attribute> {
         let attr = attrs.iter()
                         .position(|a| {
-                            if a.path == sym::derive {
+                            if a.has_name(sym::derive) {
                                 *after_derive = true;
                             }
                             !attr::is_known(a) && !is_builtin_attr(a)
@@ -982,7 +983,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                         .map(|i| attrs.remove(i));
         if let Some(attr) = &attr {
             if !self.cx.ecfg.custom_inner_attributes() &&
-               attr.style == ast::AttrStyle::Inner && attr.path != sym::test {
+               attr.style == ast::AttrStyle::Inner && !attr.has_name(sym::test) {
                 emit_feature_err(&self.cx.parse_sess, sym::custom_inner_attributes,
                                  attr.span, GateIssue::Language,
                                  "non-builtin inner attributes are unstable");
@@ -1032,7 +1033,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
             feature_gate::check_attribute(attr, self.cx.parse_sess, features);
 
             // macros are expanded before any lint passes so this warning has to be hardcoded
-            if attr.path == sym::derive {
+            if attr.has_name(sym::derive) {
                 self.cx.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
                     .note("this may become a hard error in a future release")
                     .emit();
@@ -1547,11 +1548,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
 
             let meta = attr::mk_list_item(Ident::with_dummy_span(sym::doc), items);
             *at = attr::Attribute {
-                item: AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) },
+                kind: ast::AttrKind::Normal(
+                    AttrItem { path: meta.path, tokens: meta.kind.tokens(meta.span) },
+                ),
                 span: at.span,
                 id: at.id,
                 style: at.style,
-                is_sugared_doc: false,
             };
         } else {
             noop_visit_attribute(at, self)
diff --git a/src/libsyntax_expand/mbe.rs b/src/libsyntax_expand/mbe.rs
index 06e0cde3ad8..6964d01b719 100644
--- a/src/libsyntax_expand/mbe.rs
+++ b/src/libsyntax_expand/mbe.rs
@@ -10,7 +10,7 @@ crate mod macro_rules;
 crate mod quoted;
 
 use syntax::ast;
-use syntax::parse::token::{self, Token, TokenKind};
+use syntax::token::{self, Token, TokenKind};
 use syntax::tokenstream::{DelimSpan};
 
 use syntax_pos::Span;
diff --git a/src/libsyntax_expand/mbe/macro_check.rs b/src/libsyntax_expand/mbe/macro_check.rs
index 50abda8d45e..25754ed4217 100644
--- a/src/libsyntax_expand/mbe/macro_check.rs
+++ b/src/libsyntax_expand/mbe/macro_check.rs
@@ -108,7 +108,7 @@ use crate::mbe::{KleeneToken, TokenTree};
 
 use syntax::ast::NodeId;
 use syntax::early_buffered_lints::BufferedEarlyLintId;
-use syntax::parse::token::{DelimToken, Token, TokenKind};
+use syntax::token::{DelimToken, Token, TokenKind};
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym};
 
diff --git a/src/libsyntax_expand/mbe/macro_parser.rs b/src/libsyntax_expand/mbe/macro_parser.rs
index 3efe22626a9..80bf27e1a94 100644
--- a/src/libsyntax_expand/mbe/macro_parser.rs
+++ b/src/libsyntax_expand/mbe/macro_parser.rs
@@ -77,15 +77,15 @@ use TokenTreeOrTokenTreeSlice::*;
 use crate::mbe::{self, TokenTree};
 
 use syntax::ast::{Ident, Name};
-use syntax::parse::{Directory, PResult};
+use syntax::parse::Directory;
 use syntax::parse::parser::{Parser, PathStyle};
-use syntax::parse::token::{self, DocComment, Nonterminal, Token};
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Symbol};
+use syntax::token::{self, DocComment, Nonterminal, Token};
 use syntax::tokenstream::{DelimSpan, TokenStream};
 
-use errors::FatalError;
+use errors::{PResult, FatalError};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::Span;
 
diff --git a/src/libsyntax_expand/mbe/macro_rules.rs b/src/libsyntax_expand/mbe/macro_rules.rs
index 7a772b0d31d..a5fc301fbf6 100644
--- a/src/libsyntax_expand/mbe/macro_rules.rs
+++ b/src/libsyntax_expand/mbe/macro_rules.rs
@@ -13,12 +13,11 @@ use syntax::attr::{self, TransparencyError};
 use syntax::edition::Edition;
 use syntax::feature_gate::Features;
 use syntax::parse::parser::Parser;
-use syntax::parse::token::TokenKind::*;
-use syntax::parse::token::{self, NtTT, Token};
 use syntax::parse::Directory;
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
 use syntax::symbol::{kw, sym, Symbol};
+use syntax::token::{self, NtTT, Token, TokenKind::*};
 use syntax::tokenstream::{DelimSpan, TokenStream};
 
 use errors::{DiagnosticBuilder, FatalError};
@@ -29,7 +28,7 @@ use syntax_pos::Span;
 use rustc_data_structures::fx::FxHashMap;
 use std::borrow::Cow;
 use std::collections::hash_map::Entry;
-use std::slice;
+use std::{mem, slice};
 
 use errors::Applicability;
 use rustc_data_structures::sync::Lrc;
@@ -182,7 +181,6 @@ fn generic_extension<'cx>(
 
     // Which arm's failure should we report? (the one furthest along)
     let mut best_failure: Option<(Token, &str)> = None;
-
     for (i, lhs) in lhses.iter().enumerate() {
         // try each arm's matchers
         let lhs_tt = match *lhs {
@@ -190,8 +188,18 @@ fn generic_extension<'cx>(
             _ => cx.span_bug(sp, "malformed macro lhs"),
         };
 
+        // Take a snapshot of the state of pre-expansion gating at this point.
+        // This is used so that if a matcher is not `Success(..)`ful,
+        // then the spans which became gated when parsing the unsucessful matcher
+        // are not recorded. On the first `Success(..)`ful matcher, the spans are merged.
+        let mut gated_spans_snaphot = mem::take(&mut *cx.parse_sess.gated_spans.spans.borrow_mut());
+
         match parse_tt(cx, lhs_tt, arg.clone()) {
             Success(named_matches) => {
+                // The matcher was `Success(..)`ful.
+                // Merge the gated spans from parsing the matcher with the pre-existing ones.
+                cx.parse_sess.gated_spans.merge(gated_spans_snaphot);
+
                 let rhs = match rhses[i] {
                     // ignore delimiters
                     mbe::TokenTree::Delimited(_, ref delimed) => delimed.tts.clone(),
@@ -248,6 +256,10 @@ fn generic_extension<'cx>(
             },
             Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]),
         }
+
+        // The matcher was not `Success(..)`ful.
+        // Restore to the state before snapshotting and maybe try again.
+        mem::swap(&mut gated_spans_snaphot, &mut cx.parse_sess.gated_spans.spans.borrow_mut());
     }
 
     let (token, label) = best_failure.expect("ran no matchers");
diff --git a/src/libsyntax_expand/mbe/quoted.rs b/src/libsyntax_expand/mbe/quoted.rs
index cedd59233ad..dec504c0d97 100644
--- a/src/libsyntax_expand/mbe/quoted.rs
+++ b/src/libsyntax_expand/mbe/quoted.rs
@@ -2,10 +2,10 @@ use crate::mbe::macro_parser;
 use crate::mbe::{TokenTree, KleeneOp, KleeneToken, SequenceRepetition, Delimited};
 
 use syntax::ast;
-use syntax::parse::token::{self, Token};
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
 use syntax::symbol::kw;
+use syntax::token::{self, Token};
 use syntax::tokenstream;
 
 use syntax_pos::Span;
diff --git a/src/libsyntax_expand/mbe/transcribe.rs b/src/libsyntax_expand/mbe/transcribe.rs
index 6f060103ef4..4092d4b97de 100644
--- a/src/libsyntax_expand/mbe/transcribe.rs
+++ b/src/libsyntax_expand/mbe/transcribe.rs
@@ -4,7 +4,7 @@ use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
 
 use syntax::ast::{Ident, Mac};
 use syntax::mut_visit::{self, MutVisitor};
-use syntax::parse::token::{self, NtTT, Token};
+use syntax::token::{self, NtTT, Token};
 use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
 use smallvec::{smallvec, SmallVec};
diff --git a/src/libsyntax_expand/proc_macro.rs b/src/libsyntax_expand/proc_macro.rs
index bda9478ce96..51c368bbaa6 100644
--- a/src/libsyntax_expand/proc_macro.rs
+++ b/src/libsyntax_expand/proc_macro.rs
@@ -4,8 +4,9 @@ use crate::proc_macro_server;
 use syntax::ast::{self, ItemKind, Attribute, Mac};
 use syntax::attr::{mark_used, mark_known};
 use syntax::errors::{Applicability, FatalError};
-use syntax::parse::{self, token};
+use syntax::parse;
 use syntax::symbol::sym;
+use syntax::token;
 use syntax::tokenstream::{self, TokenStream};
 use syntax::visit::Visitor;
 
@@ -181,7 +182,7 @@ impl<'a> Visitor<'a> for MarkAttrs<'a> {
 crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>) -> Vec<ast::Path> {
     let mut result = Vec::new();
     attrs.retain(|attr| {
-        if attr.path != sym::derive {
+        if !attr.has_name(sym::derive) {
             return true;
         }
         if !attr.is_meta_item_list() {
@@ -196,7 +197,7 @@ crate fn collect_derives(cx: &mut ExtCtxt<'_>, attrs: &mut Vec<ast::Attribute>)
         }
 
         let parse_derive_paths = |attr: &ast::Attribute| {
-            if attr.tokens.is_empty() {
+            if attr.get_normal_item().tokens.is_empty() {
                 return Ok(Vec::new());
             }
             parse::parse_in_attr(cx.parse_sess, attr, |p| p.parse_derive_paths())
diff --git a/src/libsyntax_expand/proc_macro_server.rs b/src/libsyntax_expand/proc_macro_server.rs
index 4ce99cfe73b..e96b6092787 100644
--- a/src/libsyntax_expand/proc_macro_server.rs
+++ b/src/libsyntax_expand/proc_macro_server.rs
@@ -1,10 +1,11 @@
 use crate::base::ExtCtxt;
 
 use syntax::ast;
-use syntax::parse::{self, token};
-use syntax::parse::lexer::comments;
+use syntax::parse;
+use syntax::util::comments;
 use syntax::print::pprust;
 use syntax::sess::ParseSess;
+use syntax::token;
 use syntax::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 
 use errors::Diagnostic;
@@ -52,7 +53,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
 {
     fn from_internal(((tree, is_joint), sess, stack): (TreeAndJoint, &ParseSess, &mut Vec<Self>))
                     -> Self {
-        use syntax::parse::token::*;
+        use syntax::token::*;
 
         let joint = is_joint == Joint;
         let Token { kind, span } = match tree {
@@ -193,7 +194,7 @@ impl FromInternal<(TreeAndJoint, &'_ ParseSess, &'_ mut Vec<Self>)>
 
 impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
     fn to_internal(self) -> TokenStream {
-        use syntax::parse::token::*;
+        use syntax::token::*;
 
         let (ch, joint, span) = match self {
             TokenTree::Punct(Punct { ch, joint, span }) => (ch, joint, span),
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 8c9a34713ea..539d777105d 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -8,7 +8,7 @@ use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
 use syntax::ast::AsmDialect;
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index f4d1f7fb09c..a15423b7ad8 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -2,7 +2,7 @@ use errors::{Applicability, DiagnosticBuilder};
 
 use syntax::ast::{self, *};
 use syntax_expand::base::*;
-use syntax::parse::token::{self, TokenKind};
+use syntax::token::{self, TokenKind};
 use syntax::parse::parser::Parser;
 use syntax::print::pprust;
 use syntax::ptr::P;
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 9e693f29c5a..583236d9754 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -8,7 +8,7 @@ use syntax::ast;
 use syntax_expand::base::{self, *};
 use syntax::attr;
 use syntax::tokenstream::TokenStream;
-use syntax::parse::token;
+use syntax::token;
 use syntax_pos::Span;
 
 pub fn expand_cfg(
diff --git a/src/libsyntax_ext/cmdline_attrs.rs b/src/libsyntax_ext/cmdline_attrs.rs
index 2d981526a39..171f2405573 100644
--- a/src/libsyntax_ext/cmdline_attrs.rs
+++ b/src/libsyntax_ext/cmdline_attrs.rs
@@ -2,7 +2,8 @@
 
 use syntax::ast::{self, AttrItem, AttrStyle};
 use syntax::attr::mk_attr;
-use syntax::parse::{self, token};
+use syntax::parse;
+use syntax::token;
 use syntax::sess::ParseSess;
 use syntax_expand::panictry;
 use syntax_pos::FileName;
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index 47bade698a8..4bf13f37711 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -21,8 +21,7 @@ pub fn expand_concat(
         match e.kind {
             ast::ExprKind::Lit(ref lit) => match lit.kind {
                 ast::LitKind::Str(ref s, _)
-                | ast::LitKind::Float(ref s, _)
-                | ast::LitKind::FloatUnsuffixed(ref s) => {
+                | ast::LitKind::Float(ref s, _) => {
                     accumulator.push_str(&s.as_str());
                 }
                 ast::LitKind::Char(c) => {
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index a132a4136ea..8a1bc56cf1c 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::thin_vec::ThinVec;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::ptr::P;
 use syntax_pos::Span;
 use syntax_pos::symbol::Symbol;
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 2e5ae235893..b18fd50ae76 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -182,8 +182,7 @@ use std::iter;
 use std::vec;
 
 use rustc_data_structures::thin_vec::ThinVec;
-use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
+use syntax::ast::{self, Abi, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind};
 use syntax::ast::{VariantData, GenericParamKind, GenericArg};
 use syntax::attr;
 use syntax::source_map::respan;
@@ -738,7 +737,7 @@ impl<'a> TraitDef<'a> {
                                          self,
                                          type_ident,
                                          generics,
-                                         Abi::Rust,
+                                         sym::Rust,
                                          explicit_self,
                                          tys,
                                          body)
@@ -793,7 +792,7 @@ impl<'a> TraitDef<'a> {
                                          self,
                                          type_ident,
                                          generics,
-                                         Abi::Rust,
+                                         sym::Rust,
                                          explicit_self,
                                          tys,
                                          body)
@@ -919,7 +918,7 @@ impl<'a> MethodDef<'a> {
                      trait_: &TraitDef<'_>,
                      type_ident: Ident,
                      generics: &Generics,
-                     abi: Abi,
+                     abi: Symbol,
                      explicit_self: Option<ast::ExplicitSelf>,
                      arg_types: Vec<(Ident, P<ast::Ty>)>,
                      body: P<Expr>)
@@ -949,23 +948,27 @@ impl<'a> MethodDef<'a> {
             ast::Unsafety::Normal
         };
 
+        let trait_lo_sp = trait_.span.shrink_to_lo();
+
+        let sig = ast::MethodSig {
+            header: ast::FnHeader {
+                unsafety,
+                abi: Abi::new(abi, trait_lo_sp),
+                ..ast::FnHeader::default()
+            },
+            decl: fn_decl,
+        };
+
         // Create the method.
         ast::ImplItem {
             id: ast::DUMMY_NODE_ID,
             attrs: self.attributes.clone(),
             generics: fn_generics,
             span: trait_.span,
-            vis: respan(trait_.span.shrink_to_lo(), ast::VisibilityKind::Inherited),
+            vis: respan(trait_lo_sp, ast::VisibilityKind::Inherited),
             defaultness: ast::Defaultness::Final,
             ident: method_ident,
-            kind: ast::ImplItemKind::Method(ast::MethodSig {
-                                                header: ast::FnHeader {
-                                                    unsafety, abi,
-                                                    ..ast::FnHeader::default()
-                                                },
-                                                decl: fn_decl,
-                                            },
-                                            body_block),
+            kind: ast::ImplItemKind::Method(sig, body_block),
             tokens: None,
         }
     }
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 314c2eefd4c..e25ba7b1783 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -9,7 +9,7 @@ use errors::pluralize;
 
 use syntax::ast;
 use syntax_expand::base::{self, *};
-use syntax::parse::token;
+use syntax::token;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
 use syntax::tokenstream::TokenStream;
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 879ae1e4215..8a8ce9a7f14 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -13,7 +13,7 @@ use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::source_map::respan;
 use syntax_expand::base::{self, *};
-use syntax::parse::token;
+use syntax::token;
 use syntax::ptr::P;
 use syntax_pos::Span;
 use syntax::tokenstream::TokenStream;
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index 1ca9422eb9d..cee1b97af55 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -4,12 +4,12 @@
 use syntax::ast::*;
 use syntax::attr;
 use syntax::edition::Edition;
-use syntax_expand::base::{Resolver, NamedSyntaxExtension};
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::source_map::respan;
 use syntax::symbol::sym;
+use syntax::token;
 use syntax::tokenstream::*;
+use syntax_expand::base::{Resolver, NamedSyntaxExtension};
 use syntax_pos::{Span, DUMMY_SP};
 use syntax_pos::hygiene::{ExpnData, ExpnKind, AstPass};
 
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index fc4a7a0a0fe..792c97d8508 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -249,9 +249,11 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         for attr in &item.attrs {
             if is_proc_macro_attr(&attr) {
                 if let Some(prev_attr) = found_attr {
-                    let path_str = pprust::path_to_string(&attr.path);
-                    let msg = if attr.path.segments[0].ident.name ==
-                                 prev_attr.path.segments[0].ident.name {
+                    let prev_item = prev_attr.get_normal_item();
+                    let item = attr.get_normal_item();
+                    let path_str = pprust::path_to_string(&item.path);
+                    let msg = if item.path.segments[0].ident.name ==
+                                 prev_item.path.segments[0].ident.name {
                         format!(
                             "only one `#[{}]` attribute is allowed on any given function",
                             path_str,
@@ -261,7 +263,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
                             "`#[{}]` and `#[{}]` attributes cannot both be applied
                             to the same function",
                             path_str,
-                            pprust::path_to_string(&prev_attr.path),
+                            pprust::path_to_string(&prev_item.path),
                         )
                     };
 
@@ -290,7 +292,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         if !is_fn {
             let msg = format!(
                 "the `#[{}]` attribute may only be used on bare functions",
-                pprust::path_to_string(&attr.path),
+                pprust::path_to_string(&attr.get_normal_item().path),
             );
 
             self.handler.span_err(attr.span, &msg);
@@ -304,7 +306,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
         if !self.is_proc_macro_crate {
             let msg = format!(
                 "the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type",
-                pprust::path_to_string(&attr.path),
+                pprust::path_to_string(&attr.get_normal_item().path),
             );
 
             self.handler.span_err(attr.span, &msg);
diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs
index f6c58fcdfa1..7e47b40714d 100644
--- a/src/libsyntax_ext/source_util.rs
+++ b/src/libsyntax_ext/source_util.rs
@@ -1,10 +1,11 @@
 use syntax_expand::panictry;
 use syntax_expand::base::{self, *};
 use syntax::ast;
-use syntax::parse::{self, token, DirectoryOwnership};
+use syntax::parse::{self, DirectoryOwnership};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
+use syntax::token;
 use syntax::tokenstream::TokenStream;
 use syntax::early_buffered_lints::BufferedEarlyLintId;
 
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index d834a59b486..ae82ffd6383 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -148,6 +148,7 @@ symbols! {
         associated_type_bounds,
         associated_type_defaults,
         associated_types,
+        assume_init,
         async_await,
         async_closure,
         attr,
@@ -417,6 +418,8 @@ symbols! {
         match_beginning_vert,
         match_default_bindings,
         may_dangle,
+        maybe_uninit,
+        MaybeUninit,
         mem,
         member_constraints,
         message,
@@ -563,6 +566,7 @@ symbols! {
         rust_2018_preview,
         rust_begin_unwind,
         rustc,
+        Rust,
         RustcDecodable,
         RustcEncodable,
         rustc_allocator,
@@ -709,6 +713,7 @@ symbols! {
         underscore_imports,
         underscore_lifetimes,
         uniform_paths,
+        uninit,
         uninitialized,
         universal_impl_trait,
         unmarked_api,
diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs
index 9de774555e9..e0e211444cf 100644
--- a/src/libtest/tests.rs
+++ b/src/libtest/tests.rs
@@ -269,7 +269,7 @@ fn time_test_failure_template(test_type: TestType) -> TestResult {
 fn test_error_on_exceed() {
     let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest];
 
-    for test_type in types.into_iter() {
+    for test_type in types.iter() {
         let result = time_test_failure_template(*test_type);
 
         assert_eq!(result, TestResult::TrTimedFail);
@@ -320,7 +320,7 @@ fn test_time_options_threshold() {
         (TestType::DocTest, doc.critical.as_millis(), true, true),
     ];
 
-    for (test_type, time, expected_warn, expected_critical) in test_vector.into_iter() {
+    for (test_type, time, expected_warn, expected_critical) in test_vector.iter() {
         let test_desc = typed_test_desc(*test_type);
         let exec_time = test_exec_time(*time as u64);
 
diff --git a/src/test/codegen/abi-efiapi.rs b/src/test/codegen/abi-efiapi.rs
index 72adb95e96a..8aeee5859d0 100644
--- a/src/test/codegen/abi-efiapi.rs
+++ b/src/test/codegen/abi-efiapi.rs
@@ -1,14 +1,12 @@
 // Checks if the correct annotation for the efiapi ABI is passed to llvm.
 
-// revisions:x86_64 i686 aarch64 arm riscv
+// revisions:x86_64 i686 arm
 
 // min-llvm-version 9.0
 
 //[x86_64] compile-flags: --target x86_64-unknown-uefi
 //[i686] compile-flags: --target i686-unknown-linux-musl
-//[aarch64] compile-flags: --target aarch64-unknown-none
 //[arm] compile-flags: --target armv7r-none-eabi
-//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
@@ -24,8 +22,6 @@ trait Copy { }
 
 //x86_64: define win64cc void @has_efiapi
 //i686: define void @has_efiapi
-//aarch64: define void @has_efiapi
 //arm: define void @has_efiapi
-//riscv: define void @has_efiapi
 #[no_mangle]
 pub extern "efiapi" fn has_efiapi() {}
diff --git a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
index 709e9be663e..fa52ca90b10 100644
--- a/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
+++ b/src/test/incremental/issue-59523-on-implemented-is-not-unused.rs
@@ -5,7 +5,7 @@
 // revisions: cfail1 cfail2
 // build-pass (FIXME(62277): could be check-pass?)
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 #![deny(unused_attributes)]
 
 #[rustc_on_unimplemented = "invalid"]
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
index a9f25853350..38d1d5bb848 100644
--- a/src/test/run-make-fulldeps/extern-flag-fun/Makefile
+++ b/src/test/run-make-fulldeps/extern-flag-fun/Makefile
@@ -4,7 +4,6 @@ all:
 	$(RUSTC) bar.rs --crate-type=rlib
 	$(RUSTC) bar.rs --crate-type=rlib -C extra-filename=-a
 	$(RUSTC) bar-alt.rs --crate-type=rlib
-	$(RUSTC) foo.rs --extern hello && exit 1 || exit 0
 	$(RUSTC) foo.rs --extern bar=no-exist && exit 1 || exit 0
 	$(RUSTC) foo.rs --extern bar=foo.rs && exit 1 || exit 0
 	$(RUSTC) foo.rs \
@@ -15,3 +14,6 @@ all:
 		--extern bar=$(TMPDIR)/libbar.rlib \
 		--extern bar=$(TMPDIR)/libbar-a.rlib
 	$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib
+	# Try to be sneaky and load a private crate from with a non-private name.
+	$(RUSTC) rustc.rs -Zforce-unstable-if-unmarked --crate-type=rlib
+	$(RUSTC) gated_unstable.rs --extern alloc=$(TMPDIR)/librustc.rlib 2>&1 | $(CGREP) 'rustc_private'
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs b/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
new file mode 100644
index 00000000000..03600c830ff
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-fun/gated_unstable.rs
@@ -0,0 +1,3 @@
+extern crate alloc;
+
+fn main() {}
diff --git a/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
new file mode 100644
index 00000000000..b76b4321d62
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-fun/rustc.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/Makefile b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
new file mode 100644
index 00000000000..4849fc62f4a
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/Makefile
@@ -0,0 +1,18 @@
+-include ../tools.mk
+
+# Test mixing pathless --extern with paths.
+
+all:
+	$(RUSTC) bar-static.rs --crate-name=bar --crate-type=rlib
+	$(RUSTC) bar-dynamic.rs --crate-name=bar --crate-type=dylib -C prefer-dynamic
+	# rlib preferred over dylib
+	$(RUSTC) foo.rs --extern bar
+	$(call RUN,foo) | $(CGREP) 'static'
+	$(RUSTC) foo.rs --extern bar=$(TMPDIR)/libbar.rlib --extern bar
+	$(call RUN,foo) | $(CGREP) 'static'
+	# explicit --extern overrides pathless
+	$(RUSTC) foo.rs --extern bar=$(call DYLIB,bar) --extern bar
+	$(call RUN,foo) | $(CGREP) 'dynamic'
+	# prefer-dynamic does what it says
+	$(RUSTC) foo.rs --extern bar -C prefer-dynamic
+	$(call RUN,foo) | $(CGREP) 'dynamic'
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs b/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs
new file mode 100644
index 00000000000..e2d68d517ff
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs
@@ -0,0 +1,3 @@
+pub fn f() {
+    println!("dynamic");
+}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs b/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
new file mode 100644
index 00000000000..240d8bde4d1
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/bar-static.rs
@@ -0,0 +1,3 @@
+pub fn f() {
+    println!("static");
+}
diff --git a/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs b/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
new file mode 100644
index 00000000000..1ea64da7dad
--- /dev/null
+++ b/src/test/run-make-fulldeps/extern-flag-pathless/foo.rs
@@ -0,0 +1,3 @@
+fn main() {
+    bar::f();
+}
diff --git a/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
index ac42141365e..96fb16b1fcc 100644
--- a/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
+++ b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs
@@ -7,12 +7,43 @@
 // Eventually we should see an argument that looks like `@` as we switch from
 // passing literal arguments to passing everything in the file.
 
+use std::collections::HashSet;
 use std::env;
 use std::fs::{self, File};
-use std::io::{BufWriter, Write, Read};
-use std::path::PathBuf;
+use std::io::{BufWriter, Write};
+use std::path::{Path, PathBuf};
 use std::process::Command;
 
+fn write_test_case(file: &Path, n: usize) -> HashSet<String> {
+    let mut libs = HashSet::new();
+    let mut f = BufWriter::new(File::create(&file).unwrap());
+    let mut prefix = String::new();
+    for _ in 0..n {
+        prefix.push_str("foo");
+    }
+    for i in 0..n {
+        writeln!(f, "#[link(name = \"S{}{}S\")]", prefix, i).unwrap();
+        libs.insert(format!("{}{}", prefix, i));
+    }
+    writeln!(f, "extern {{}}\nfn main() {{}}").unwrap();
+    f.into_inner().unwrap();
+
+    libs
+}
+
+fn read_linker_args(path: &Path) -> String {
+    let contents = fs::read(path).unwrap();
+    if cfg!(target_env = "msvc") {
+        let mut i = contents.chunks(2).map(|c| {
+            c[0] as u16 | ((c[1] as u16) << 8)
+        });
+        assert_eq!(i.next(), Some(0xfeff), "Expected UTF-16 BOM");
+        String::from_utf16(&i.collect::<Vec<u16>>()).unwrap()
+    } else {
+        String::from_utf8(contents).unwrap()
+    }
+}
+
 fn main() {
     let tmpdir = PathBuf::from(env::var_os("TMPDIR").unwrap());
     let ok = tmpdir.join("ok");
@@ -29,16 +60,7 @@ fn main() {
     for i in (1..).map(|i| i * 100) {
         println!("attempt: {}", i);
         let file = tmpdir.join("bar.rs");
-        let mut f = BufWriter::new(File::create(&file).unwrap());
-        let mut lib_name = String::new();
-        for _ in 0..i {
-            lib_name.push_str("foo");
-        }
-        for j in 0..i {
-            writeln!(f, "#[link(name = \"{}{}\")]", lib_name, j).unwrap();
-        }
-        writeln!(f, "extern {{}}\nfn main() {{}}").unwrap();
-        f.into_inner().unwrap();
+        let mut expected_libs = write_test_case(&file, i);
 
         drop(fs::remove_file(&ok));
         let output = Command::new(&rustc)
@@ -67,25 +89,18 @@ fn main() {
             continue
         }
 
-        let mut contents = Vec::new();
-        File::open(&ok).unwrap().read_to_end(&mut contents).unwrap();
-
-        for j in 0..i {
-            let exp = format!("{}{}", lib_name, j);
-            let exp = if cfg!(target_env = "msvc") {
-                let mut out = Vec::with_capacity(exp.len() * 2);
-                for c in exp.encode_utf16() {
-                    // encode in little endian
-                    out.push(c as u8);
-                    out.push((c >> 8) as u8);
-                }
-                out
-            } else {
-                exp.into_bytes()
-            };
-            assert!(contents.windows(exp.len()).any(|w| w == &exp[..]));
+        let linker_args = read_linker_args(&ok);
+        for mut arg in linker_args.split('S') {
+            expected_libs.remove(arg);
         }
 
+        assert!(
+            expected_libs.is_empty(),
+            "expected but missing libraries: {:#?}\nlinker arguments: \n{}",
+            expected_libs,
+            linker_args,
+        );
+
         break
     }
 }
diff --git a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
index bf98fcd10cf..36288c4b870 100644
--- a/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
+++ b/src/test/run-make-fulldeps/save-analysis-rfc2126/Makefile
@@ -1,8 +1,7 @@
 -include ../tools.mk
 
 all: extern_absolute_paths.rs krate2
-	$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 \
-		-Z unstable-options --extern krate2
+	$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 --extern krate2
 	cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py
 
 krate2: krate2.rs
diff --git a/src/test/rustdoc/inline_cross/use_crate.rs b/src/test/rustdoc/inline_cross/use_crate.rs
index f678ba0a46c..00e0f041c56 100644
--- a/src/test/rustdoc/inline_cross/use_crate.rs
+++ b/src/test/rustdoc/inline_cross/use_crate.rs
@@ -2,7 +2,7 @@
 // aux-build:use_crate_2.rs
 // build-aux-docs
 // edition:2018
-// compile-flags:--extern use_crate --extern use_crate_2 -Z unstable-options
+// compile-flags:--extern use_crate --extern use_crate_2
 
 // During the buildup to Rust 2018, rustdoc would eagerly inline `pub use some_crate;` as if it
 // were a module, so we changed it to make `pub use`ing crate roots remain as a `pub use` statement
diff --git a/src/test/ui-fulldeps/ast_stmt_expr_attr.rs b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
index 927e2c0820e..ac864e76784 100644
--- a/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
+++ b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
@@ -6,17 +6,18 @@
 #![feature(rustc_private)]
 
 extern crate syntax;
+extern crate rustc_errors;
 
+use rustc_errors::PResult;
 use syntax::ast::*;
 use syntax::attr::*;
 use syntax::ast;
 use syntax::sess::ParseSess;
 use syntax::source_map::{FilePathMapping, FileName};
 use syntax::parse;
-use syntax::parse::PResult;
 use syntax::parse::new_parser_from_source_str;
 use syntax::parse::parser::Parser;
-use syntax::parse::token;
+use syntax::token;
 use syntax::ptr::P;
 use syntax::parse::parser::attr::*;
 use syntax::print::pprust;
diff --git a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
index 3524f449c74..520347faa15 100644
--- a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
+++ b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
@@ -15,7 +15,7 @@ extern crate syntax_pos;
 extern crate rustc;
 extern crate rustc_driver;
 
-use syntax::parse::token::{self, Token};
+use syntax::token::{self, Token};
 use syntax::tokenstream::{TokenTree, TokenStream};
 use syntax_expand::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax_pos::Span;
diff --git a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr
index c6d198dc458..5ab3dfb2449 100644
--- a/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr
+++ b/src/test/ui-fulldeps/lint-plugin-cmdline-allow.stderr
@@ -7,10 +7,10 @@ LL | #![plugin(lint_plugin_test)]
    = note: `#[warn(deprecated)]` on by default
 
 warning: function is never used: `lintme`
-  --> $DIR/lint-plugin-cmdline-allow.rs:10:1
+  --> $DIR/lint-plugin-cmdline-allow.rs:10:4
    |
 LL | fn lintme() { }
-   | ^^^^^^^^^^^
+   |    ^^^^^^
    |
 note: lint level defined here
   --> $DIR/lint-plugin-cmdline-allow.rs:7:9
diff --git a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
index 239732521d5..3a9fd7c2867 100644
--- a/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
+++ b/src/test/ui-fulldeps/lint-tool-cmdline-allow.stderr
@@ -19,10 +19,10 @@ LL | fn lintme() {}
    = note: `#[warn(clippy::test_lint)]` on by default
 
 warning: function is never used: `lintme`
-  --> $DIR/lint-tool-cmdline-allow.rs:10:1
+  --> $DIR/lint-tool-cmdline-allow.rs:10:4
    |
 LL | fn lintme() {}
-   | ^^^^^^^^^^^
+   |    ^^^^^^
    |
 note: lint level defined here
   --> $DIR/lint-tool-cmdline-allow.rs:7:9
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.rs b/src/test/ui-fulldeps/pathless-extern-unstable.rs
new file mode 100644
index 00000000000..00b3ec5409f
--- /dev/null
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.rs
@@ -0,0 +1,10 @@
+// ignore-stage1
+// edition:2018
+// compile-flags:--extern rustc
+
+// Test that `--extern rustc` fails with `rustc_private`.
+
+pub use rustc;
+//~^ ERROR use of unstable library feature 'rustc_private'
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/pathless-extern-unstable.stderr b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
new file mode 100644
index 00000000000..edc3b1c58be
--- /dev/null
+++ b/src/test/ui-fulldeps/pathless-extern-unstable.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
+  --> $DIR/pathless-extern-unstable.rs:7:9
+   |
+LL | pub use rustc;
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/27812
+   = help: add `#![feature(rustc_private)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/abi/abi-sysv64-register-usage.rs b/src/test/ui/abi/abi-sysv64-register-usage.rs
index 0c7e2d906b7..88d89fba260 100644
--- a/src/test/ui/abi/abi-sysv64-register-usage.rs
+++ b/src/test/ui/abi/abi-sysv64-register-usage.rs
@@ -33,6 +33,7 @@ pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
 
 // this struct contains 8 i64's, while only 6 can be passed in registers.
 #[cfg(target_arch = "x86_64")]
+#[repr(C)]
 #[derive(PartialEq, Eq, Debug)]
 pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
 
diff --git a/src/test/ui/align-with-extern-c-fn.rs b/src/test/ui/align-with-extern-c-fn.rs
index 09abe4fbf7e..8ba90225c6c 100644
--- a/src/test/ui/align-with-extern-c-fn.rs
+++ b/src/test/ui/align-with-extern-c-fn.rs
@@ -7,7 +7,7 @@
 
 #![feature(repr_align)]
 
-#[repr(align(16))]
+#[repr(align(16), C)]
 pub struct A(i64);
 
 pub extern "C" fn foo(x: A) {}
diff --git a/src/test/ui/async-await/issue-61793.rs b/src/test/ui/async-await/issue-61793.rs
index f6084be9167..9180e1d811a 100644
--- a/src/test/ui/async-await/issue-61793.rs
+++ b/src/test/ui/async-await/issue-61793.rs
@@ -3,7 +3,7 @@
 // while those two fields were at the same offset (which is impossible).
 // That is, memory ordering of `(X, ())`, but offsets of `((), X)`.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // edition:2018
 
 async fn foo<F>(_: &(), _: F) {}
diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs
index 5cae0704444..e9079bfdd85 100644
--- a/src/test/ui/async-await/issues/issue-53249.rs
+++ b/src/test/ui/async-await/issues/issue-53249.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 #![feature(arbitrary_self_types)]
diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs
index 9adc0a82323..b602ef153e6 100644
--- a/src/test/ui/async-await/issues/issue-54974.rs
+++ b/src/test/ui/async-await/issues/issue-54974.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 use std::sync::Arc;
diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs
index 1ca05160751..69bbdd0e83a 100644
--- a/src/test/ui/async-await/issues/issue-60518.rs
+++ b/src/test/ui/async-await/issues/issue-60518.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 // This is a regression test to ensure that simple bindings (where replacement arguments aren't
diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
index 788474365c9..e95f7df388c 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -1,6 +1,5 @@
 // edition:2018
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 
 async fn print_dur() {}
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 538430290d2..6c8e0d0a5c4 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:8:5
+  --> $DIR/issue-62009-1.rs:7:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -7,7 +7,7 @@ LL |     async { let (); }.await;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:10:5
+  --> $DIR/issue-62009-1.rs:9:5
    |
 LL |   fn main() {
    |      ---- this is not `async`
@@ -19,7 +19,7 @@ LL | |     }.await;
    | |___________^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:14:5
+  --> $DIR/issue-62009-1.rs:13:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -27,11 +27,11 @@ LL | fn main() {
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied
-  --> $DIR/issue-62009-1.rs:14:5
+error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:13:5: 13:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:13:5
    |
 LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]`
+   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:13:5: 13:15]`
    | 
   ::: $SRC_DIR/libstd/future.rs:LL:COL
    |
diff --git a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
index 1d98067ce73..b87ef3baa4a 100644
--- a/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
+++ b/src/test/ui/borrowck/issue-55552-ascribe-wildcard-to-structured-pattern.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274
 // (for ensuring that NLL respects user-provided lifetime annotations)
diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs
index f7b4f2b2454..2e104b599bd 100644
--- a/src/test/ui/closure-expected-type/issue-24421.rs
+++ b/src/test/ui/closure-expected-type/issue-24421.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn test<F: Fn(&u64, &u64)>(f: F) {}
 
diff --git a/src/test/ui/closures/closure-move-sync.rs b/src/test/ui/closures/closure-move-sync.rs
index 951a3bcb5f4..2f1e6c81ae5 100644
--- a/src/test/ui/closures/closure-move-sync.rs
+++ b/src/test/ui/closures/closure-move-sync.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::thread;
 use std::sync::mpsc::channel;
 
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index f676df9c559..ac5e3ccb421 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:8:13
+  --> $DIR/closure-move-sync.rs:7:13
    |
 LL |     let t = thread::spawn(|| {
    |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
@@ -11,10 +11,10 @@ LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:8:27: 11:6 recv:&std::sync::mpsc::Receiver<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:7:27: 10:6 recv:&std::sync::mpsc::Receiver<()>]`
 
 error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:20:5
+  --> $DIR/closure-move-sync.rs:19:5
    |
 LL |     thread::spawn(|| tx.send(()).unwrap());
    |     ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
@@ -26,7 +26,7 @@ LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:20:19: 20:42 tx:&std::sync::mpsc::Sender<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:19:19: 19:42 tx:&std::sync::mpsc::Sender<()>]`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 9134ef5a31a..85fb8ac2a4a 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:107:1
    |
 LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
@@ -90,7 +90,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:133:1
    |
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
diff --git a/src/test/ui/consts/const-size_of-cycle.rs b/src/test/ui/consts/const-size_of-cycle.rs
index 1bbe881872c..6c35b9212c6 100644
--- a/src/test/ui/consts/const-size_of-cycle.rs
+++ b/src/test/ui/consts/const-size_of-cycle.rs
@@ -1,5 +1,4 @@
-// ignore-musl
-// ignore-x86
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // error-pattern: cycle detected
 
 struct Foo {
diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr
index 1ae39e7563a..5b06ade44c5 100644
--- a/src/test/ui/consts/const-size_of-cycle.stderr
+++ b/src/test/ui/consts/const-size_of-cycle.stderr
@@ -1,11 +1,11 @@
 error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0`
-  --> $DIR/const-size_of-cycle.rs:6:17
+  --> $DIR/const-size_of-cycle.rs:5:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
-  --> $DIR/const-size_of-cycle.rs:6:17
+  --> $DIR/const-size_of-cycle.rs:5:17
    |
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     pub fn size_of<T>() -> usize;
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
    = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
-  --> $DIR/const-size_of-cycle.rs:5:1
+  --> $DIR/const-size_of-cycle.rs:4:1
    |
 LL | struct Foo {
    | ^^^^^^^^^^
diff --git a/src/test/ui/consts/const_let_promote.rs b/src/test/ui/consts/const_let_promote.rs
new file mode 100644
index 00000000000..f4661e9e425
--- /dev/null
+++ b/src/test/ui/consts/const_let_promote.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+use std::cell::Cell;
+
+const X: Option<Cell<i32>> = None;
+
+const Y: Option<Cell<i32>> = {
+    let x = None;
+    x
+};
+
+// Ensure that binding the final value of a `const` to a variable does not affect promotion.
+#[allow(unused)]
+fn main() {
+    let x: &'static _ = &X;
+    let y: &'static _ = &Y;
+}
diff --git a/src/test/ui/consts/issue-62045.rs b/src/test/ui/consts/issue-62045.rs
index efeb9fc551c..5abed374a6d 100644
--- a/src/test/ui/consts/issue-62045.rs
+++ b/src/test/ui/consts/issue-62045.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     assert_eq!(&mut [0; 1][..], &mut []);
diff --git a/src/test/ui/consts/promote_borrowed_field.rs b/src/test/ui/consts/promote_borrowed_field.rs
new file mode 100644
index 00000000000..c4841b46f60
--- /dev/null
+++ b/src/test/ui/consts/promote_borrowed_field.rs
@@ -0,0 +1,12 @@
+// run-pass
+
+// From https://github.com/rust-lang/rust/issues/65727
+
+const _: &i32 = {
+    let x = &(5, false).0;
+    x
+};
+
+fn main() {
+    let _: &'static i32 = &(5, false).0;
+}
diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
index b556d442420..da00f81b96e 100644
--- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
index 7db5fbe3de4..796e6a2b744 100644
--- a/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Clone-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Clone-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-enum.rs b/src/test/ui/derives/derives-span-Clone-enum.rs
index 9bb4f486c3e..98ae1b2c5b8 100644
--- a/src/test/ui/derives/derives-span-Clone-enum.rs
+++ b/src/test/ui/derives/derives-span-Clone-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-enum.stderr b/src/test/ui/derives/derives-span-Clone-enum.stderr
index 4371dc900ac..3e94bb551ea 100644
--- a/src/test/ui/derives/derives-span-Clone-enum.stderr
+++ b/src/test/ui/derives/derives-span-Clone-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-enum.rs:9:6
+  --> $DIR/derives-span-Clone-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-struct.rs b/src/test/ui/derives/derives-span-Clone-struct.rs
index f151636f848..db677e26f50 100644
--- a/src/test/ui/derives/derives-span-Clone-struct.rs
+++ b/src/test/ui/derives/derives-span-Clone-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-struct.stderr b/src/test/ui/derives/derives-span-Clone-struct.stderr
index cc3b602c9c0..0674d64fe9d 100644
--- a/src/test/ui/derives/derives-span-Clone-struct.stderr
+++ b/src/test/ui/derives/derives-span-Clone-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-struct.rs:8:5
+  --> $DIR/derives-span-Clone-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.rs b/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
index 7a62885324e..d716b6fe900 100644
--- a/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
index b2bf3527b0c..f6b4006014a 100644
--- a/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Clone-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::clone::Clone` is not satisfied
-  --> $DIR/derives-span-Clone-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Clone-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::clone::Clone` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
index 949597bc8f6..10deccb8ad7 100644
--- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
index ca5bcfe930d..6a0e382b9e5 100644
--- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Debug-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-enum.rs b/src/test/ui/derives/derives-span-Debug-enum.rs
index b2a39708ceb..b8bed0eab55 100644
--- a/src/test/ui/derives/derives-span-Debug-enum.rs
+++ b/src/test/ui/derives/derives-span-Debug-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-enum.stderr b/src/test/ui/derives/derives-span-Debug-enum.stderr
index cd367a334fc..f27499ba441 100644
--- a/src/test/ui/derives/derives-span-Debug-enum.stderr
+++ b/src/test/ui/derives/derives-span-Debug-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-enum.rs:9:6
+  --> $DIR/derives-span-Debug-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-struct.rs b/src/test/ui/derives/derives-span-Debug-struct.rs
index cf91c9436a6..22f037ee36f 100644
--- a/src/test/ui/derives/derives-span-Debug-struct.rs
+++ b/src/test/ui/derives/derives-span-Debug-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-struct.stderr b/src/test/ui/derives/derives-span-Debug-struct.stderr
index e00695ec0ba..09d62f12b04 100644
--- a/src/test/ui/derives/derives-span-Debug-struct.stderr
+++ b/src/test/ui/derives/derives-span-Debug-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-struct.rs:8:5
+  --> $DIR/derives-span-Debug-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.rs b/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
index cea973c91a7..c693facfeaa 100644
--- a/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
index 37440b59ae7..f100cf32fdf 100644
--- a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Error` doesn't implement `std::fmt::Debug`
-  --> $DIR/derives-span-Debug-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Debug-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ `Error` cannot be formatted using `{:?}`
diff --git a/src/test/ui/derives/derives-span-Default-struct.rs b/src/test/ui/derives/derives-span-Default-struct.rs
index 71fd5829e75..1654883998d 100644
--- a/src/test/ui/derives/derives-span-Default-struct.rs
+++ b/src/test/ui/derives/derives-span-Default-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Default-struct.stderr b/src/test/ui/derives/derives-span-Default-struct.stderr
index 413d4ec8c29..11664d400ee 100644
--- a/src/test/ui/derives/derives-span-Default-struct.stderr
+++ b/src/test/ui/derives/derives-span-Default-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::default::Default` is not satisfied
-  --> $DIR/derives-span-Default-struct.rs:8:5
+  --> $DIR/derives-span-Default-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::default::Default` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.rs b/src/test/ui/derives/derives-span-Default-tuple-struct.rs
index 463f7d230ca..f1390c8b6f6 100644
--- a/src/test/ui/derives/derives-span-Default-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Default-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
index 8f4d43daa51..c79f093942f 100644
--- a/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Default-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::default::Default` is not satisfied
-  --> $DIR/derives-span-Default-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Default-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::default::Default` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
index d2dab8687f7..77c386d7f90 100644
--- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
index 52ecce4632d..87c0313ca1f 100644
--- a/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Eq-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Eq-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-enum.rs b/src/test/ui/derives/derives-span-Eq-enum.rs
index c6c0d432108..c7fe3781332 100644
--- a/src/test/ui/derives/derives-span-Eq-enum.rs
+++ b/src/test/ui/derives/derives-span-Eq-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-enum.stderr b/src/test/ui/derives/derives-span-Eq-enum.stderr
index bf91a0edc37..c8db6d3ff2f 100644
--- a/src/test/ui/derives/derives-span-Eq-enum.stderr
+++ b/src/test/ui/derives/derives-span-Eq-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-enum.rs:9:6
+  --> $DIR/derives-span-Eq-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-struct.rs b/src/test/ui/derives/derives-span-Eq-struct.rs
index df310039847..8674cadb309 100644
--- a/src/test/ui/derives/derives-span-Eq-struct.rs
+++ b/src/test/ui/derives/derives-span-Eq-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-struct.stderr b/src/test/ui/derives/derives-span-Eq-struct.stderr
index 531e8887cd2..df4ea5b1d41 100644
--- a/src/test/ui/derives/derives-span-Eq-struct.stderr
+++ b/src/test/ui/derives/derives-span-Eq-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-struct.rs:8:5
+  --> $DIR/derives-span-Eq-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.rs b/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
index abf6526b900..99cc9582b5b 100644
--- a/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
index 9e21c6c67bf..def06d71086 100644
--- a/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Eq-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Eq` is not satisfied
-  --> $DIR/derives-span-Eq-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Eq-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::cmp::Eq` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
index ed87360a0be..604b0842fa9 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
index 708ebca9fb1..cc1caf78041 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum-struct-variant.rs:11:6
+  --> $DIR/derives-span-Hash-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum.rs b/src/test/ui/derives/derives-span-Hash-enum.rs
index 5b3649c9826..bf3033a232c 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr
index dc171cbe5dd..246d821ed2b 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum.rs:11:6
+  --> $DIR/derives-span-Hash-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-struct.rs b/src/test/ui/derives/derives-span-Hash-struct.rs
index ead70861a0a..b6abb9d229e 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-struct.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr
index 429449b82bf..720c127635e 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-struct.rs:10:5
+  --> $DIR/derives-span-Hash-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
index 820f13ed18e..e01351fe8a6 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
index a6c4c479b24..1fd1e601eca 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-tuple-struct.rs:10:5
+  --> $DIR/derives-span-Hash-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
index 62355cc2d96..6d516d4b0ad 100644
--- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
index 5c0d4e4ebe9..f0d7e4465a7 100644
--- a/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Ord-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Ord-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-enum.rs b/src/test/ui/derives/derives-span-Ord-enum.rs
index 72738931d10..51b5d7f0ed1 100644
--- a/src/test/ui/derives/derives-span-Ord-enum.rs
+++ b/src/test/ui/derives/derives-span-Ord-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-enum.stderr b/src/test/ui/derives/derives-span-Ord-enum.stderr
index 56268a23745..37eca92e77e 100644
--- a/src/test/ui/derives/derives-span-Ord-enum.stderr
+++ b/src/test/ui/derives/derives-span-Ord-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-enum.rs:9:6
+  --> $DIR/derives-span-Ord-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-struct.rs b/src/test/ui/derives/derives-span-Ord-struct.rs
index 53d4c2c22b5..c924ecaa315 100644
--- a/src/test/ui/derives/derives-span-Ord-struct.rs
+++ b/src/test/ui/derives/derives-span-Ord-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-struct.stderr b/src/test/ui/derives/derives-span-Ord-struct.stderr
index 40dc3d09dad..72c1fe4803c 100644
--- a/src/test/ui/derives/derives-span-Ord-struct.stderr
+++ b/src/test/ui/derives/derives-span-Ord-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-struct.rs:8:5
+  --> $DIR/derives-span-Ord-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.rs b/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
index 4e09c270986..80546634690 100644
--- a/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(Eq,PartialOrd,PartialEq)]
diff --git a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
index 4a9dea8c12e..642c8579b51 100644
--- a/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Ord-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::cmp::Ord` is not satisfied
-  --> $DIR/derives-span-Ord-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Ord-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::cmp::Ord` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
index d66faa086de..b13798686c0 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
index ed5468cc4da..d6a56525601 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^
@@ -7,7 +7,7 @@ LL |      x: Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.rs b/src/test/ui/derives/derives-span-PartialEq-enum.rs
index 66edf460b31..5f8f05ad94b 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-enum.stderr b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
index 06a88c03f58..1f5ad42a3aa 100644
--- a/src/test/ui/derives/derives-span-PartialEq-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-enum.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^
@@ -7,7 +7,7 @@ LL |      Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-enum.rs:9:6
+  --> $DIR/derives-span-PartialEq-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.rs b/src/test/ui/derives/derives-span-PartialEq-struct.rs
index ce5c67af77f..560bf582e8d 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
index b8481048361..4e0b2fa4e6f 100644
--- a/src/test/ui/derives/derives-span-PartialEq-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-struct.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^
@@ -7,7 +7,7 @@ LL |     x: Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
index eaa62831136..09a3249f059 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
index 4398d252125..78e215534e0 100644
--- a/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialEq-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0369]: binary operation `==` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^
@@ -7,7 +7,7 @@ LL |     Error
    = note: an implementation of `std::cmp::PartialEq` might be missing for `Error`
 
 error[E0369]: binary operation `!=` cannot be applied to type `Error`
-  --> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
+  --> $DIR/derives-span-PartialEq-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
index 0bc6f98d982..0d18bdc113a 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
index ac9f4504635..a6f0c873e2f 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:10:6
    |
 LL |      x: Error
    |      ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.rs b/src/test/ui/derives/derives-span-PartialOrd-enum.rs
index ee4423f3bee..78e4babb976 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
index 3e684aef39f..838126111c3 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-enum.rs:9:6
+  --> $DIR/derives-span-PartialOrd-enum.rs:10:6
    |
 LL |      Error
    |      ^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-struct.rs
index 48435e0cd45..728ec75b6c4 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
index 10659aac642..2df64d915a9 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-struct.rs:8:5
+  --> $DIR/derives-span-PartialOrd-struct.rs:9:5
    |
 LL |     x: Error
    |     ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
index 2aa412e6d1d..c92b47e9297 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.rs
@@ -1,3 +1,4 @@
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
index cbe05e37840..63aebe32ed2 100644
--- a/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-PartialOrd-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: can't compare `Error` with `Error`
-  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
+  --> $DIR/derives-span-PartialOrd-tuple-struct.rs:9:5
    |
 LL |     Error
    |     ^^^^^ no implementation for `Error < Error` and `Error > Error`
diff --git a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
index 2718e89a3f2..4cb9bd1975a 100644
--- a/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
+++ b/src/test/ui/dyn-keyword/issue-56327-dyn-trait-in-macro-is-okay.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#56327: Some occurrences of `dyn` within a macro are
 // not instances of identifiers, and thus should *not* be caught by the
diff --git a/src/test/ui/enum-discriminant/discriminant_value.rs b/src/test/ui/enum-discriminant/discriminant_value.rs
index b7000015c71..32d2d40241c 100644
--- a/src/test/ui/enum-discriminant/discriminant_value.rs
+++ b/src/test/ui/enum-discriminant/discriminant_value.rs
@@ -51,34 +51,31 @@ enum Mixed {
 }
 
 pub fn main() {
-    unsafe {
+    assert_eq!(discriminant_value(&CLike1::A), 0);
+    assert_eq!(discriminant_value(&CLike1::B), 1);
+    assert_eq!(discriminant_value(&CLike1::C), 2);
+    assert_eq!(discriminant_value(&CLike1::D), 3);
 
-        assert_eq!(discriminant_value(&CLike1::A), 0);
-        assert_eq!(discriminant_value(&CLike1::B), 1);
-        assert_eq!(discriminant_value(&CLike1::C), 2);
-        assert_eq!(discriminant_value(&CLike1::D), 3);
+    assert_eq!(discriminant_value(&CLike2::A), 5);
+    assert_eq!(discriminant_value(&CLike2::B), 2);
+    assert_eq!(discriminant_value(&CLike2::C), 19);
+    assert_eq!(discriminant_value(&CLike2::D), 20);
 
-        assert_eq!(discriminant_value(&CLike2::A), 5);
-        assert_eq!(discriminant_value(&CLike2::B), 2);
-        assert_eq!(discriminant_value(&CLike2::C), 19);
-        assert_eq!(discriminant_value(&CLike2::D), 20);
+    assert_eq!(discriminant_value(&CLike3::A), 5);
+    assert_eq!(discriminant_value(&CLike3::B), 6);
+    assert_eq!(discriminant_value(&CLike3::C), -1_i8 as u64);
+    assert_eq!(discriminant_value(&CLike3::D), 0);
 
-        assert_eq!(discriminant_value(&CLike3::A), 5);
-        assert_eq!(discriminant_value(&CLike3::B), 6);
-        assert_eq!(discriminant_value(&CLike3::C), -1_i8 as u64);
-        assert_eq!(discriminant_value(&CLike3::D), 0);
+    assert_eq!(discriminant_value(&ADT::First(0,0)), 0);
+    assert_eq!(discriminant_value(&ADT::Second(5)), 1);
 
-        assert_eq!(discriminant_value(&ADT::First(0,0)), 0);
-        assert_eq!(discriminant_value(&ADT::Second(5)), 1);
+    assert_eq!(discriminant_value(&NullablePointer::Nothing), 1);
+    assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0);
 
-        assert_eq!(discriminant_value(&NullablePointer::Nothing), 1);
-        assert_eq!(discriminant_value(&NullablePointer::Something(&CONST)), 0);
+    assert_eq!(discriminant_value(&10), 0);
+    assert_eq!(discriminant_value(&"test"), 0);
 
-        assert_eq!(discriminant_value(&10), 0);
-        assert_eq!(discriminant_value(&"test"), 0);
-
-        assert_eq!(3, discriminant_value(&Mixed::Unit));
-        assert_eq!(2, discriminant_value(&Mixed::Tuple(5)));
-        assert_eq!(1, discriminant_value(&Mixed::Struct{a: 7, b: 11}));
-    }
+    assert_eq!(3, discriminant_value(&Mixed::Unit));
+    assert_eq!(2, discriminant_value(&Mixed::Tuple(5)));
+    assert_eq!(1, discriminant_value(&Mixed::Struct{a: 7, b: 11}));
 }
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
index dab946bb818..75a3d9124eb 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs
@@ -3,7 +3,7 @@
 // `#![macro_escape]` is incompatible with crate-level `#![macro_use]`
 // already present in issue-43106-gating-of-builtin-attrs.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![macro_escape]
 //~^ WARN macro_escape is a deprecated synonym for macro_use
diff --git a/src/test/ui/feature-gated-feature-in-macro-arg.stderr b/src/test/ui/feature-gated-feature-in-macro-arg.stderr
index 5ee05154c3a..218e0292776 100644
--- a/src/test/ui/feature-gated-feature-in-macro-arg.stderr
+++ b/src/test/ui/feature-gated-feature-in-macro-arg.stderr
@@ -1,10 +1,8 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gated-feature-in-macro-arg.rs:8:9
+  --> $DIR/feature-gated-feature-in-macro-arg.rs:8:16
    |
-LL | /         extern "rust-intrinsic" {
-LL | |             fn atomic_fence();
-LL | |         }
-   | |_________^
+LL |         extern "rust-intrinsic" {
+   |                ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
diff --git a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
index 0d2e355535d..d58a2d91b2b 100644
--- a/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi-msp430-interrupt.stderr
@@ -1,8 +1,8 @@
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi-msp430-interrupt.rs:4:1
+  --> $DIR/feature-gate-abi-msp430-interrupt.rs:4:8
    |
 LL | extern "msp430-interrupt" fn foo() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr
index 0f2622f1065..6db6cb49cef 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi.stderr
@@ -1,591 +1,591 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:13:1
+  --> $DIR/feature-gate-abi.rs:13:8
    |
 LL | extern "rust-intrinsic" fn f1() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:15:1
+  --> $DIR/feature-gate-abi.rs:15:8
    |
 LL | extern "platform-intrinsic" fn f2() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:17:1
+  --> $DIR/feature-gate-abi.rs:17:8
    |
 LL | extern "vectorcall" fn f3() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:18:1
+  --> $DIR/feature-gate-abi.rs:18:8
    |
 LL | extern "rust-call" fn f4() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:19:1
+  --> $DIR/feature-gate-abi.rs:19:8
    |
 LL | extern "msp430-interrupt" fn f5() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:20:1
+  --> $DIR/feature-gate-abi.rs:20:8
    |
 LL | extern "ptx-kernel" fn f6() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:21:1
+  --> $DIR/feature-gate-abi.rs:21:8
    |
 LL | extern "x86-interrupt" fn f7() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:22:1
+  --> $DIR/feature-gate-abi.rs:22:8
    |
 LL | extern "thiscall" fn f8() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:23:1
+  --> $DIR/feature-gate-abi.rs:23:8
    |
 LL | extern "amdgpu-kernel" fn f9() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:24:1
+  --> $DIR/feature-gate-abi.rs:24:8
    |
 LL | extern "efiapi" fn f10() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:28:5
+  --> $DIR/feature-gate-abi.rs:28:12
    |
 LL |     extern "rust-intrinsic" fn m1();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:30:5
+  --> $DIR/feature-gate-abi.rs:30:12
    |
 LL |     extern "platform-intrinsic" fn m2();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:32:5
+  --> $DIR/feature-gate-abi.rs:32:12
    |
 LL |     extern "vectorcall" fn m3();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:33:5
+  --> $DIR/feature-gate-abi.rs:33:12
    |
 LL |     extern "rust-call" fn m4();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:34:5
+  --> $DIR/feature-gate-abi.rs:34:12
    |
 LL |     extern "msp430-interrupt" fn m5();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:35:5
+  --> $DIR/feature-gate-abi.rs:35:12
    |
 LL |     extern "ptx-kernel" fn m6();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:36:5
+  --> $DIR/feature-gate-abi.rs:36:12
    |
 LL |     extern "x86-interrupt" fn m7();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:37:5
+  --> $DIR/feature-gate-abi.rs:37:12
    |
 LL |     extern "thiscall" fn m8();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:38:5
+  --> $DIR/feature-gate-abi.rs:38:12
    |
 LL |     extern "amdgpu-kernel" fn m9();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:39:5
+  --> $DIR/feature-gate-abi.rs:39:12
    |
 LL |     extern "efiapi" fn m10();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:41:5
+  --> $DIR/feature-gate-abi.rs:41:12
    |
 LL |     extern "vectorcall" fn dm3() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:42:5
+  --> $DIR/feature-gate-abi.rs:42:12
    |
 LL |     extern "rust-call" fn dm4() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:43:5
+  --> $DIR/feature-gate-abi.rs:43:12
    |
 LL |     extern "msp430-interrupt" fn dm5() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:44:5
+  --> $DIR/feature-gate-abi.rs:44:12
    |
 LL |     extern "ptx-kernel" fn dm6() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:45:5
+  --> $DIR/feature-gate-abi.rs:45:12
    |
 LL |     extern "x86-interrupt" fn dm7() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:46:5
+  --> $DIR/feature-gate-abi.rs:46:12
    |
 LL |     extern "thiscall" fn dm8() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:47:5
+  --> $DIR/feature-gate-abi.rs:47:12
    |
 LL |     extern "amdgpu-kernel" fn dm9() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:48:5
+  --> $DIR/feature-gate-abi.rs:48:12
    |
 LL |     extern "efiapi" fn dm10() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:55:5
+  --> $DIR/feature-gate-abi.rs:55:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:57:5
+  --> $DIR/feature-gate-abi.rs:57:12
    |
 LL |     extern "platform-intrinsic" fn m2() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:59:5
+  --> $DIR/feature-gate-abi.rs:59:12
    |
 LL |     extern "vectorcall" fn m3() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:60:5
+  --> $DIR/feature-gate-abi.rs:60:12
    |
 LL |     extern "rust-call" fn m4() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:61:5
+  --> $DIR/feature-gate-abi.rs:61:12
    |
 LL |     extern "msp430-interrupt" fn m5() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:62:5
+  --> $DIR/feature-gate-abi.rs:62:12
    |
 LL |     extern "ptx-kernel" fn m6() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:63:5
+  --> $DIR/feature-gate-abi.rs:63:12
    |
 LL |     extern "x86-interrupt" fn m7() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:64:5
+  --> $DIR/feature-gate-abi.rs:64:12
    |
 LL |     extern "thiscall" fn m8() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:65:5
+  --> $DIR/feature-gate-abi.rs:65:12
    |
 LL |     extern "amdgpu-kernel" fn m9() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:66:5
+  --> $DIR/feature-gate-abi.rs:66:12
    |
 LL |     extern "efiapi" fn m10() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:71:5
+  --> $DIR/feature-gate-abi.rs:71:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:73:5
+  --> $DIR/feature-gate-abi.rs:73:12
    |
 LL |     extern "platform-intrinsic" fn im2() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:75:5
+  --> $DIR/feature-gate-abi.rs:75:12
    |
 LL |     extern "vectorcall" fn im3() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:76:5
+  --> $DIR/feature-gate-abi.rs:76:12
    |
 LL |     extern "rust-call" fn im4() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:77:5
+  --> $DIR/feature-gate-abi.rs:77:12
    |
 LL |     extern "msp430-interrupt" fn im5() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:78:5
+  --> $DIR/feature-gate-abi.rs:78:12
    |
 LL |     extern "ptx-kernel" fn im6() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:79:5
+  --> $DIR/feature-gate-abi.rs:79:12
    |
 LL |     extern "x86-interrupt" fn im7() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:80:5
+  --> $DIR/feature-gate-abi.rs:80:12
    |
 LL |     extern "thiscall" fn im8() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:81:5
+  --> $DIR/feature-gate-abi.rs:81:12
    |
 LL |     extern "amdgpu-kernel" fn im9() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:82:5
+  --> $DIR/feature-gate-abi.rs:82:12
    |
 LL |     extern "efiapi" fn im10() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:86:11
+  --> $DIR/feature-gate-abi.rs:86:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:87:11
+  --> $DIR/feature-gate-abi.rs:87:18
    |
 LL | type A2 = extern "platform-intrinsic" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:88:11
+  --> $DIR/feature-gate-abi.rs:88:18
    |
 LL | type A3 = extern "vectorcall" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:89:11
+  --> $DIR/feature-gate-abi.rs:89:18
    |
 LL | type A4 = extern "rust-call" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:90:11
+  --> $DIR/feature-gate-abi.rs:90:18
    |
 LL | type A5 = extern "msp430-interrupt" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:91:11
+  --> $DIR/feature-gate-abi.rs:91:18
    |
 LL | type A6 = extern "ptx-kernel" fn ();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:92:11
+  --> $DIR/feature-gate-abi.rs:92:18
    |
 LL | type A7 = extern "x86-interrupt" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:93:11
+  --> $DIR/feature-gate-abi.rs:93:18
    |
 LL | type A8 = extern "thiscall" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:94:11
+  --> $DIR/feature-gate-abi.rs:94:18
    |
 LL | type A9 = extern "amdgpu-kernel" fn();
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:95:12
+  --> $DIR/feature-gate-abi.rs:95:19
    |
 LL | type A10 = extern "efiapi" fn();
-   |            ^^^^^^^^^^^^^^^^^^^^
+   |                   ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:98:1
+  --> $DIR/feature-gate-abi.rs:98:8
    |
 LL | extern "rust-intrinsic" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:99:1
+  --> $DIR/feature-gate-abi.rs:99:8
    |
 LL | extern "platform-intrinsic" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/27731
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:100:1
+  --> $DIR/feature-gate-abi.rs:100:8
    |
 LL | extern "vectorcall" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:101:1
+  --> $DIR/feature-gate-abi.rs:101:8
    |
 LL | extern "rust-call" {}
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:102:1
+  --> $DIR/feature-gate-abi.rs:102:8
    |
 LL | extern "msp430-interrupt" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38487
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:103:1
+  --> $DIR/feature-gate-abi.rs:103:8
    |
 LL | extern "ptx-kernel" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/38788
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:104:1
+  --> $DIR/feature-gate-abi.rs:104:8
    |
 LL | extern "x86-interrupt" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/40180
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:105:1
+  --> $DIR/feature-gate-abi.rs:105:8
    |
 LL | extern "thiscall" {}
-   | ^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^
    |
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:106:1
+  --> $DIR/feature-gate-abi.rs:106:8
    |
 LL | extern "amdgpu-kernel" {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: efiapi ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:107:1
+  --> $DIR/feature-gate-abi.rs:107:8
    |
 LL | extern "efiapi" {}
-   | ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/65815
    = help: add `#![feature(abi_efiapi)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr
index 4954a7d1f71..1757befec35 100644
--- a/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi_unadjusted.stderr
@@ -1,10 +1,8 @@
 error[E0658]: unadjusted ABI is an implementation detail and perma-unstable
-  --> $DIR/feature-gate-abi_unadjusted.rs:1:1
+  --> $DIR/feature-gate-abi_unadjusted.rs:1:8
    |
-LL | / extern "unadjusted" fn foo() {
-LL | |
-LL | | }
-   | |_^
+LL | extern "unadjusted" fn foo() {
+   |        ^^^^^^^^^^^^
    |
    = help: add `#![feature(abi_unadjusted)]` to the crate attributes to enable
 
diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
index 101a10e8df7..8f943d357ce 100644
--- a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
+++ b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
@@ -1,18 +1,16 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-intrinsics.rs:1:1
+  --> $DIR/feature-gate-intrinsics.rs:1:8
    |
-LL | / extern "rust-intrinsic" {
-LL | |     fn bar();
-LL | | }
-   | |_^
+LL | extern "rust-intrinsic" {
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-intrinsics.rs:5:1
+  --> $DIR/feature-gate-intrinsics.rs:5:8
    |
 LL | extern "rust-intrinsic" fn baz() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
    |
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs b/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs
deleted file mode 100644
index bec1531c533..00000000000
--- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Test that `#[rustc_on_unimplemented]` is gated by `on_unimplemented` feature
-// gate.
-
-#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
-//~^ ERROR the `#[rustc_on_unimplemented]` attribute is an experimental feature
-trait Foo<Bar>
-{}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index c05379c71ee..657bf13c873 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -1,35 +1,35 @@
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:11:12
    |
 LL |     extern "rust-call" fn call(self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:17:12
    |
 LL |     extern "rust-call" fn call_once(self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:23:12
    |
 LL |     extern "rust-call" fn call_mut(&self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:5
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:29:12
    |
 LL |     extern "rust-call" fn call_once(&self, args: ()) -> () {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
index 723c6619887..f343a42eb8f 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures.stderr
@@ -1,10 +1,8 @@
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-unboxed-closures.rs:9:5
+  --> $DIR/feature-gate-unboxed-closures.rs:9:12
    |
-LL | /     extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
-LL | |         a + b
-LL | |     }
-   | |_____^
+LL |     extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 {
+   |            ^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/29625
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
diff --git a/src/test/ui/generator/issue-53548-1.rs b/src/test/ui/generator/issue-53548-1.rs
index 395456ce7c6..173ae3c6fb6 100644
--- a/src/test/ui/generator/issue-53548-1.rs
+++ b/src/test/ui/generator/issue-53548-1.rs
@@ -2,7 +2,7 @@
 // but which encountered the same ICE/error. See `issue-53548.rs`
 // for details.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::cell::RefCell;
 use std::rc::Rc;
diff --git a/src/test/ui/generator/issue-53548.rs b/src/test/ui/generator/issue-53548.rs
index 8136c65923b..3ebabb91462 100644
--- a/src/test/ui/generator/issue-53548.rs
+++ b/src/test/ui/generator/issue-53548.rs
@@ -15,7 +15,7 @@
 // also analogous to what we would do for higher-ranked regions
 // appearing within the trait in other positions).
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(generators)]
 
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.rs b/src/test/ui/impl-trait/impl-generic-mismatch.rs
index f4fba4c34c1..5597df4ba49 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.rs
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.rs
@@ -1,5 +1,4 @@
-// ignore-musl
-// ignore-x86
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 
 use std::fmt::Debug;
 
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.stderr b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
index bfe94119a02..2278519e95a 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0643]: method `foo` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:11:12
+  --> $DIR/impl-generic-mismatch.rs:10:12
    |
 LL |     fn foo(&self, _: &impl Debug);
    |                       ---------- declaration in trait here
@@ -13,7 +13,7 @@ LL |     fn foo(&self, _: &impl Debug) { }
    |          --           ^^^^^^^^^^
 
 error[E0643]: method `bar` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:20:23
+  --> $DIR/impl-generic-mismatch.rs:19:23
    |
 LL |     fn bar<U: Debug>(&self, _: &U);
    |            - declaration in trait here
@@ -27,7 +27,7 @@ LL |     fn bar<U: Debug>(&self, _: &U) { }
    |           ^^^^^^^^^^            ^
 
 error[E0643]: method `hash` has incompatible signature for trait
-  --> $DIR/impl-generic-mismatch.rs:31:33
+  --> $DIR/impl-generic-mismatch.rs:30:33
    |
 LL |     fn hash(&self, hasher: &mut impl Hasher) {}
    |                                 ^^^^^^^^^^^ expected generic parameter, found `impl Trait`
diff --git a/src/test/ui/impl-trait/issues/issue-42479.rs b/src/test/ui/impl-trait/issues/issue-42479.rs
index 7d69cd0a303..efc1f975d16 100644
--- a/src/test/ui/impl-trait/issues/issue-42479.rs
+++ b/src/test/ui/impl-trait/issues/issue-42479.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::iter::once;
 
diff --git a/src/test/ui/impl-trait/issues/issue-49376.rs b/src/test/ui/impl-trait/issues/issue-49376.rs
index 12e69b16adf..e4472fcc160 100644
--- a/src/test/ui/impl-trait/issues/issue-49376.rs
+++ b/src/test/ui/impl-trait/issues/issue-49376.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Tests for nested self-reference which caused a stack overflow.
 
diff --git a/src/test/ui/impl-trait/issues/issue-52128.rs b/src/test/ui/impl-trait/issues/issue-52128.rs
index ac26c10e55d..5afd380dd4f 100644
--- a/src/test/ui/impl-trait/issues/issue-52128.rs
+++ b/src/test/ui/impl-trait/issues/issue-52128.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![deny(warnings)]
 
diff --git a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
index 0c07101bb7b..0c34c97e258 100644
--- a/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
+++ b/src/test/ui/impl-trait/issues/issue-55608-captures-empty-region.rs
@@ -1,7 +1,7 @@
 // This used to ICE because it creates an `impl Trait` that captures a
 // hidden empty region.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn server() -> impl FilterBase2 {
     segment2(|| { loop { } }).map2(|| "")
diff --git a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
index ed066ce1924..c4f738a34b6 100644
--- a/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
+++ b/src/test/ui/impl-trait/issues/issue-57464-unexpected-regions.rs
@@ -5,7 +5,7 @@
 // opaque type. As all regions are now required to outlive the bound in an
 // opaque type we avoid the issue here.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct A<F>(F);
 
diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr
index 129d7ef5783..151dc681621 100644
--- a/src/test/ui/impl-trait/trait_type.stderr
+++ b/src/test/ui/impl-trait/trait_type.stderr
@@ -29,7 +29,7 @@ error[E0046]: not all trait items implemented, missing: `fmt`
 LL | impl std::fmt::Display for MyType4 {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
    |
-   = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+   = help: implement the missing item: `fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { unimplemented!() }`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
index ce8c2d5168f..abcc92ce34d 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // aux-build:two_macros.rs
 
 macro_rules! define_vec {
diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
index 8e01fc8df3d..7a55abe4255 100644
--- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
+++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr
@@ -1,5 +1,5 @@
 error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:21:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:20:9
    |
 LL |         extern crate std as core;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,13 +8,13 @@ LL | define_other_core!();
    | --------------------- in this macro invocation
 
 error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:14:9
    |
 LL |         Vec::panic!();
    |         ^^^ ambiguous name
    |
 note: `Vec` could refer to the crate imported here
-  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9
+  --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:6:9
    |
 LL |         extern crate std as Vec;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/imports/issue-53140.rs b/src/test/ui/imports/issue-53140.rs
index 1854ddf96b8..7b4cc176806 100644
--- a/src/test/ui/imports/issue-53140.rs
+++ b/src/test/ui/imports/issue-53140.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 mod m {
     pub struct S(u8);
diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs
index 8cb602d868c..2df328cca89 100644
--- a/src/test/ui/imports/issue-55811.rs
+++ b/src/test/ui/imports/issue-55811.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // aux-build:issue-55811.rs
 
 extern crate issue_55811;
diff --git a/src/test/ui/imports/issue-56263.rs b/src/test/ui/imports/issue-56263.rs
index 4763ae4be99..363781f2daf 100644
--- a/src/test/ui/imports/issue-56263.rs
+++ b/src/test/ui/imports/issue-56263.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 use ::std;
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
index eca9a67fcb3..369de040070 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::ops::Deref;
 trait Trait {}
 
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
index d3862e3d4df..8086d3f1fbc 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
@@ -1,5 +1,5 @@
 error: `impl` item signature doesn't match `trait` item signature
-  --> $DIR/mismatched_trait_impl-2.rs:10:5
+  --> $DIR/mismatched_trait_impl-2.rs:9:5
    |
 LL |     fn deref(&self) -> &dyn Trait {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found fn(&Struct) -> &dyn Trait
diff --git a/src/test/ui/interior-mutability/interior-mutability.rs b/src/test/ui/interior-mutability/interior-mutability.rs
index 6968e3669ca..60633fdd393 100644
--- a/src/test/ui/interior-mutability/interior-mutability.rs
+++ b/src/test/ui/interior-mutability/interior-mutability.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::cell::Cell;
 use std::panic::catch_unwind;
 fn main() {
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index b76fce28805..5c129524f51 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
-  --> $DIR/interior-mutability.rs:7:5
+  --> $DIR/interior-mutability.rs:6:5
    |
 LL |     catch_unwind(|| { x.set(23); });
    |     ^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -12,7 +12,7 @@ LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
    = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<i32>`
-   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:7:18: 7:35 x:&std::cell::Cell<i32>]`
+   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:6:18: 6:35 x:&std::cell::Cell<i32>]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-10396.rs b/src/test/ui/issues/issue-10396.rs
index 0781e5e3ed9..d16ea3dc344 100644
--- a/src/test/ui/issues/issue-10396.rs
+++ b/src/test/ui/issues/issue-10396.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Debug)]
 enum Foo<'s> {
diff --git a/src/test/ui/issues/issue-10456.rs b/src/test/ui/issues/issue-10456.rs
index 7eac095de5d..9f8d2595520 100644
--- a/src/test/ui/issues/issue-10456.rs
+++ b/src/test/ui/issues/issue-10456.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub struct Foo;
diff --git a/src/test/ui/issues/issue-10763.rs b/src/test/ui/issues/issue-10763.rs
index 091a7c52963..627a8c2384c 100644
--- a/src/test/ui/issues/issue-10763.rs
+++ b/src/test/ui/issues/issue-10763.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-10853.rs b/src/test/ui/issues/issue-10853.rs
index c9de39feda6..3dcabf9b165 100644
--- a/src/test/ui/issues/issue-10853.rs
+++ b/src/test/ui/issues/issue-10853.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![deny(missing_docs)]
diff --git a/src/test/ui/issues/issue-10902.rs b/src/test/ui/issues/issue-10902.rs
index d53ce9a1db8..162482d49ab 100644
--- a/src/test/ui/issues/issue-10902.rs
+++ b/src/test/ui/issues/issue-10902.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-11384.rs b/src/test/ui/issues/issue-11384.rs
index 443c2be08bb..0105b4d223e 100644
--- a/src/test/ui/issues/issue-11384.rs
+++ b/src/test/ui/issues/issue-11384.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Common { fn dummy(&self) { } }
diff --git a/src/test/ui/issues/issue-11592.rs b/src/test/ui/issues/issue-11592.rs
index 0298f83baf8..a4611f2f90e 100644
--- a/src/test/ui/issues/issue-11592.rs
+++ b/src/test/ui/issues/issue-11592.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 //! Ensure the private trait Bar isn't complained about.
 
 #![deny(missing_docs)]
diff --git a/src/test/ui/issues/issue-11612.rs b/src/test/ui/issues/issue-11612.rs
index 553648a5ebc..9f7f1cc6fc7 100644
--- a/src/test/ui/issues/issue-11612.rs
+++ b/src/test/ui/issues/issue-11612.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // #11612
 // We weren't updating the auto adjustments with all the resolved
diff --git a/src/test/ui/issues/issue-11869.rs b/src/test/ui/issues/issue-11869.rs
index a44094bfb23..b300f4593a7 100644
--- a/src/test/ui/issues/issue-11869.rs
+++ b/src/test/ui/issues/issue-11869.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs
index 77278ecda6e..7f25c9a787e 100644
--- a/src/test/ui/issues/issue-1251.rs
+++ b/src/test/ui/issues/issue-1251.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_attributes)]
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-12729.rs b/src/test/ui/issues/issue-12729.rs
index 67c1bdc32ed..aa0b04af28e 100644
--- a/src/test/ui/issues/issue-12729.rs
+++ b/src/test/ui/issues/issue-12729.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-13105.rs b/src/test/ui/issues/issue-13105.rs
index 2410e2f1367..15a98c77983 100644
--- a/src/test/ui/issues/issue-13105.rs
+++ b/src/test/ui/issues/issue-13105.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/src/test/ui/issues/issue-13167.rs b/src/test/ui/issues/issue-13167.rs
index e04faabb7e8..8584c98decf 100644
--- a/src/test/ui/issues/issue-13167.rs
+++ b/src/test/ui/issues/issue-13167.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 use std::slice;
diff --git a/src/test/ui/issues/issue-13214.rs b/src/test/ui/issues/issue-13214.rs
index 0015169b117..0cf8d0675e6 100644
--- a/src/test/ui/issues/issue-13214.rs
+++ b/src/test/ui/issues/issue-13214.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // defining static with struct that contains enum
 // with &'static str variant used to cause ICE
diff --git a/src/test/ui/issues/issue-13405.rs b/src/test/ui/issues/issue-13405.rs
index fb48abe2648..732172b23ed 100644
--- a/src/test/ui/issues/issue-13405.rs
+++ b/src/test/ui/issues/issue-13405.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-13703.rs b/src/test/ui/issues/issue-13703.rs
index fe5458a7d7c..424c99974b3 100644
--- a/src/test/ui/issues/issue-13703.rs
+++ b/src/test/ui/issues/issue-13703.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub struct Foo<'a, 'b: 'a> { foo: &'a &'b isize }
diff --git a/src/test/ui/issues/issue-13775.rs b/src/test/ui/issues/issue-13775.rs
index 0359bb581d5..f5977effc40 100644
--- a/src/test/ui/issues/issue-13775.rs
+++ b/src/test/ui/issues/issue-13775.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/src/test/ui/issues/issue-13837.rs b/src/test/ui/issues/issue-13837.rs
index 06790fbd324..645b1c0eb87 100644
--- a/src/test/ui/issues/issue-13837.rs
+++ b/src/test/ui/issues/issue-13837.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-14082.rs b/src/test/ui/issues/issue-14082.rs
index e5f1b492f27..52b8c86802f 100644
--- a/src/test/ui/issues/issue-14082.rs
+++ b/src/test/ui/issues/issue-14082.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![allow(unused_imports, dead_code)]
diff --git a/src/test/ui/issues/issue-14254.rs b/src/test/ui/issues/issue-14254.rs
index 8b04fa192ad..6f930837641 100644
--- a/src/test/ui/issues/issue-14254.rs
+++ b/src/test/ui/issues/issue-14254.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo: Sized {
diff --git a/src/test/ui/issues/issue-14330.rs b/src/test/ui/issues/issue-14330.rs
index be31fa5eabc..0844fc72045 100644
--- a/src/test/ui/issues/issue-14330.rs
+++ b/src/test/ui/issues/issue-14330.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_imports)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-14837.rs b/src/test/ui/issues/issue-14837.rs
index a276e27f9dc..a83bc415002 100644
--- a/src/test/ui/issues/issue-14837.rs
+++ b/src/test/ui/issues/issue-14837.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #[deny(dead_code)]
diff --git a/src/test/ui/issues/issue-14901.rs b/src/test/ui/issues/issue-14901.rs
index c164658331e..5319abbdf0e 100644
--- a/src/test/ui/issues/issue-14901.rs
+++ b/src/test/ui/issues/issue-14901.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Reader {}
 
 enum Wrapper<'a> {
diff --git a/src/test/ui/issues/issue-14933.rs b/src/test/ui/issues/issue-14933.rs
index f229c0f7c26..bd95332caba 100644
--- a/src/test/ui/issues/issue-14933.rs
+++ b/src/test/ui/issues/issue-14933.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub type BigRat<T = isize> = T;
diff --git a/src/test/ui/issues/issue-14936.rs b/src/test/ui/issues/issue-14936.rs
index 809a1088992..33532855fcd 100644
--- a/src/test/ui/issues/issue-14936.rs
+++ b/src/test/ui/issues/issue-14936.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_macros)]
 #![allow(dead_code)]
 #![feature(asm)]
diff --git a/src/test/ui/issues/issue-14959.rs b/src/test/ui/issues/issue-14959.rs
index bd6c7a2bda9..e31a9431558 100644
--- a/src/test/ui/issues/issue-14959.rs
+++ b/src/test/ui/issues/issue-14959.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![feature(fn_traits, unboxed_closures)]
diff --git a/src/test/ui/issues/issue-15108.rs b/src/test/ui/issues/issue-15108.rs
deleted file mode 100644
index b8231ad4e83..00000000000
--- a/src/test/ui/issues/issue-15108.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-// build-pass (FIXME(62277): could be check-pass?)
-// pretty-expanded FIXME #23616
-
-fn main() {}
diff --git a/src/test/ui/issues/issue-15261.rs b/src/test/ui/issues/issue-15261.rs
index dd859475f9c..ec413f6d1d2 100644
--- a/src/test/ui/issues/issue-15261.rs
+++ b/src/test/ui/issues/issue-15261.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-15689-2.rs b/src/test/ui/issues/issue-15689-2.rs
index 1731a356ccd..83dcb1406f8 100644
--- a/src/test/ui/issues/issue-15689-2.rs
+++ b/src/test/ui/issues/issue-15689-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-15735.rs b/src/test/ui/issues/issue-15735.rs
index 0da4d4a620b..f9ba34405f6 100644
--- a/src/test/ui/issues/issue-15735.rs
+++ b/src/test/ui/issues/issue-15735.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct A<'a> {
     a: &'a i32,
diff --git a/src/test/ui/issues/issue-16441.rs b/src/test/ui/issues/issue-16441.rs
index bae3813f9da..1086aeb3055 100644
--- a/src/test/ui/issues/issue-16441.rs
+++ b/src/test/ui/issues/issue-16441.rs
@@ -5,6 +5,7 @@
 struct Empty;
 
 // This used to cause an ICE
+#[allow(improper_ctypes)]
 extern "C" fn ice(_a: Empty) {}
 
 fn main() {
diff --git a/src/test/ui/issues/issue-16596.rs b/src/test/ui/issues/issue-16596.rs
index 693dea436bb..e7a09630251 100644
--- a/src/test/ui/issues/issue-16596.rs
+++ b/src/test/ui/issues/issue-16596.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 trait MatrixRow { fn dummy(&self) { }}
diff --git a/src/test/ui/issues/issue-16668.rs b/src/test/ui/issues/issue-16668.rs
index a898ab20a48..92efb42fe30 100644
--- a/src/test/ui/issues/issue-16668.rs
+++ b/src/test/ui/issues/issue-16668.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Parser<'a, I, O> {
     parse: Box<dyn FnMut(I) -> Result<O, String> + 'a>
diff --git a/src/test/ui/issues/issue-17121.rs b/src/test/ui/issues/issue-17121.rs
index 0f1d4f5410d..34b1e2099be 100644
--- a/src/test/ui/issues/issue-17121.rs
+++ b/src/test/ui/issues/issue-17121.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 // ignore-cloudabi no std::fs
diff --git a/src/test/ui/issues/issue-17263.rs b/src/test/ui/issues/issue-17263.rs
index f24acb7b304..7e9ff685482 100644
--- a/src/test/ui/issues/issue-17263.rs
+++ b/src/test/ui/issues/issue-17263.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(box_syntax)]
 
diff --git a/src/test/ui/issues/issue-17336.rs b/src/test/ui/issues/issue-17336.rs
index 830d799fb65..89ce59b11f2 100644
--- a/src/test/ui/issues/issue-17336.rs
+++ b/src/test/ui/issues/issue-17336.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_must_use)]
 #[allow(dead_code)]
 fn check(a: &str) {
diff --git a/src/test/ui/issues/issue-17450.rs b/src/test/ui/issues/issue-17450.rs
index 595e0a4d25c..1ac0af1754b 100644
--- a/src/test/ui/issues/issue-17450.rs
+++ b/src/test/ui/issues/issue-17450.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code, warnings)]
 
 static mut x: isize = 3;
diff --git a/src/test/ui/issues/issue-17718-const-destructors.rs b/src/test/ui/issues/issue-17718-const-destructors.rs
index 7ec025ec3af..c9a729c7b20 100644
--- a/src/test/ui/issues/issue-17718-const-destructors.rs
+++ b/src/test/ui/issues/issue-17718-const-destructors.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct A;
 impl Drop for A {
diff --git a/src/test/ui/issues/issue-17732.rs b/src/test/ui/issues/issue-17732.rs
index 17135c191ca..5e11fc4fcfb 100644
--- a/src/test/ui/issues/issue-17732.rs
+++ b/src/test/ui/issues/issue-17732.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-17746.rs b/src/test/ui/issues/issue-17746.rs
index 847b2eb60bb..bab64a4b5ae 100644
--- a/src/test/ui/issues/issue-17746.rs
+++ b/src/test/ui/issues/issue-17746.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #17746
 
diff --git a/src/test/ui/issues/issue-17904.rs b/src/test/ui/issues/issue-17904.rs
index d916abb9c73..c3f504ac1b9 100644
--- a/src/test/ui/issues/issue-17904.rs
+++ b/src/test/ui/issues/issue-17904.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Test that we can parse where clauses on various forms of tuple
 // structs.
diff --git a/src/test/ui/issues/issue-18083.rs b/src/test/ui/issues/issue-18083.rs
index f159ed4a0ce..36420ec142e 100644
--- a/src/test/ui/issues/issue-18083.rs
+++ b/src/test/ui/issues/issue-18083.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_imports)]
 // These crossed imports should resolve fine, and not block on
diff --git a/src/test/ui/issues/issue-18088.rs b/src/test/ui/issues/issue-18088.rs
index 06f259958f8..c557b5a6512 100644
--- a/src/test/ui/issues/issue-18088.rs
+++ b/src/test/ui/issues/issue-18088.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub trait Indexable<T>: std::ops::Index<usize, Output = T> {
     fn index2(&self, i: usize) -> &T {
diff --git a/src/test/ui/issues/issue-18188.rs b/src/test/ui/issues/issue-18188.rs
index da10a8647ba..ce166724aff 100644
--- a/src/test/ui/issues/issue-18188.rs
+++ b/src/test/ui/issues/issue-18188.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 pub trait Promisable: Send + Sync {}
diff --git a/src/test/ui/issues/issue-1821.rs b/src/test/ui/issues/issue-1821.rs
index db97a507b68..76ee9c3edb0 100644
--- a/src/test/ui/issues/issue-1821.rs
+++ b/src/test/ui/issues/issue-1821.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-18446-2.rs b/src/test/ui/issues/issue-18446-2.rs
index 6b984c13da5..85422d4d261 100644
--- a/src/test/ui/issues/issue-18446-2.rs
+++ b/src/test/ui/issues/issue-18446-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Test that methods in trait impls should override default methods.
 
diff --git a/src/test/ui/issues/issue-1866.rs b/src/test/ui/issues/issue-1866.rs
index 0223e2ebea9..e4fe26800ef 100644
--- a/src/test/ui/issues/issue-1866.rs
+++ b/src/test/ui/issues/issue-1866.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-18738.rs b/src/test/ui/issues/issue-18738.rs
index ec4429234bc..bcc1ec03f26 100644
--- a/src/test/ui/issues/issue-18738.rs
+++ b/src/test/ui/issues/issue-18738.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Eq, PartialEq, PartialOrd, Ord)]
 enum Test<'a> {
diff --git a/src/test/ui/issues/issue-18809.rs b/src/test/ui/issues/issue-18809.rs
index 9b8275f8119..cc5b4a64c6d 100644
--- a/src/test/ui/issues/issue-18809.rs
+++ b/src/test/ui/issues/issue-18809.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait Tup {
     type T0;
     type T1;
diff --git a/src/test/ui/issues/issue-18906.rs b/src/test/ui/issues/issue-18906.rs
index 387fd41fb7a..976a9f49b9d 100644
--- a/src/test/ui/issues/issue-18906.rs
+++ b/src/test/ui/issues/issue-18906.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-18988.rs b/src/test/ui/issues/issue-18988.rs
index 6dbfd3a0a98..708965d81d8 100644
--- a/src/test/ui/issues/issue-18988.rs
+++ b/src/test/ui/issues/issue-18988.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 pub trait Foo : Send { }
 
diff --git a/src/test/ui/issues/issue-19037.rs b/src/test/ui/issues/issue-19037.rs
index 30497d3e94f..74623da1454 100644
--- a/src/test/ui/issues/issue-19037.rs
+++ b/src/test/ui/issues/issue-19037.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19081.rs b/src/test/ui/issues/issue-19081.rs
index 0948cd3271b..fbfe4c6f839 100644
--- a/src/test/ui/issues/issue-19081.rs
+++ b/src/test/ui/issues/issue-19081.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Hasher {
     type State;
 
diff --git a/src/test/ui/issues/issue-19097.rs b/src/test/ui/issues/issue-19097.rs
index c800e0bd12a..2f4b0d575bb 100644
--- a/src/test/ui/issues/issue-19097.rs
+++ b/src/test/ui/issues/issue-19097.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // regression test for #19097
 
diff --git a/src/test/ui/issues/issue-19098.rs b/src/test/ui/issues/issue-19098.rs
index 37c0d7f0522..3d05f11b697 100644
--- a/src/test/ui/issues/issue-19098.rs
+++ b/src/test/ui/issues/issue-19098.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Handler {
     fn handle(&self, _: &mut String);
 }
diff --git a/src/test/ui/issues/issue-19102.rs b/src/test/ui/issues/issue-19102.rs
index 76ed3efc4ed..1f32d10b644 100644
--- a/src/test/ui/issues/issue-19102.rs
+++ b/src/test/ui/issues/issue-19102.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_imports)]
 #![deny(unused_qualifications)]
 
diff --git a/src/test/ui/issues/issue-19129-1.rs b/src/test/ui/issues/issue-19129-1.rs
index e17ee053f33..03a9691018a 100644
--- a/src/test/ui/issues/issue-19129-1.rs
+++ b/src/test/ui/issues/issue-19129-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Trait<Input> {
diff --git a/src/test/ui/issues/issue-19129-2.rs b/src/test/ui/issues/issue-19129-2.rs
index 30c64573a15..991d79d4159 100644
--- a/src/test/ui/issues/issue-19129-2.rs
+++ b/src/test/ui/issues/issue-19129-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19398.rs b/src/test/ui/issues/issue-19398.rs
index 28d266a1d61..a9d0acaa26f 100644
--- a/src/test/ui/issues/issue-19398.rs
+++ b/src/test/ui/issues/issue-19398.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait T {
diff --git a/src/test/ui/issues/issue-19404.rs b/src/test/ui/issues/issue-19404.rs
index 40c9fdac7b0..f1cf1feb005 100644
--- a/src/test/ui/issues/issue-19404.rs
+++ b/src/test/ui/issues/issue-19404.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 use std::any::TypeId;
diff --git a/src/test/ui/issues/issue-19479.rs b/src/test/ui/issues/issue-19479.rs
index c134d85c7e9..70bfe7213f2 100644
--- a/src/test/ui/issues/issue-19479.rs
+++ b/src/test/ui/issues/issue-19479.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Base {
diff --git a/src/test/ui/issues/issue-19631.rs b/src/test/ui/issues/issue-19631.rs
index 015758dd6e1..694e6dcd15a 100644
--- a/src/test/ui/issues/issue-19631.rs
+++ b/src/test/ui/issues/issue-19631.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19632.rs b/src/test/ui/issues/issue-19632.rs
index ddd87a9f6e9..203976079fb 100644
--- a/src/test/ui/issues/issue-19632.rs
+++ b/src/test/ui/issues/issue-19632.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-19850.rs b/src/test/ui/issues/issue-19850.rs
index d51cf0cfcb9..4a578c398a8 100644
--- a/src/test/ui/issues/issue-19850.rs
+++ b/src/test/ui/issues/issue-19850.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_variables)]
 // Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
 // bindings
diff --git a/src/test/ui/issues/issue-19982.rs b/src/test/ui/issues/issue-19982.rs
index fb88781ee28..12419c109c5 100644
--- a/src/test/ui/issues/issue-19982.rs
+++ b/src/test/ui/issues/issue-19982.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(fn_traits, unboxed_closures)]
 
diff --git a/src/test/ui/issues/issue-20009.rs b/src/test/ui/issues/issue-20009.rs
index 730f1a9a162..f289e58c50e 100644
--- a/src/test/ui/issues/issue-20009.rs
+++ b/src/test/ui/issues/issue-20009.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Check that associated types are `Sized`
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-20091.rs b/src/test/ui/issues/issue-20091.rs
index 68e0f65ca23..90db44fa02d 100644
--- a/src/test/ui/issues/issue-20091.rs
+++ b/src/test/ui/issues/issue-20091.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// run-pass
 #![allow(stable_features)]
 
 // ignore-cloudabi no processes
diff --git a/src/test/ui/issues/issue-20186.rs b/src/test/ui/issues/issue-20186.rs
index 28cbde772c5..54d68f10052 100644
--- a/src/test/ui/issues/issue-20186.rs
+++ b/src/test/ui/issues/issue-20186.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 struct Foo;
diff --git a/src/test/ui/issues/issue-20396.rs b/src/test/ui/issues/issue-20396.rs
index 5e0411b2cd2..4a34f8b385f 100644
--- a/src/test/ui/issues/issue-20396.rs
+++ b/src/test/ui/issues/issue-20396.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![allow(dead_code)]
diff --git a/src/test/ui/issues/issue-20414.rs b/src/test/ui/issues/issue-20414.rs
index 5c6929d45d1..2496e342a2f 100644
--- a/src/test/ui/issues/issue-20414.rs
+++ b/src/test/ui/issues/issue-20414.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-20454.rs b/src/test/ui/issues/issue-20454.rs
index 13ce1daf30a..46cae33f102 100644
--- a/src/test/ui/issues/issue-20454.rs
+++ b/src/test/ui/issues/issue-20454.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_must_use)]
 use std::thread;
 
diff --git a/src/test/ui/issues/issue-2063-resource.rs b/src/test/ui/issues/issue-2063-resource.rs
index ea4cbf2cede..1d0527447ba 100644
--- a/src/test/ui/issues/issue-2063-resource.rs
+++ b/src/test/ui/issues/issue-2063-resource.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // test that autoderef of a type like this does not
 // cause compiler to loop.  Note that no instances
diff --git a/src/test/ui/issues/issue-20644.rs b/src/test/ui/issues/issue-20644.rs
index bde65229ec2..36eac382496 100644
--- a/src/test/ui/issues/issue-20644.rs
+++ b/src/test/ui/issues/issue-20644.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(unused_imports)]
 #![allow(stable_features)]
diff --git a/src/test/ui/issues/issue-20763-1.rs b/src/test/ui/issues/issue-20763-1.rs
index 0f0ac8f6462..858d313fc32 100644
--- a/src/test/ui/issues/issue-20763-1.rs
+++ b/src/test/ui/issues/issue-20763-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-20763-2.rs b/src/test/ui/issues/issue-20763-2.rs
index e3b566d0503..aa5bed209ee 100644
--- a/src/test/ui/issues/issue-20763-2.rs
+++ b/src/test/ui/issues/issue-20763-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-20797.rs b/src/test/ui/issues/issue-20797.rs
index bda7e8f818b..5d82592e5ea 100644
--- a/src/test/ui/issues/issue-20797.rs
+++ b/src/test/ui/issues/issue-20797.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // ignore-cloudabi no std::fs
 
 // Regression test for #20797.
diff --git a/src/test/ui/issues/issue-20825-2.rs b/src/test/ui/issues/issue-20825-2.rs
index 7d72ef839ea..b79a2973082 100644
--- a/src/test/ui/issues/issue-20825-2.rs
+++ b/src/test/ui/issues/issue-20825-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Subscriber {
     type Input;
 }
diff --git a/src/test/ui/issues/issue-21140.rs b/src/test/ui/issues/issue-21140.rs
index 92834bbb0e4..01de901112e 100644
--- a/src/test/ui/issues/issue-21140.rs
+++ b/src/test/ui/issues/issue-21140.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Trait where Self::Out: std::fmt::Display {
     type Out;
 }
diff --git a/src/test/ui/issues/issue-21160.rs b/src/test/ui/issues/issue-21160.rs
index dfb39743352..0199abbd8f0 100644
--- a/src/test/ui/issues/issue-21160.rs
+++ b/src/test/ui/issues/issue-21160.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 struct Bar;
 
 impl Bar {
diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr
index 9f88fa2fadd..65ba64b49d0 100644
--- a/src/test/ui/issues/issue-21160.stderr
+++ b/src/test/ui/issues/issue-21160.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Bar: std::hash::Hash` is not satisfied
-  --> $DIR/issue-21160.rs:10:12
+  --> $DIR/issue-21160.rs:9:12
    |
 LL | struct Foo(Bar);
    |            ^^^ the trait `std::hash::Hash` is not implemented for `Bar`
diff --git a/src/test/ui/issues/issue-21174-2.rs b/src/test/ui/issues/issue-21174-2.rs
index 351a98d5c85..c90f91f6a69 100644
--- a/src/test/ui/issues/issue-21174-2.rs
+++ b/src/test/ui/issues/issue-21174-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 trait Trait<'a> {
diff --git a/src/test/ui/issues/issue-21245.rs b/src/test/ui/issues/issue-21245.rs
index d0aa16bfb16..c8e55a0cc20 100644
--- a/src/test/ui/issues/issue-21245.rs
+++ b/src/test/ui/issues/issue-21245.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for issue #21245. Check that we are able to infer
 // the types in these examples correctly. It used to be that
diff --git a/src/test/ui/issues/issue-21363.rs b/src/test/ui/issues/issue-21363.rs
index d5f1eec061d..acc28cb430b 100644
--- a/src/test/ui/issues/issue-21363.rs
+++ b/src/test/ui/issues/issue-21363.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #![no_implicit_prelude]
diff --git a/src/test/ui/issues/issue-21402.rs b/src/test/ui/issues/issue-21402.rs
index 21e0d58b5f4..d140b6162ce 100644
--- a/src/test/ui/issues/issue-21402.rs
+++ b/src/test/ui/issues/issue-21402.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-21520.rs b/src/test/ui/issues/issue-21520.rs
index 133bcc2360a..ab4ac7237c7 100644
--- a/src/test/ui/issues/issue-21520.rs
+++ b/src/test/ui/issues/issue-21520.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Test that the requirement (in `Bar`) that `T::Bar : 'static` does
 // not wind up propagating to `T`.
diff --git a/src/test/ui/issues/issue-21562.rs b/src/test/ui/issues/issue-21562.rs
index 2f3ee7b7490..a47d739c6be 100644
--- a/src/test/ui/issues/issue-21562.rs
+++ b/src/test/ui/issues/issue-21562.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-21622.rs b/src/test/ui/issues/issue-21622.rs
index 4aae089943f..2d4cddac911 100644
--- a/src/test/ui/issues/issue-21622.rs
+++ b/src/test/ui/issues/issue-21622.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 
diff --git a/src/test/ui/issues/issue-21634.rs b/src/test/ui/issues/issue-21634.rs
index 36b207bb2a4..2731bfd767f 100644
--- a/src/test/ui/issues/issue-21634.rs
+++ b/src/test/ui/issues/issue-21634.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// run-pass
 #![allow(stable_features)]
 
 #![feature(cfg_target_feature)]
diff --git a/src/test/ui/issues/issue-21726.rs b/src/test/ui/issues/issue-21726.rs
index 1c8284c8295..b98cf216695 100644
--- a/src/test/ui/issues/issue-21726.rs
+++ b/src/test/ui/issues/issue-21726.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #21726: an issue arose around the rules for
 // subtyping of projection types that resulted in an unconstrained
diff --git a/src/test/ui/issues/issue-21891.rs b/src/test/ui/issues/issue-21891.rs
index de0aa2919cf..576f0253e63 100644
--- a/src/test/ui/issues/issue-21891.rs
+++ b/src/test/ui/issues/issue-21891.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-22066.rs b/src/test/ui/issues/issue-22066.rs
index fbf31aa4243..8e8ba5dc46c 100644
--- a/src/test/ui/issues/issue-22066.rs
+++ b/src/test/ui/issues/issue-22066.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait LineFormatter<'a> {
     type Iter: Iterator<Item=&'a str> + 'a;
     fn iter(&'a self, line: &'a str) -> Self::Iter;
diff --git a/src/test/ui/issues/issue-22356.rs b/src/test/ui/issues/issue-22356.rs
index ec4695e5e0a..47fad3bb909 100644
--- a/src/test/ui/issues/issue-22356.rs
+++ b/src/test/ui/issues/issue-22356.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(type_alias_bounds)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-22375.rs b/src/test/ui/issues/issue-22375.rs
index 201aea3a05c..21a1a4c8380 100644
--- a/src/test/ui/issues/issue-22375.rs
+++ b/src/test/ui/issues/issue-22375.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait A<T: A<T>> {}
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-22471.rs b/src/test/ui/issues/issue-22471.rs
index befccc19bf8..69879ab7fdf 100644
--- a/src/test/ui/issues/issue-22471.rs
+++ b/src/test/ui/issues/issue-22471.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(type_alias_bounds)]
 
diff --git a/src/test/ui/issues/issue-22777.rs b/src/test/ui/issues/issue-22777.rs
index 81efb250dfa..a31f059408f 100644
--- a/src/test/ui/issues/issue-22777.rs
+++ b/src/test/ui/issues/issue-22777.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // This test is reduced from libsyntax.  It is just checking that we
 // can successfully deal with a "deep" structure, which the drop-check
 // was hitting a recursion limit on at one point.
diff --git a/src/test/ui/issues/issue-22781.rs b/src/test/ui/issues/issue-22781.rs
index 37f40aa0421..d644cec4d56 100644
--- a/src/test/ui/issues/issue-22781.rs
+++ b/src/test/ui/issues/issue-22781.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_variables)]
 use std::collections::HashMap;
 use std::collections::hash_map::Entry::Vacant;
diff --git a/src/test/ui/issues/issue-22814.rs b/src/test/ui/issues/issue-22814.rs
index 065e7edc67e..4079adfc8b6 100644
--- a/src/test/ui/issues/issue-22814.rs
+++ b/src/test/ui/issues/issue-22814.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait Test {}
 
 macro_rules! test {
diff --git a/src/test/ui/issues/issue-22894.rs b/src/test/ui/issues/issue-22894.rs
index 7b1513a10c0..93c1db914ea 100644
--- a/src/test/ui/issues/issue-22894.rs
+++ b/src/test/ui/issues/issue-22894.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #[allow(dead_code)]
 static X: &'static str = &*"";
 fn main() {}
diff --git a/src/test/ui/issues/issue-2311-2.rs b/src/test/ui/issues/issue-2311-2.rs
index f735338fcdb..760d4edaa98 100644
--- a/src/test/ui/issues/issue-2311-2.rs
+++ b/src/test/ui/issues/issue-2311-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-2311.rs b/src/test/ui/issues/issue-2311.rs
index 151ad4e2664..21ff19f7f03 100644
--- a/src/test/ui/issues/issue-2311.rs
+++ b/src/test/ui/issues/issue-2311.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(non_camel_case_types)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-2312.rs b/src/test/ui/issues/issue-2312.rs
index b445f9581b3..8a94bcbd4cc 100644
--- a/src/test/ui/issues/issue-2312.rs
+++ b/src/test/ui/issues/issue-2312.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-23406.rs b/src/test/ui/issues/issue-23406.rs
index 2e57b16e3c7..d00d5d6f944 100644
--- a/src/test/ui/issues/issue-23406.rs
+++ b/src/test/ui/issues/issue-23406.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 trait Inner {
     type T;
diff --git a/src/test/ui/issues/issue-23442.rs b/src/test/ui/issues/issue-23442.rs
index 659e1e07942..d1e4317e5b4 100644
--- a/src/test/ui/issues/issue-23442.rs
+++ b/src/test/ui/issues/issue-23442.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::marker::PhantomData;
 
diff --git a/src/test/ui/issues/issue-23550.rs b/src/test/ui/issues/issue-23550.rs
index fad0ad7ecca..9cce9a0a98b 100644
--- a/src/test/ui/issues/issue-23550.rs
+++ b/src/test/ui/issues/issue-23550.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![feature(core_intrinsics)]
 #![allow(warnings)]
 
diff --git a/src/test/ui/issues/issue-23649-3.rs b/src/test/ui/issues/issue-23649-3.rs
index febdc4256c7..8f61c71d6eb 100644
--- a/src/test/ui/issues/issue-23649-3.rs
+++ b/src/test/ui/issues/issue-23649-3.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #[derive(PartialEq)]
 struct Slice { slice: [u8] }
 
diff --git a/src/test/ui/issues/issue-24085.rs b/src/test/ui/issues/issue-24085.rs
index dc2de922ff0..86e94beb7e2 100644
--- a/src/test/ui/issues/issue-24085.rs
+++ b/src/test/ui/issues/issue-24085.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #24085. Errors were occurring in region
 // inference due to the requirement that `'a:b'`, which was getting
diff --git a/src/test/ui/issues/issue-24161.rs b/src/test/ui/issues/issue-24161.rs
index c5c8651d43b..f4cdd982ac6 100644
--- a/src/test/ui/issues/issue-24161.rs
+++ b/src/test/ui/issues/issue-24161.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Copy,Clone)]
 struct Functions {
diff --git a/src/test/ui/issues/issue-24227.rs b/src/test/ui/issues/issue-24227.rs
index eaadaf7c449..12816c235f8 100644
--- a/src/test/ui/issues/issue-24227.rs
+++ b/src/test/ui/issues/issue-24227.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // This resulted in an ICE. Test for future-proofing
 // Issue #24227
 
diff --git a/src/test/ui/issues/issue-24338.rs b/src/test/ui/issues/issue-24338.rs
index 09cc99f9507..3a2c790f852 100644
--- a/src/test/ui/issues/issue-24338.rs
+++ b/src/test/ui/issues/issue-24338.rs
@@ -1,5 +1,5 @@
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait DictLike<'a> {
     type ItemsIterator: Iterator<Item=u8>;
diff --git a/src/test/ui/issues/issue-24389.rs b/src/test/ui/issues/issue-24389.rs
index 63d1687af50..7cc7611769a 100644
--- a/src/test/ui/issues/issue-24389.rs
+++ b/src/test/ui/issues/issue-24389.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 struct Foo;
diff --git a/src/test/ui/issues/issue-24434.rs b/src/test/ui/issues/issue-24434.rs
index b500b9d56dd..4c1bfc03c9a 100644
--- a/src/test/ui/issues/issue-24434.rs
+++ b/src/test/ui/issues/issue-24434.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags:--cfg set1
 
 #![cfg_attr(set1, feature(rustc_attrs))]
diff --git a/src/test/ui/issues/issue-2487-a.rs b/src/test/ui/issues/issue-2487-a.rs
index a43933d2020..fe12dad74f5 100644
--- a/src/test/ui/issues/issue-2487-a.rs
+++ b/src/test/ui/issues/issue-2487-a.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-2502.rs b/src/test/ui/issues/issue-2502.rs
index 9a2bbb82413..63151002438 100644
--- a/src/test/ui/issues/issue-2502.rs
+++ b/src/test/ui/issues/issue-2502.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 
diff --git a/src/test/ui/issues/issue-25180.rs b/src/test/ui/issues/issue-25180.rs
index 12f8f88a170..29dc07f4914 100644
--- a/src/test/ui/issues/issue-25180.rs
+++ b/src/test/ui/issues/issue-25180.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-25394.rs b/src/test/ui/issues/issue-25394.rs
index c41b554df14..2f0ae19fcb1 100644
--- a/src/test/ui/issues/issue-25394.rs
+++ b/src/test/ui/issues/issue-25394.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Debug)]
 struct Row<T>([T]);
diff --git a/src/test/ui/issues/issue-25579.rs b/src/test/ui/issues/issue-25579.rs
index 32b4b75b080..5f5a0f4d267 100644
--- a/src/test/ui/issues/issue-25579.rs
+++ b/src/test/ui/issues/issue-25579.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 enum Sexpression {
     Num(()),
diff --git a/src/test/ui/issues/issue-26095.rs b/src/test/ui/issues/issue-26095.rs
index 1e3cc902e56..638f8f57187 100644
--- a/src/test/ui/issues/issue-26095.rs
+++ b/src/test/ui/issues/issue-26095.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-2611-3.rs b/src/test/ui/issues/issue-2611-3.rs
index 7335d53f8a6..a95a748e091 100644
--- a/src/test/ui/issues/issue-2611-3.rs
+++ b/src/test/ui/issues/issue-2611-3.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Tests that impls are allowed to have looser, more permissive bounds
 // than the traits require.
diff --git a/src/test/ui/issues/issue-26205.rs b/src/test/ui/issues/issue-26205.rs
index 45ca998a831..f5f39ded021 100644
--- a/src/test/ui/issues/issue-26205.rs
+++ b/src/test/ui/issues/issue-26205.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::ops::{Deref, DerefMut};
 
diff --git a/src/test/ui/issues/issue-26646.rs b/src/test/ui/issues/issue-26646.rs
index d6f51ce9c99..86e4bd7e8f8 100644
--- a/src/test/ui/issues/issue-26646.rs
+++ b/src/test/ui/issues/issue-26646.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(unused_attributes)]
 
 #[repr(C)]
diff --git a/src/test/ui/issues/issue-26997.rs b/src/test/ui/issues/issue-26997.rs
index a2b32a13678..9e7e47117ac 100644
--- a/src/test/ui/issues/issue-26997.rs
+++ b/src/test/ui/issues/issue-26997.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 pub struct Foo {
     x: isize,
@@ -6,6 +6,7 @@ pub struct Foo {
 }
 
 impl Foo {
+    #[allow(improper_ctypes)]
     pub extern fn foo_new() -> Foo {
         Foo { x: 21, y: 33 }
     }
diff --git a/src/test/ui/issues/issue-27033.rs b/src/test/ui/issues/issue-27033.rs
index bcb06d743a0..7120dee6339 100644
--- a/src/test/ui/issues/issue-27033.rs
+++ b/src/test/ui/issues/issue-27033.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 fn main() {
     match Some(1) {
         None @ _ => {} //~ ERROR match bindings cannot shadow unit variants
diff --git a/src/test/ui/issues/issue-27033.stderr b/src/test/ui/issues/issue-27033.stderr
index a4baa7bdf7f..2d6d2ef41bd 100644
--- a/src/test/ui/issues/issue-27033.stderr
+++ b/src/test/ui/issues/issue-27033.stderr
@@ -1,5 +1,5 @@
 error[E0530]: match bindings cannot shadow unit variants
-  --> $DIR/issue-27033.rs:5:9
+  --> $DIR/issue-27033.rs:4:9
    |
 LL |         None @ _ => {}
    |         ^^^^ cannot be named the same as a unit variant
@@ -10,7 +10,7 @@ LL | pub use crate::option::Option::{self, Some, None};
    |                                             ---- the unit variant `None` is defined here
 
 error[E0530]: match bindings cannot shadow constants
-  --> $DIR/issue-27033.rs:9:9
+  --> $DIR/issue-27033.rs:8:9
    |
 LL |     const C: u8 = 1;
    |     ---------------- the constant `C` is defined here
diff --git a/src/test/ui/issues/issue-27105.rs b/src/test/ui/issues/issue-27105.rs
index e7584d941ba..3339af364a0 100644
--- a/src/test/ui/issues/issue-27105.rs
+++ b/src/test/ui/issues/issue-27105.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 use std::cell::RefCell;
 use std::rc::Rc;
 
diff --git a/src/test/ui/issues/issue-27281.rs b/src/test/ui/issues/issue-27281.rs
index 58b8f07bca6..717d8b2c2aa 100644
--- a/src/test/ui/issues/issue-27281.rs
+++ b/src/test/ui/issues/issue-27281.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub trait Trait<'a> {
     type T;
     type U;
diff --git a/src/test/ui/issues/issue-2748-a.rs b/src/test/ui/issues/issue-2748-a.rs
index 5f566e186eb..cbb9bcc28ac 100644
--- a/src/test/ui/issues/issue-2748-a.rs
+++ b/src/test/ui/issues/issue-2748-a.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 
diff --git a/src/test/ui/issues/issue-27583.rs b/src/test/ui/issues/issue-27583.rs
index 9981f867bd0..84c94c7c905 100644
--- a/src/test/ui/issues/issue-27583.rs
+++ b/src/test/ui/issues/issue-27583.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for issue #27583. Unclear how useful this will be
 // going forward, since the issue in question was EXTREMELY sensitive
 // to compiler internals (like the precise numbering of nodes), but
diff --git a/src/test/ui/issues/issue-27889.rs b/src/test/ui/issues/issue-27889.rs
index bb5a186b457..623416a5d00 100644
--- a/src/test/ui/issues/issue-27889.rs
+++ b/src/test/ui/issues/issue-27889.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 // Test that a field can have the same name in different variants
diff --git a/src/test/ui/issues/issue-2804-2.rs b/src/test/ui/issues/issue-2804-2.rs
index 68933fc2e8a..d02725505ac 100644
--- a/src/test/ui/issues/issue-2804-2.rs
+++ b/src/test/ui/issues/issue-2804-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Minimized version of issue-2804.rs. Both check that callee IDs don't
 // clobber the previous node ID in a macro expr
diff --git a/src/test/ui/issues/issue-28279.rs b/src/test/ui/issues/issue-28279.rs
index e36a9551ab5..bab5df122c8 100644
--- a/src/test/ui/issues/issue-28279.rs
+++ b/src/test/ui/issues/issue-28279.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::rc::Rc;
 
diff --git a/src/test/ui/issues/issue-28561.rs b/src/test/ui/issues/issue-28561.rs
index cc4e63696e5..1241fb0b1f8 100644
--- a/src/test/ui/issues/issue-28561.rs
+++ b/src/test/ui/issues/issue-28561.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
 struct Array<T> {
     f00: [T; 00],
diff --git a/src/test/ui/issues/issue-28600.rs b/src/test/ui/issues/issue-28600.rs
index 05c4050b03a..170c0a07125 100644
--- a/src/test/ui/issues/issue-28600.rs
+++ b/src/test/ui/issues/issue-28600.rs
@@ -1,9 +1,10 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // #28600 ICE: pub extern fn with parameter type &str inside struct impl
 
 struct Test;
 
 impl Test {
+    #[allow(improper_ctypes)]
     #[allow(dead_code)]
     #[allow(unused_variables)]
     pub extern fn test(val: &str) {
diff --git a/src/test/ui/issues/issue-28822.rs b/src/test/ui/issues/issue-28822.rs
index 2c0c01aa827..10e5d1dd0ac 100644
--- a/src/test/ui/issues/issue-28822.rs
+++ b/src/test/ui/issues/issue-28822.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-28871.rs b/src/test/ui/issues/issue-28871.rs
index 43564dfcc46..210c783de79 100644
--- a/src/test/ui/issues/issue-28871.rs
+++ b/src/test/ui/issues/issue-28871.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for #28871. The problem is that rustc encountered
 // two ways to project, one from a where clause and one from the where
 // clauses on the trait definition. (In fact, in this case, the where
diff --git a/src/test/ui/issues/issue-28936.rs b/src/test/ui/issues/issue-28936.rs
index 9267491aafd..da9e92c0c80 100644
--- a/src/test/ui/issues/issue-28936.rs
+++ b/src/test/ui/issues/issue-28936.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub type Session = i32;
 pub struct StreamParser<'a, T> {
     _tokens: T,
diff --git a/src/test/ui/issues/issue-28999.rs b/src/test/ui/issues/issue-28999.rs
index 888a8010a2f..cec3e25da86 100644
--- a/src/test/ui/issues/issue-28999.rs
+++ b/src/test/ui/issues/issue-28999.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub struct Xyz<'a, V> {
     pub v: (V, &'a u32),
 }
diff --git a/src/test/ui/issues/issue-29030.rs b/src/test/ui/issues/issue-29030.rs
index f9e89840314..723e358407f 100644
--- a/src/test/ui/issues/issue-29030.rs
+++ b/src/test/ui/issues/issue-29030.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #[derive(Debug)]
 struct Message<'a, P: 'a = &'a [u8]> {
diff --git a/src/test/ui/issues/issue-29037.rs b/src/test/ui/issues/issue-29037.rs
index b1ca76be10d..155ed144b3a 100644
--- a/src/test/ui/issues/issue-29037.rs
+++ b/src/test/ui/issues/issue-29037.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // This test ensures that each pointer type `P<X>` is covariant in `X`.
 
diff --git a/src/test/ui/issues/issue-2904.rs b/src/test/ui/issues/issue-2904.rs
index 36bc8002f99..73aa78f09b9 100644
--- a/src/test/ui/issues/issue-2904.rs
+++ b/src/test/ui/issues/issue-2904.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
diff --git a/src/test/ui/issues/issue-29048.rs b/src/test/ui/issues/issue-29048.rs
index e3ccb0d6579..039f072f107 100644
--- a/src/test/ui/issues/issue-29048.rs
+++ b/src/test/ui/issues/issue-29048.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 pub struct Chan;
 pub struct ChanSelect<'c, T> {
     chans: Vec<(&'c Chan, T)>,
diff --git a/src/test/ui/issues/issue-29071.rs b/src/test/ui/issues/issue-29071.rs
index 7e016a715cd..8bdacf2cebb 100644
--- a/src/test/ui/issues/issue-29071.rs
+++ b/src/test/ui/issues/issue-29071.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-29276.rs b/src/test/ui/issues/issue-29276.rs
index 2532dac9772..02b69565953 100644
--- a/src/test/ui/issues/issue-29276.rs
+++ b/src/test/ui/issues/issue-29276.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct S([u8; { struct Z; 0 }]);
 
diff --git a/src/test/ui/issues/issue-29516.rs b/src/test/ui/issues/issue-29516.rs
index 8966730fd87..d43367e3452 100644
--- a/src/test/ui/issues/issue-29516.rs
+++ b/src/test/ui/issues/issue-29516.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![feature(optin_builtin_traits)]
 
 auto trait NotSame {}
diff --git a/src/test/ui/issues/issue-29540.rs b/src/test/ui/issues/issue-29540.rs
index e472f71aa7f..2a4d50f613c 100644
--- a/src/test/ui/issues/issue-29540.rs
+++ b/src/test/ui/issues/issue-29540.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #[derive(Debug)]
 pub struct Config {
     pub name: String,
diff --git a/src/test/ui/issues/issue-29710.rs b/src/test/ui/issues/issue-29710.rs
index d4de756e56f..bc98d389c6e 100644
--- a/src/test/ui/issues/issue-29710.rs
+++ b/src/test/ui/issues/issue-29710.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(unused_results)]
 #![allow(dead_code)]
 
diff --git a/src/test/ui/issues/issue-29740.rs b/src/test/ui/issues/issue-29740.rs
index 50a03d86acb..20398890baf 100644
--- a/src/test/ui/issues/issue-29740.rs
+++ b/src/test/ui/issues/issue-29740.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #29740. Inefficient MIR matching algorithms
 // generated way too much code for this sort of case, leading to OOM.
diff --git a/src/test/ui/issues/issue-29743.rs b/src/test/ui/issues/issue-29743.rs
index 2598b07490e..250cd7e1b25 100644
--- a/src/test/ui/issues/issue-29743.rs
+++ b/src/test/ui/issues/issue-29743.rs
@@ -1,5 +1,4 @@
-//
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     let mut i = [1, 2, 3];
diff --git a/src/test/ui/issues/issue-31260.rs b/src/test/ui/issues/issue-31260.rs
index 608900301e0..4db7445b025 100644
--- a/src/test/ui/issues/issue-31260.rs
+++ b/src/test/ui/issues/issue-31260.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 pub struct Struct<K: 'static> {
     pub field: K,
diff --git a/src/test/ui/issues/issue-3149.rs b/src/test/ui/issues/issue-3149.rs
index da3fe9ad6ec..6ab3bc846a3 100644
--- a/src/test/ui/issues/issue-3149.rs
+++ b/src/test/ui/issues/issue-3149.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_snake_case)]
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-31597.rs b/src/test/ui/issues/issue-31597.rs
index 1d28a91ea7e..2872be6d6c8 100644
--- a/src/test/ui/issues/issue-31597.rs
+++ b/src/test/ui/issues/issue-31597.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait Make {
     type Out;
diff --git a/src/test/ui/issues/issue-32324.rs b/src/test/ui/issues/issue-32324.rs
index eaad98d6785..2df547b2e0c 100644
--- a/src/test/ui/issues/issue-32324.rs
+++ b/src/test/ui/issues/issue-32324.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 trait Resources {
diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.rs b/src/test/ui/issues/issue-33140-traitobject-crate.rs
index 03567b20a8f..5f6996c6f52 100644
--- a/src/test/ui/issues/issue-33140-traitobject-crate.rs
+++ b/src/test/ui/issues/issue-33140-traitobject-crate.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(order_dependent_trait_objects)]
 
diff --git a/src/test/ui/issues/issue-33264.rs b/src/test/ui/issues/issue-33264.rs
index e6370bc84de..31638b00439 100644
--- a/src/test/ui/issues/issue-33264.rs
+++ b/src/test/ui/issues/issue-33264.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // only-x86_64
 
 #![allow(dead_code, non_upper_case_globals)]
diff --git a/src/test/ui/issues/issue-33287.rs b/src/test/ui/issues/issue-33287.rs
index 036a1e37688..770eb7c02bb 100644
--- a/src/test/ui/issues/issue-33287.rs
+++ b/src/test/ui/issues/issue-33287.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 const A: [u32; 1] = [0];
diff --git a/src/test/ui/issues/issue-3344.stderr b/src/test/ui/issues/issue-3344.stderr
index 6593e07b189..271fbb6c874 100644
--- a/src/test/ui/issues/issue-3344.stderr
+++ b/src/test/ui/issues/issue-3344.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
 LL | impl PartialOrd for Thing {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
    |
-   = note: `partial_cmp` from trait: `fn(&Self, &Rhs) -> std::option::Option<std::cmp::Ordering>`
+   = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> std::option::Option<std::cmp::Ordering> { unimplemented!() }`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-33903.rs b/src/test/ui/issues/issue-33903.rs
index 6a8305dabeb..613aa121a47 100644
--- a/src/test/ui/issues/issue-33903.rs
+++ b/src/test/ui/issues/issue-33903.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Issue 33903:
 // Built-in indexing should be used even when the index is not
diff --git a/src/test/ui/issues/issue-34194.rs b/src/test/ui/issues/issue-34194.rs
index ea89e4cbdeb..6dce556e9e3 100644
--- a/src/test/ui/issues/issue-34194.rs
+++ b/src/test/ui/issues/issue-34194.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 
 struct A {
diff --git a/src/test/ui/issues/issue-3424.rs b/src/test/ui/issues/issue-3424.rs
index a8ff03e2a24..43d75a6525f 100644
--- a/src/test/ui/issues/issue-3424.rs
+++ b/src/test/ui/issues/issue-3424.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 // rustc --test ignores2.rs && ./ignores2
diff --git a/src/test/ui/issues/issue-34751.rs b/src/test/ui/issues/issue-34751.rs
index a921cb50612..6309c0a0257 100644
--- a/src/test/ui/issues/issue-34751.rs
+++ b/src/test/ui/issues/issue-34751.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // #34751 ICE: 'rustc' panicked at 'assertion failed: !substs.has_regions_escaping_depth(0)'
 
diff --git a/src/test/ui/issues/issue-34780.rs b/src/test/ui/issues/issue-34780.rs
index 3202ef64021..fbedad35b86 100644
--- a/src/test/ui/issues/issue-34780.rs
+++ b/src/test/ui/issues/issue-34780.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(stable_features)]
 #![feature(associated_consts)]
 
diff --git a/src/test/ui/issues/issue-35376.rs b/src/test/ui/issues/issue-35376.rs
index b415d655405..eb139ec4d7f 100644
--- a/src/test/ui/issues/issue-35376.rs
+++ b/src/test/ui/issues/issue-35376.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![feature(specialization)]
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-35546.rs b/src/test/ui/issues/issue-35546.rs
index e2f0f98d57b..004679a6240 100644
--- a/src/test/ui/issues/issue-35546.rs
+++ b/src/test/ui/issues/issue-35546.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // Regression test for #35546. Check that we are able to codegen
 // this. Before we had problems because of the drop glue signature
diff --git a/src/test/ui/issues/issue-3563-2.rs b/src/test/ui/issues/issue-3563-2.rs
index 5ab668eed18..88a449b85b8 100644
--- a/src/test/ui/issues/issue-3563-2.rs
+++ b/src/test/ui/issues/issue-3563-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Canvas {
diff --git a/src/test/ui/issues/issue-36075.rs b/src/test/ui/issues/issue-36075.rs
index 00c8cf1fb8a..bc5bdc3ff9e 100644
--- a/src/test/ui/issues/issue-36075.rs
+++ b/src/test/ui/issues/issue-36075.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait DeclarationParser {
     type Declaration;
diff --git a/src/test/ui/issues/issue-3609.rs b/src/test/ui/issues/issue-3609.rs
index e8fc073a158..57ff12a08ce 100644
--- a/src/test/ui/issues/issue-3609.rs
+++ b/src/test/ui/issues/issue-3609.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_must_use)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
diff --git a/src/test/ui/issues/issue-36744-without-calls.rs b/src/test/ui/issues/issue-36744-without-calls.rs
index 4d03d9bbca6..dc5dc4f13c0 100644
--- a/src/test/ui/issues/issue-36744-without-calls.rs
+++ b/src/test/ui/issues/issue-36744-without-calls.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // Tests for an LLVM abort when storing a lifetime-parametric fn into
 // context that is expecting one that is not lifetime-parametric
 // (i.e., has no `for <'_>`).
diff --git a/src/test/ui/issues/issue-37323.rs b/src/test/ui/issues/issue-37323.rs
index 61c8029adf5..55f5c5a9581 100644
--- a/src/test/ui/issues/issue-37323.rs
+++ b/src/test/ui/issues/issue-37323.rs
@@ -1,4 +1,5 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
+// compile-flags: -Zsave-analysis
 
 #![feature(rustc_attrs)]
 #![allow(warnings)]
diff --git a/src/test/ui/issues/issue-37655.rs b/src/test/ui/issues/issue-37655.rs
index fecff4e0246..416854d66f3 100644
--- a/src/test/ui/issues/issue-37655.rs
+++ b/src/test/ui/issues/issue-37655.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for #37655. The problem was a false edge created by
 // coercion that wound up requiring that `'a` (in `split()`) outlive
 // `'b`, which shouldn't be necessary.
diff --git a/src/test/ui/issues/issue-37725.rs b/src/test/ui/issues/issue-37725.rs
index eefdc72f0c3..965ecde6f3c 100644
--- a/src/test/ui/issues/issue-37725.rs
+++ b/src/test/ui/issues/issue-37725.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 trait Foo {
     fn foo(&self);
diff --git a/src/test/ui/issues/issue-37733.rs b/src/test/ui/issues/issue-37733.rs
index c1df28331a5..e211e2c3336 100644
--- a/src/test/ui/issues/issue-37733.rs
+++ b/src/test/ui/issues/issue-37733.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 type A = for<> fn();
 
diff --git a/src/test/ui/issues/issue-38727.rs b/src/test/ui/issues/issue-38727.rs
index 3c728e9def1..2d418b65269 100644
--- a/src/test/ui/issues/issue-38727.rs
+++ b/src/test/ui/issues/issue-38727.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #[repr(u64)]
 enum A {
diff --git a/src/test/ui/issues/issue-3874.rs b/src/test/ui/issues/issue-3874.rs
index b290da52080..f9553d88d24 100644
--- a/src/test/ui/issues/issue-3874.rs
+++ b/src/test/ui/issues/issue-3874.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-38763.rs b/src/test/ui/issues/issue-38763.rs
index 6e6de09225f..c84846bc4e8 100644
--- a/src/test/ui/issues/issue-38763.rs
+++ b/src/test/ui/issues/issue-38763.rs
@@ -4,6 +4,7 @@
 #[repr(C)]
 pub struct Foo(i128);
 
+#[allow(improper_ctypes)]
 #[no_mangle]
 pub extern "C" fn foo(x: Foo) -> Foo { x }
 
diff --git a/src/test/ui/issues/issue-38875/issue-38875.rs b/src/test/ui/issues/issue-38875/issue-38875.rs
index 68981eaf2b5..124e4d6fd41 100644
--- a/src/test/ui/issues/issue-38875/issue-38875.rs
+++ b/src/test/ui/issues/issue-38875/issue-38875.rs
@@ -1,5 +1,5 @@
 // aux-build:issue-38875-b.rs
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 extern crate issue_38875_b;
 
diff --git a/src/test/ui/issues/issue-3888-2.rs b/src/test/ui/issues/issue-3888-2.rs
index 3d4b184ab6b..d1ef914bdec 100644
--- a/src/test/ui/issues/issue-3888-2.rs
+++ b/src/test/ui/issues/issue-3888-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-39089.rs b/src/test/ui/issues/issue-39089.rs
index 12ca9e1da0f..c7d4f8bd320 100644
--- a/src/test/ui/issues/issue-39089.rs
+++ b/src/test/ui/issues/issue-39089.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 fn f<T: ?for<'a> Sized>() {}
 
diff --git a/src/test/ui/issues/issue-39467.rs b/src/test/ui/issues/issue-39467.rs
index 86e67560008..397751e4ec3 100644
--- a/src/test/ui/issues/issue-39467.rs
+++ b/src/test/ui/issues/issue-39467.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 macro_rules! expr { () => { () } }
 
diff --git a/src/test/ui/issues/issue-3979-2.rs b/src/test/ui/issues/issue-3979-2.rs
index f3fcfd2c8fb..4ec128a4586 100644
--- a/src/test/ui/issues/issue-3979-2.rs
+++ b/src/test/ui/issues/issue-3979-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait A {
diff --git a/src/test/ui/issues/issue-3991.rs b/src/test/ui/issues/issue-3991.rs
index b8ff671bf38..4851eddf533 100644
--- a/src/test/ui/issues/issue-3991.rs
+++ b/src/test/ui/issues/issue-3991.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-39984.rs b/src/test/ui/issues/issue-39984.rs
index 613aad1a34f..1c9ae26cab2 100644
--- a/src/test/ui/issues/issue-39984.rs
+++ b/src/test/ui/issues/issue-39984.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unreachable_code)]
 // Regression test for issue #39984.
diff --git a/src/test/ui/issues/issue-40136.rs b/src/test/ui/issues/issue-40136.rs
index 412ddafdd97..29d3fc2d560 100644
--- a/src/test/ui/issues/issue-40136.rs
+++ b/src/test/ui/issues/issue-40136.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 macro_rules! m { () => { 0 } }
diff --git a/src/test/ui/issues/issue-4025.rs b/src/test/ui/issues/issue-4025.rs
index 6e009ba6eb4..dc534c64c60 100644
--- a/src/test/ui/issues/issue-4025.rs
+++ b/src/test/ui/issues/issue-4025.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_mut)]
 /*
diff --git a/src/test/ui/issues/issue-40510-2.rs b/src/test/ui/issues/issue-40510-2.rs
index 499fa8a04f2..3ae84be0578 100644
--- a/src/test/ui/issues/issue-40510-2.rs
+++ b/src/test/ui/issues/issue-40510-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused)]
 
 fn f() {
diff --git a/src/test/ui/issues/issue-40510-4.rs b/src/test/ui/issues/issue-40510-4.rs
index 5fad7e4a629..48bb8d36f55 100644
--- a/src/test/ui/issues/issue-40510-4.rs
+++ b/src/test/ui/issues/issue-40510-4.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused)]
 
 fn f() {
diff --git a/src/test/ui/issues/issue-40962.rs b/src/test/ui/issues/issue-40962.rs
index c051133cbed..7b91c06819f 100644
--- a/src/test/ui/issues/issue-40962.rs
+++ b/src/test/ui/issues/issue-40962.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 macro_rules! m {
     ($i:meta) => {
         #[derive($i)]
diff --git a/src/test/ui/issues/issue-41272.rs b/src/test/ui/issues/issue-41272.rs
index 9cd20036286..1f4da46f894 100644
--- a/src/test/ui/issues/issue-41272.rs
+++ b/src/test/ui/issues/issue-41272.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Foo;
 
diff --git a/src/test/ui/issues/issue-41298.rs b/src/test/ui/issues/issue-41298.rs
index c719664de0d..a1b4de39bee 100644
--- a/src/test/ui/issues/issue-41298.rs
+++ b/src/test/ui/issues/issue-41298.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Function<T, F> { t: T, f: F }
 
diff --git a/src/test/ui/issues/issue-41628.rs b/src/test/ui/issues/issue-41628.rs
index 92369fdcd49..92159824eb0 100644
--- a/src/test/ui/issues/issue-41628.rs
+++ b/src/test/ui/issues/issue-41628.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(dead_code)]
 
 #[used]
diff --git a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
index 6c6cec25a9a..3d678ba041b 100644
--- a/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
+++ b/src/test/ui/issues/issue-41936-variance-coerce-unsized-cycle.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // Regression test for #41936. The coerce-unsized trait check in
 // coherence was using subtyping, which triggered variance
diff --git a/src/test/ui/issues/issue-41998.rs b/src/test/ui/issues/issue-41998.rs
index 2f2842598fc..7696a3108d1 100644
--- a/src/test/ui/issues/issue-41998.rs
+++ b/src/test/ui/issues/issue-41998.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 
 fn main() {
diff --git a/src/test/ui/issues/issue-42467.rs b/src/test/ui/issues/issue-42467.rs
index f1a55169ffd..afa1bcd13fc 100644
--- a/src/test/ui/issues/issue-42467.rs
+++ b/src/test/ui/issues/issue-42467.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 struct Foo<T>(T);
 
diff --git a/src/test/ui/issues/issue-42956.rs b/src/test/ui/issues/issue-42956.rs
index 8cf0ae00306..e6b3f9ffab7 100644
--- a/src/test/ui/issues/issue-42956.rs
+++ b/src/test/ui/issues/issue-42956.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(stable_features)]
 #![feature(associated_consts)]
diff --git a/src/test/ui/issues/issue-43057.rs b/src/test/ui/issues/issue-43057.rs
index 7e1d5036f37..4ce52af434c 100644
--- a/src/test/ui/issues/issue-43057.rs
+++ b/src/test/ui/issues/issue-43057.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused)]
 
 macro_rules! column {
diff --git a/src/test/ui/issues/issue-43357.rs b/src/test/ui/issues/issue-43357.rs
index 3090e229b6d..474c9765595 100644
--- a/src/test/ui/issues/issue-43357.rs
+++ b/src/test/ui/issues/issue-43357.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait Trait {
     type Output;
diff --git a/src/test/ui/issues/issue-43398.rs b/src/test/ui/issues/issue-43398.rs
index ae52e8f3f6b..f0b762c6254 100644
--- a/src/test/ui/issues/issue-43398.rs
+++ b/src/test/ui/issues/issue-43398.rs
@@ -7,9 +7,7 @@
 enum Big { A, B }
 
 fn main() {
-    unsafe {
-        println!("{} {:?}",
-            std::intrinsics::discriminant_value(&Big::A),
-            std::mem::discriminant(&Big::B));
-    }
+    println!("{} {:?}",
+        std::intrinsics::discriminant_value(&Big::A),
+        std::mem::discriminant(&Big::B));
 }
diff --git a/src/test/ui/issues/issue-43483.rs b/src/test/ui/issues/issue-43483.rs
index f071d110f32..76dd1c2eb58 100644
--- a/src/test/ui/issues/issue-43483.rs
+++ b/src/test/ui/issues/issue-43483.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(unused_variables)]
 trait VecN {
diff --git a/src/test/ui/issues/issue-44005.rs b/src/test/ui/issues/issue-44005.rs
index f6fe9fcbd89..041fcdbf823 100644
--- a/src/test/ui/issues/issue-44005.rs
+++ b/src/test/ui/issues/issue-44005.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 pub trait Foo<'a> {
     type Bar;
     fn foo(&'a self) -> Self::Bar;
diff --git a/src/test/ui/issues/issue-44056.rs b/src/test/ui/issues/issue-44056.rs
index 42f30bf3023..a4903ed2cb4 100644
--- a/src/test/ui/issues/issue-44056.rs
+++ b/src/test/ui/issues/issue-44056.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass (FIXME(55996): should be run on targets supporting avx)
 // only-x86_64
 // no-prefer-dynamic
 // compile-flags: -Ctarget-feature=+avx -Clto
diff --git a/src/test/ui/issues/issue-44247.rs b/src/test/ui/issues/issue-44247.rs
index ef244e03857..3544880fade 100644
--- a/src/test/ui/issues/issue-44247.rs
+++ b/src/test/ui/issues/issue-44247.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 trait T {
     type X;
diff --git a/src/test/ui/issues/issue-44373-2.rs b/src/test/ui/issues/issue-44373-2.rs
index 7fdc4b1ee5b..194ce1dca77 100644
--- a/src/test/ui/issues/issue-44373-2.rs
+++ b/src/test/ui/issues/issue-44373-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 struct Foo(bool);
diff --git a/src/test/ui/issues/issue-4464.rs b/src/test/ui/issues/issue-4464.rs
index 13df6112482..7ac107150a0 100644
--- a/src/test/ui/issues/issue-4464.rs
+++ b/src/test/ui/issues/issue-4464.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-44730.rs b/src/test/ui/issues/issue-44730.rs
index 93f0445d343..0493811b279 100644
--- a/src/test/ui/issues/issue-44730.rs
+++ b/src/test/ui/issues/issue-44730.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 //! dox
 
 #![deny(missing_docs)]
diff --git a/src/test/ui/issues/issue-44851.rs b/src/test/ui/issues/issue-44851.rs
index 735678047a5..23daaeb0f00 100644
--- a/src/test/ui/issues/issue-44851.rs
+++ b/src/test/ui/issues/issue-44851.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 macro_rules! a {
     () => { "a" }
 }
diff --git a/src/test/ui/issues/issue-45425.rs b/src/test/ui/issues/issue-45425.rs
index 99e018ba6c8..10ce374eada 100644
--- a/src/test/ui/issues/issue-45425.rs
+++ b/src/test/ui/issues/issue-45425.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 use std::ops::Add;
 
diff --git a/src/test/ui/issues/issue-46959.rs b/src/test/ui/issues/issue-46959.rs
index 86f1158c198..3611a956836 100644
--- a/src/test/ui/issues/issue-46959.rs
+++ b/src/test/ui/issues/issue-46959.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![deny(non_camel_case_types)]
 
 #[allow(dead_code)]
diff --git a/src/test/ui/issues/issue-46964.rs b/src/test/ui/issues/issue-46964.rs
index 9cf53973d87..28fa92f2091 100644
--- a/src/test/ui/issues/issue-46964.rs
+++ b/src/test/ui/issues/issue-46964.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 mod my_mod {
     #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
     pub struct Name<'a> {
diff --git a/src/test/ui/issues/issue-47094.rs b/src/test/ui/issues/issue-47094.rs
index f17d4f88d90..97da984d4af 100644
--- a/src/test/ui/issues/issue-47094.rs
+++ b/src/test/ui/issues/issue-47094.rs
@@ -1,12 +1,12 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
-#[repr(C,u8)]
+#[repr(C,u8)] //~ WARNING conflicting representation hints
 enum Foo {
     A,
     B,
 }
 
-#[repr(C)]
+#[repr(C)] //~ WARNING conflicting representation hints
 #[repr(u8)]
 enum Bar {
     A,
diff --git a/src/test/ui/issues/issue-47309.rs b/src/test/ui/issues/issue-47309.rs
index 03092022d4d..abed9687b49 100644
--- a/src/test/ui/issues/issue-47309.rs
+++ b/src/test/ui/issues/issue-47309.rs
@@ -3,7 +3,7 @@
 // See https://github.com/rust-lang/rust/issues/47309
 
 // compile-flags:-Clink-dead-code
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 #![crate_type="rlib"]
 
diff --git a/src/test/ui/issues/issue-47673.rs b/src/test/ui/issues/issue-47673.rs
index 0d813e2fad2..b5f0febfbee 100644
--- a/src/test/ui/issues/issue-47673.rs
+++ b/src/test/ui/issues/issue-47673.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(unused_imports)]
 
 use {{}, {}};
diff --git a/src/test/ui/issues/issue-47703-1.rs b/src/test/ui/issues/issue-47703-1.rs
index 95738828647..61d684c2a81 100644
--- a/src/test/ui/issues/issue-47703-1.rs
+++ b/src/test/ui/issues/issue-47703-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct AtomicRefMut<'a> {
     value: &'a mut i32,
diff --git a/src/test/ui/issues/issue-47703-tuple.rs b/src/test/ui/issues/issue-47703-tuple.rs
index 1b285f219dc..bad187ead81 100644
--- a/src/test/ui/issues/issue-47703-tuple.rs
+++ b/src/test/ui/issues/issue-47703-tuple.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct WithDrop;
 
diff --git a/src/test/ui/issues/issue-47703.rs b/src/test/ui/issues/issue-47703.rs
index dbf49c7621f..38be6f5d2a9 100644
--- a/src/test/ui/issues/issue-47703.rs
+++ b/src/test/ui/issues/issue-47703.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct MyStruct<'a> {
     field: &'a mut (),
diff --git a/src/test/ui/issues/issue-47722.rs b/src/test/ui/issues/issue-47722.rs
index b3c344257b6..5645a634343 100644
--- a/src/test/ui/issues/issue-47722.rs
+++ b/src/test/ui/issues/issue-47722.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Tests that automatic coercions from &mut T to *mut T
 // allow borrows of T to expire immediately - essentially, that
diff --git a/src/test/ui/issues/issue-47789.rs b/src/test/ui/issues/issue-47789.rs
index 28671db0998..32dd909b2e9 100644
--- a/src/test/ui/issues/issue-47789.rs
+++ b/src/test/ui/issues/issue-47789.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(non_upper_case_globals)]
 
 static mut x: &'static u32 = &0;
diff --git a/src/test/ui/issues/issue-4830.rs b/src/test/ui/issues/issue-4830.rs
index 3724bb6393c..a8553bd6bf3 100644
--- a/src/test/ui/issues/issue-4830.rs
+++ b/src/test/ui/issues/issue-4830.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 // pretty-expanded FIXME #23616
diff --git a/src/test/ui/issues/issue-48551.rs b/src/test/ui/issues/issue-48551.rs
index 903b2e29929..b95a4832bb2 100644
--- a/src/test/ui/issues/issue-48551.rs
+++ b/src/test/ui/issues/issue-48551.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // Regression test for #48551. Covers a case where duplicate candidates
 // arose during associated type projection.
 
diff --git a/src/test/ui/issues/issue-49556.rs b/src/test/ui/issues/issue-49556.rs
index d3c6d17f416..c8c172f0e2f 100644
--- a/src/test/ui/issues/issue-49556.rs
+++ b/src/test/ui/issues/issue-49556.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 fn iter<'a>(data: &'a [usize]) -> impl Iterator<Item = usize> + 'a {
     data.iter()
         .map(
diff --git a/src/test/ui/issues/issue-49579.rs b/src/test/ui/issues/issue-49579.rs
index 767e06c4e90..98de014e90b 100644
--- a/src/test/ui/issues/issue-49579.rs
+++ b/src/test/ui/issues/issue-49579.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn fibs(n: u32) -> impl Iterator<Item=u128> {
     (0 .. n)
diff --git a/src/test/ui/issues/issue-50187.rs b/src/test/ui/issues/issue-50187.rs
index f530c3853e3..4b0aeaab410 100644
--- a/src/test/ui/issues/issue-50187.rs
+++ b/src/test/ui/issues/issue-50187.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(decl_macro)]
 
diff --git a/src/test/ui/issues/issue-50411.rs b/src/test/ui/issues/issue-50411.rs
index a32faa69841..1bf12707817 100644
--- a/src/test/ui/issues/issue-50411.rs
+++ b/src/test/ui/issues/issue-50411.rs
@@ -4,7 +4,7 @@
 // second time. Uncool.
 
 // compile-flags:-Zmir-opt-level=3
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 fn main() {
     let _ = (0 .. 1).filter(|_| [1].iter().all(|_| true)).count();
diff --git a/src/test/ui/issues/issue-50471.rs b/src/test/ui/issues/issue-50471.rs
index e728e45e60b..7278c392d54 100644
--- a/src/test/ui/issues/issue-50471.rs
+++ b/src/test/ui/issues/issue-50471.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     assert!({false});
diff --git a/src/test/ui/issues/issue-50518.rs b/src/test/ui/issues/issue-50518.rs
index 653b52902d2..1e7b7794929 100644
--- a/src/test/ui/issues/issue-50518.rs
+++ b/src/test/ui/issues/issue-50518.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 use std::marker::PhantomData;
 
 struct Meta<A> {
diff --git a/src/test/ui/issues/issue-50761.rs b/src/test/ui/issues/issue-50761.rs
index 59d4f9afdaa..1bf494ba8f9 100644
--- a/src/test/ui/issues/issue-50761.rs
+++ b/src/test/ui/issues/issue-50761.rs
@@ -1,6 +1,6 @@
 // Confirm that we don't accidentally divide or mod by zero in llvm_type
 
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 mod a {
     pub trait A {}
diff --git a/src/test/ui/issues/issue-50993.rs b/src/test/ui/issues/issue-50993.rs
index b170e09d02d..d38eb826678 100644
--- a/src/test/ui/issues/issue-50993.rs
+++ b/src/test/ui/issues/issue-50993.rs
@@ -1,5 +1,5 @@
 // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf`
 
 #![feature(no_core)]
diff --git a/src/test/ui/issues/issue-51582.rs b/src/test/ui/issues/issue-51582.rs
index 63ef05729bc..40a70c623a7 100644
--- a/src/test/ui/issues/issue-51582.rs
+++ b/src/test/ui/issues/issue-51582.rs
@@ -14,5 +14,5 @@ fn main() {
     assert_eq!(1, make_b() as u8);
     assert_eq!(1, make_b() as i32);
     assert_eq!(1, make_b() as u32);
-    assert_eq!(1, unsafe { std::intrinsics::discriminant_value(&make_b()) });
+    assert_eq!(1, std::intrinsics::discriminant_value(&make_b()));
 }
diff --git a/src/test/ui/issues/issue-51655.rs b/src/test/ui/issues/issue-51655.rs
index c2ad60fd8cf..36fd90dabed 100644
--- a/src/test/ui/issues/issue-51655.rs
+++ b/src/test/ui/issues/issue-51655.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 const PATH_DOT: &[u8] = &[b'.'];
diff --git a/src/test/ui/issues/issue-51907.rs b/src/test/ui/issues/issue-51907.rs
index 3691fe19117..1946611a17c 100644
--- a/src/test/ui/issues/issue-51907.rs
+++ b/src/test/ui/issues/issue-51907.rs
@@ -6,7 +6,9 @@ trait Foo {
 
 struct Bar;
 impl Foo for Bar {
+    #[allow(improper_ctypes)]
     extern fn borrow(&self) {}
+    #[allow(improper_ctypes)]
     extern fn take(self: Box<Self>) {}
 }
 
diff --git a/src/test/ui/issues/issue-51947.rs b/src/test/ui/issues/issue-51947.rs
index b5ebf156a27..c877fb8aef1 100644
--- a/src/test/ui/issues/issue-51947.rs
+++ b/src/test/ui/issues/issue-51947.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 #![crate_type = "lib"]
 #![feature(linkage)]
diff --git a/src/test/ui/issues/issue-52992.rs b/src/test/ui/issues/issue-52992.rs
index 727dd43d574..530d1a61b31 100644
--- a/src/test/ui/issues/issue-52992.rs
+++ b/src/test/ui/issues/issue-52992.rs
@@ -2,7 +2,7 @@
 // implied bounds was causing outlives relations that were not
 // properly handled.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {}
 
diff --git a/src/test/ui/issues/issue-53419.rs b/src/test/ui/issues/issue-53419.rs
index 64ac0b1c03b..892ec66afec 100644
--- a/src/test/ui/issues/issue-53419.rs
+++ b/src/test/ui/issues/issue-53419.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Foo {
     bar: dyn for<'r> Fn(usize, &'r dyn FnMut())
diff --git a/src/test/ui/issues/issue-5353.rs b/src/test/ui/issues/issue-5353.rs
index cca17595051..1d6813d5a39 100644
--- a/src/test/ui/issues/issue-5353.rs
+++ b/src/test/ui/issues/issue-5353.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-53568.rs b/src/test/ui/issues/issue-53568.rs
index 7644810c947..49ae444f97e 100644
--- a/src/test/ui/issues/issue-53568.rs
+++ b/src/test/ui/issues/issue-53568.rs
@@ -1,7 +1,7 @@
 // Regression test for an NLL-related ICE (#53568) -- we failed to
 // resolve inference variables in "custom type-ops".
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Future {
     type Item;
diff --git a/src/test/ui/issues/issue-53675-a-test-called-panic.rs b/src/test/ui/issues/issue-53675-a-test-called-panic.rs
index b8dca96946a..e573038980d 100644
--- a/src/test/ui/issues/issue-53675-a-test-called-panic.rs
+++ b/src/test/ui/issues/issue-53675-a-test-called-panic.rs
@@ -1,7 +1,7 @@
 // rust-lang/rust#53675: At one point the compiler errored when a test
 // named `panic` used the `assert!` macro in expression position.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags: --test
 
 mod in_expression_position {
diff --git a/src/test/ui/issues/issue-53912.rs b/src/test/ui/issues/issue-53912.rs
index 4718aea0429..65b6825a832 100644
--- a/src/test/ui/issues/issue-53912.rs
+++ b/src/test/ui/issues/issue-53912.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 // This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the
 // reproduction compiles successfully and doesn't segfault, whereas that test just checks that the
diff --git a/src/test/ui/issues/issue-54387.rs b/src/test/ui/issues/issue-54387.rs
index 7aee500744d..60e3a02f4ce 100644
--- a/src/test/ui/issues/issue-54387.rs
+++ b/src/test/ui/issues/issue-54387.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub struct GstRc {
     _obj: *const (),
diff --git a/src/test/ui/issues/issue-54521-1.rs b/src/test/ui/issues/issue-54521-1.rs
index 9bda7635eff..8a682ef0a11 100644
--- a/src/test/ui/issues/issue-54521-1.rs
+++ b/src/test/ui/issues/issue-54521-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // This test checks that the `remove extra angle brackets` error doesn't happen for some
 // potential edge-cases..
diff --git a/src/test/ui/issues/issue-54943-1.rs b/src/test/ui/issues/issue-54943-1.rs
index eca27819a40..ec682d96081 100644
--- a/src/test/ui/issues/issue-54943-1.rs
+++ b/src/test/ui/issues/issue-54943-1.rs
@@ -1,7 +1,7 @@
 // This test is a minimal version of an ICE in the dropck-eyepatch tests
 // found in the fix for #54943.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn foo<T>(_t: T) {
 }
diff --git a/src/test/ui/issues/issue-54943-2.rs b/src/test/ui/issues/issue-54943-2.rs
index c32f85dbe1a..d400ae58db4 100644
--- a/src/test/ui/issues/issue-54943-2.rs
+++ b/src/test/ui/issues/issue-54943-2.rs
@@ -2,7 +2,7 @@
 // found in the fix for #54943. In particular, this test is in unreachable
 // code as the initial fix for this ICE only worked if the code was reachable.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn foo<T>(_t: T) {
 }
diff --git a/src/test/ui/issues/issue-54943-3.rs b/src/test/ui/issues/issue-54943-3.rs
index ef705946ad4..e6c2611b683 100644
--- a/src/test/ui/issues/issue-54943-3.rs
+++ b/src/test/ui/issues/issue-54943-3.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // FIXME(#54943) This test targets the scenario where proving the WF requirements requires
 // knowing the value of the `_` type present in the user type annotation - unfortunately, figuring
 // out the value of that `_` requires type-checking the surrounding code, but that code is dead,
diff --git a/src/test/ui/issues/issue-5500-1.rs b/src/test/ui/issues/issue-5500-1.rs
index edbbe33c66f..98d6e1a14cb 100644
--- a/src/test/ui/issues/issue-5500-1.rs
+++ b/src/test/ui/issues/issue-5500-1.rs
@@ -2,7 +2,7 @@
 // is OK because the test is here to check that the compiler doesn't ICE (cf.
 // #5500).
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct TrieMapIterator<'a> {
     node: &'a usize
diff --git a/src/test/ui/issues/issue-5572.rs b/src/test/ui/issues/issue-5572.rs
index db26b0372a6..175dc879dda 100644
--- a/src/test/ui/issues/issue-5572.rs
+++ b/src/test/ui/issues/issue-5572.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs
index 32d87586cf4..10b50943c23 100644
--- a/src/test/ui/issues/issue-56128.rs
+++ b/src/test/ui/issues/issue-56128.rs
@@ -1,7 +1,7 @@
 // Regression test for #56128. When this `pub(super) use...` gets
 // exploded in the HIR, we were not handling ids correctly.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 mod bar {
     pub(super) use self::baz::{x, y};
diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs
index 6d6f23d2844..0952843e60a 100644
--- a/src/test/ui/issues/issue-56202.rs
+++ b/src/test/ui/issues/issue-56202.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 
 trait FooTrait {}
 
diff --git a/src/test/ui/issues/issue-56411-aux.rs b/src/test/ui/issues/issue-56411-aux.rs
index 6880a8a98d2..c8e5a059810 100644
--- a/src/test/ui/issues/issue-56411-aux.rs
+++ b/src/test/ui/issues/issue-56411-aux.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct T {}
 
diff --git a/src/test/ui/issues/issue-57156.rs b/src/test/ui/issues/issue-57156.rs
index b6cd8c927a2..9f5ec9f2771 100644
--- a/src/test/ui/issues/issue-57156.rs
+++ b/src/test/ui/issues/issue-57156.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo<Args> {
     type Output;
diff --git a/src/test/ui/issues/issue-57162.rs b/src/test/ui/issues/issue-57162.rs
index 7ba2f9cea84..65070060287 100644
--- a/src/test/ui/issues/issue-57162.rs
+++ b/src/test/ui/issues/issue-57162.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo {}
 impl Foo for dyn Send {}
diff --git a/src/test/ui/issues/issue-57410-1.rs b/src/test/ui/issues/issue-57410-1.rs
index c4247b3b11c..d825cb18008 100644
--- a/src/test/ui/issues/issue-57410-1.rs
+++ b/src/test/ui/issues/issue-57410-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Originally from #53925.
 // Tests that the `unreachable_pub` lint doesn't fire for `pub self::bar::Bar`.
diff --git a/src/test/ui/issues/issue-57410.rs b/src/test/ui/issues/issue-57410.rs
index de7ae4b3c07..0cf4b8068e4 100644
--- a/src/test/ui/issues/issue-57410.rs
+++ b/src/test/ui/issues/issue-57410.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Tests that the `unreachable_pub` lint doesn't fire for `pub self::imp::f`.
 
diff --git a/src/test/ui/issues/issue-5754.rs b/src/test/ui/issues/issue-5754.rs
index a629729d395..d90816635ab 100644
--- a/src/test/ui/issues/issue-5754.rs
+++ b/src/test/ui/issues/issue-5754.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
diff --git a/src/test/ui/issues/issue-5884.rs b/src/test/ui/issues/issue-5884.rs
index acb3e19765e..2f64342a6dd 100644
--- a/src/test/ui/issues/issue-5884.rs
+++ b/src/test/ui/issues/issue-5884.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-5900.rs b/src/test/ui/issues/issue-5900.rs
index 850e67db629..a7dc0eff43a 100644
--- a/src/test/ui/issues/issue-5900.rs
+++ b/src/test/ui/issues/issue-5900.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-5950.rs b/src/test/ui/issues/issue-5950.rs
index 5c2250e25fc..492a9d5723a 100644
--- a/src/test/ui/issues/issue-5950.rs
+++ b/src/test/ui/issues/issue-5950.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-60662.rs b/src/test/ui/issues/issue-60662.rs
index dcf935c5780..967c5f8ed73 100644
--- a/src/test/ui/issues/issue-60662.rs
+++ b/src/test/ui/issues/issue-60662.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags: -Z unpretty=hir
 
 #![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/issues/issue-60662.stdout b/src/test/ui/issues/issue-60662.stdout
index e2a88dec97f..5a4b49cfa1e 100644
--- a/src/test/ui/issues/issue-60662.stdout
+++ b/src/test/ui/issues/issue-60662.stdout
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // compile-flags: -Z unpretty=hir
 
 #![feature(type_alias_impl_trait)]
diff --git a/src/test/ui/issues/issue-6341.rs b/src/test/ui/issues/issue-6341.rs
index 2fb0fee60ba..1be1394dfae 100644
--- a/src/test/ui/issues/issue-6341.rs
+++ b/src/test/ui/issues/issue-6341.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 #[derive(PartialEq)]
diff --git a/src/test/ui/issues/issue-6470.rs b/src/test/ui/issues/issue-6470.rs
index 305f46c6d4e..0c86a648828 100644
--- a/src/test/ui/issues/issue-6470.rs
+++ b/src/test/ui/issues/issue-6470.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 #![allow(improper_ctypes)]
 
diff --git a/src/test/ui/issues/issue-6557.rs b/src/test/ui/issues/issue-6557.rs
index 70b301d3d9c..e066aa52923 100644
--- a/src/test/ui/issues/issue-6557.rs
+++ b/src/test/ui/issues/issue-6557.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-6898.rs b/src/test/ui/issues/issue-6898.rs
index 6bf20d71d1f..44fd4bd0735 100644
--- a/src/test/ui/issues/issue-6898.rs
+++ b/src/test/ui/issues/issue-6898.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // pretty-expanded FIXME #23616
 
 use std::mem;
diff --git a/src/test/ui/issues/issue-6991.rs b/src/test/ui/issues/issue-6991.rs
index aae67637f2c..f00cd9aeffd 100644
--- a/src/test/ui/issues/issue-6991.rs
+++ b/src/test/ui/issues/issue-6991.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_upper_case_globals)]
 
diff --git a/src/test/ui/issues/issue-7268.rs b/src/test/ui/issues/issue-7268.rs
index 69901e97894..309176fb0c5 100644
--- a/src/test/ui/issues/issue-7268.rs
+++ b/src/test/ui/issues/issue-7268.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-7607-2.rs b/src/test/ui/issues/issue-7607-2.rs
index e336e0b47b2..420a0ffd3cc 100644
--- a/src/test/ui/issues/issue-7607-2.rs
+++ b/src/test/ui/issues/issue-7607-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
index 9570386730a..2961dc79f10 100644
--- a/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
+++ b/src/test/ui/issues/issue-7673-cast-generically-implemented-trait.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
index 653d002fa61..505e7b84b5c 100644
--- a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
+++ b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-8398.rs b/src/test/ui/issues/issue-8398.rs
index 5fe88854b39..0ef39b6a6b3 100644
--- a/src/test/ui/issues/issue-8398.rs
+++ b/src/test/ui/issues/issue-8398.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-8521.rs b/src/test/ui/issues/issue-8521.rs
index 02a0e14d55e..15fbd4465a0 100644
--- a/src/test/ui/issues/issue-8521.rs
+++ b/src/test/ui/issues/issue-8521.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 trait Foo1 {}
 
 trait A {}
diff --git a/src/test/ui/issues/issue-8578.rs b/src/test/ui/issues/issue-8578.rs
index 6ffb721372a..2346ef5a950 100644
--- a/src/test/ui/issues/issue-8578.rs
+++ b/src/test/ui/issues/issue-8578.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
diff --git a/src/test/ui/issues/issue-9110.rs b/src/test/ui/issues/issue-9110.rs
index f3bab42ee16..cbf3c92d033 100644
--- a/src/test/ui/issues/issue-9110.rs
+++ b/src/test/ui/issues/issue-9110.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 #![allow(non_snake_case)]
diff --git a/src/test/ui/issues/issue-9243.rs b/src/test/ui/issues/issue-9243.rs
index 78237421c98..59fdb466285 100644
--- a/src/test/ui/issues/issue-9243.rs
+++ b/src/test/ui/issues/issue-9243.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // Regression test for issue 9243
 #![allow(non_upper_case_globals)]
diff --git a/src/test/ui/issues/issue-9249.rs b/src/test/ui/issues/issue-9249.rs
index b1f2bd7569a..caaba668ad7 100644
--- a/src/test/ui/issues/issue-9249.rs
+++ b/src/test/ui/issues/issue-9249.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/issues/issue-9719.rs b/src/test/ui/issues/issue-9719.rs
index 58eb32b111d..e8c3c9c194a 100644
--- a/src/test/ui/issues/issue-9719.rs
+++ b/src/test/ui/issues/issue-9719.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// build-pass
 #![allow(dead_code)]
 // pretty-expanded FIXME #23616
 
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.fixed b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
new file mode 100644
index 00000000000..f88a52d3159
--- /dev/null
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.fixed
@@ -0,0 +1,33 @@
+// run-pass
+// run-rustfix
+
+fn main() {
+    let small = [1, 2];
+    let big = [0u8; 33];
+
+    // Expressions that should trigger the lint
+    small.iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [1, 2].iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    big.iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [0u8; 33].iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+
+
+    // Expressions that should not
+    (&[1, 2]).into_iter();
+    (&small).into_iter();
+    (&[0u8; 33]).into_iter();
+    (&big).into_iter();
+
+    for _ in &[1, 2] {}
+    (&small as &[_]).into_iter();
+    small[..].into_iter();
+    std::iter::IntoIterator::into_iter(&[1, 2]);
+}
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.rs b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
new file mode 100644
index 00000000000..e1a4b535f38
--- /dev/null
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.rs
@@ -0,0 +1,33 @@
+// run-pass
+// run-rustfix
+
+fn main() {
+    let small = [1, 2];
+    let big = [0u8; 33];
+
+    // Expressions that should trigger the lint
+    small.into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [1, 2].into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    big.into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+    [0u8; 33].into_iter();
+    //~^ WARNING this method call currently resolves to `<&[T] as IntoIterator>::into_iter`
+    //~| WARNING this was previously accepted by the compiler but is being phased out
+
+
+    // Expressions that should not
+    (&[1, 2]).into_iter();
+    (&small).into_iter();
+    (&[0u8; 33]).into_iter();
+    (&big).into_iter();
+
+    for _ in &[1, 2] {}
+    (&small as &[_]).into_iter();
+    small[..].into_iter();
+    std::iter::IntoIterator::into_iter(&[1, 2]);
+}
diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
new file mode 100644
index 00000000000..b5964bd44bf
--- /dev/null
+++ b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr
@@ -0,0 +1,37 @@
+warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:9:11
+   |
+LL |     small.into_iter();
+   |           ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = note: `#[warn(array_into_iter)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
+warning: this method call currently resolves to `<&[T; N] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:12:12
+   |
+LL |     [1, 2].into_iter();
+   |            ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
+warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:15:9
+   |
+LL |     big.into_iter();
+   |         ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
+warning: this method call currently resolves to `<&[T] as IntoIterator>::into_iter` (due to autoref coercions), but that might change in the future when `IntoIterator` impls for arrays are added.
+  --> $DIR/into-iter-on-arrays-lint.rs:18:15
+   |
+LL |     [0u8; 33].into_iter();
+   |               ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #66145 <https://github.com/rust-lang/rust/issues/66145>
+
diff --git a/src/test/ui/dead-code-alias-in-pat.rs b/src/test/ui/lint/dead-code/alias-in-pat.rs
index 69d455f3b60..69d455f3b60 100644
--- a/src/test/ui/dead-code-alias-in-pat.rs
+++ b/src/test/ui/lint/dead-code/alias-in-pat.rs
diff --git a/src/test/ui/lint-dead-code-associated-type.rs b/src/test/ui/lint/dead-code/associated-type.rs
index 1cf66e75a95..1cf66e75a95 100644
--- a/src/test/ui/lint-dead-code-associated-type.rs
+++ b/src/test/ui/lint/dead-code/associated-type.rs
diff --git a/src/test/ui/fail-no-dead-code.rs b/src/test/ui/lint/dead-code/basic.rs
index 2b69985d33d..2b69985d33d 100644
--- a/src/test/ui/fail-no-dead-code.rs
+++ b/src/test/ui/lint/dead-code/basic.rs
diff --git a/src/test/ui/fail-no-dead-code.stderr b/src/test/ui/lint/dead-code/basic.stderr
index 8babcffaa8d..194398e5a07 100644
--- a/src/test/ui/fail-no-dead-code.stderr
+++ b/src/test/ui/lint/dead-code/basic.stderr
@@ -1,11 +1,11 @@
 error: function is never used: `foo`
-  --> $DIR/fail-no-dead-code.rs:4:1
+  --> $DIR/basic.rs:4:4
    |
 LL | fn foo() {
-   | ^^^^^^^^
+   |    ^^^
    |
 note: lint level defined here
-  --> $DIR/fail-no-dead-code.rs:1:9
+  --> $DIR/basic.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/dead-code-closure-bang.rs b/src/test/ui/lint/dead-code/closure-bang.rs
index 8e8636b1180..8e8636b1180 100644
--- a/src/test/ui/dead-code-closure-bang.rs
+++ b/src/test/ui/lint/dead-code/closure-bang.rs
diff --git a/src/test/ui/lint/lint-dead-code-const-and-self.rs b/src/test/ui/lint/dead-code/const-and-self.rs
index 1a7b3f43cda..1a7b3f43cda 100644
--- a/src/test/ui/lint/lint-dead-code-const-and-self.rs
+++ b/src/test/ui/lint/dead-code/const-and-self.rs
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs b/src/test/ui/lint/dead-code/empty-unused-enum.rs
index 834681d77e6..834681d77e6 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs
+++ b/src/test/ui/lint/dead-code/empty-unused-enum.rs
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr b/src/test/ui/lint/dead-code/empty-unused-enum.stderr
index 4e3bebfc48b..44b0a8f613e 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr
+++ b/src/test/ui/lint/dead-code/empty-unused-enum.stderr
@@ -1,11 +1,11 @@
 error: enum is never used: `E`
-  --> $DIR/lint-dead-code-empty-unused-enum.rs:3:1
+  --> $DIR/empty-unused-enum.rs:3:6
    |
 LL | enum E {}
-   | ^^^^^^
+   |      ^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-empty-unused-enum.rs:1:9
+  --> $DIR/empty-unused-enum.rs:1:9
    |
 LL | #![deny(unused)]
    |         ^^^^^^
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs b/src/test/ui/lint/dead-code/empty-unused-public-enum.rs
index 15b04496ba7..15b04496ba7 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
+++ b/src/test/ui/lint/dead-code/empty-unused-public-enum.rs
diff --git a/src/test/ui/lint-dead-code-variant.rs b/src/test/ui/lint/dead-code/enum-variants.rs
index 91c97232eed..91c97232eed 100644
--- a/src/test/ui/lint-dead-code-variant.rs
+++ b/src/test/ui/lint/dead-code/enum-variants.rs
diff --git a/src/test/ui/lint/lint-dead-code-impl-trait.rs b/src/test/ui/lint/dead-code/impl-trait.rs
index a2736d97308..a2736d97308 100644
--- a/src/test/ui/lint/lint-dead-code-impl-trait.rs
+++ b/src/test/ui/lint/dead-code/impl-trait.rs
diff --git a/src/test/ui/lint/lint-dead-code-impl-trait.stderr b/src/test/ui/lint/dead-code/impl-trait.stderr
index 61d0954bf31..f2a78cc65e2 100644
--- a/src/test/ui/lint/lint-dead-code-impl-trait.stderr
+++ b/src/test/ui/lint/dead-code/impl-trait.stderr
@@ -1,11 +1,11 @@
 error: type alias is never used: `Unused`
-  --> $DIR/lint-dead-code-impl-trait.rs:12:1
+  --> $DIR/impl-trait.rs:12:1
    |
 LL | type Unused = ();
    | ^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-impl-trait.rs:1:9
+  --> $DIR/impl-trait.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/dead-code-leading-underscore.rs b/src/test/ui/lint/dead-code/leading-underscore.rs
index 1b6e03ab887..1b6e03ab887 100644
--- a/src/test/ui/dead-code-leading-underscore.rs
+++ b/src/test/ui/lint/dead-code/leading-underscore.rs
diff --git a/src/test/ui/lint/lint-dead-code-1.rs b/src/test/ui/lint/dead-code/lint-dead-code-1.rs
index 09977f8df51..09977f8df51 100644
--- a/src/test/ui/lint/lint-dead-code-1.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-1.rs
diff --git a/src/test/ui/lint/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr
index be96c697d99..bac46a2e843 100644
--- a/src/test/ui/lint/lint-dead-code-1.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr
@@ -1,8 +1,8 @@
 error: struct is never constructed: `Bar`
-  --> $DIR/lint-dead-code-1.rs:12:5
+  --> $DIR/lint-dead-code-1.rs:12:16
    |
 LL |     pub struct Bar;
-   |     ^^^^^^^^^^^^^^^
+   |                ^^^
    |
 note: lint level defined here
   --> $DIR/lint-dead-code-1.rs:5:9
@@ -23,16 +23,16 @@ LL | const priv_const: isize = 0;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: struct is never constructed: `PrivStruct`
-  --> $DIR/lint-dead-code-1.rs:35:1
+  --> $DIR/lint-dead-code-1.rs:35:8
    |
 LL | struct PrivStruct;
-   | ^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^
 
 error: enum is never used: `priv_enum`
-  --> $DIR/lint-dead-code-1.rs:64:1
+  --> $DIR/lint-dead-code-1.rs:64:6
    |
 LL | enum priv_enum { foo2, bar2 }
-   | ^^^^^^^^^^^^^^
+   |      ^^^^^^^^^
 
 error: variant is never constructed: `bar3`
   --> $DIR/lint-dead-code-1.rs:67:5
@@ -41,28 +41,28 @@ LL |     bar3
    |     ^^^^
 
 error: function is never used: `priv_fn`
-  --> $DIR/lint-dead-code-1.rs:88:1
+  --> $DIR/lint-dead-code-1.rs:88:4
    |
 LL | fn priv_fn() {
-   | ^^^^^^^^^^^^
+   |    ^^^^^^^
 
 error: function is never used: `foo`
-  --> $DIR/lint-dead-code-1.rs:93:1
+  --> $DIR/lint-dead-code-1.rs:93:4
    |
 LL | fn foo() {
-   | ^^^^^^^^
+   |    ^^^
 
 error: function is never used: `bar`
-  --> $DIR/lint-dead-code-1.rs:98:1
+  --> $DIR/lint-dead-code-1.rs:98:4
    |
 LL | fn bar() {
-   | ^^^^^^^^
+   |    ^^^
 
 error: function is never used: `baz`
-  --> $DIR/lint-dead-code-1.rs:102:1
+  --> $DIR/lint-dead-code-1.rs:102:4
    |
 LL | fn baz() -> impl Copy {
-   | ^^^^^^^^^^^^^^^^^^^^^
+   |    ^^^
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/lint/lint-dead-code-2.rs b/src/test/ui/lint/dead-code/lint-dead-code-2.rs
index 88db4f88c3f..88db4f88c3f 100644
--- a/src/test/ui/lint/lint-dead-code-2.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-2.rs
diff --git a/src/test/ui/lint/lint-dead-code-2.stderr b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr
index 1226f9823ac..a578a76d9a0 100644
--- a/src/test/ui/lint/lint-dead-code-2.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr
@@ -1,8 +1,8 @@
 error: function is never used: `dead_fn`
-  --> $DIR/lint-dead-code-2.rs:22:1
+  --> $DIR/lint-dead-code-2.rs:22:4
    |
 LL | fn dead_fn() {}
-   | ^^^^^^^^^^^^
+   |    ^^^^^^^
    |
 note: lint level defined here
   --> $DIR/lint-dead-code-2.rs:2:9
@@ -11,16 +11,16 @@ LL | #![deny(dead_code)]
    |         ^^^^^^^^^
 
 error: function is never used: `dead_fn2`
-  --> $DIR/lint-dead-code-2.rs:25:1
+  --> $DIR/lint-dead-code-2.rs:25:4
    |
 LL | fn dead_fn2() {}
-   | ^^^^^^^^^^^^^
+   |    ^^^^^^^^
 
 error: function is never used: `main`
-  --> $DIR/lint-dead-code-2.rs:38:1
+  --> $DIR/lint-dead-code-2.rs:38:4
    |
 LL | fn main() {
-   | ^^^^^^^^^
+   |    ^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/lint/lint-dead-code-3.rs b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
index 4397522f3f3..4397522f3f3 100644
--- a/src/test/ui/lint/lint-dead-code-3.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
diff --git a/src/test/ui/lint/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr
index 2408da0af89..569196fffdd 100644
--- a/src/test/ui/lint/lint-dead-code-3.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -1,8 +1,8 @@
 error: struct is never constructed: `Foo`
-  --> $DIR/lint-dead-code-3.rs:13:1
+  --> $DIR/lint-dead-code-3.rs:13:8
    |
 LL | struct Foo;
-   | ^^^^^^^^^^^
+   |        ^^^
    |
 note: lint level defined here
   --> $DIR/lint-dead-code-3.rs:3:9
@@ -17,16 +17,16 @@ LL |     fn foo(&self) {
    |     ^^^^^^^^^^^^^
 
 error: function is never used: `bar`
-  --> $DIR/lint-dead-code-3.rs:20:1
+  --> $DIR/lint-dead-code-3.rs:20:4
    |
 LL | fn bar() {
-   | ^^^^^^^^
+   |    ^^^
 
 error: enum is never used: `c_void`
-  --> $DIR/lint-dead-code-3.rs:59:1
+  --> $DIR/lint-dead-code-3.rs:59:6
    |
 LL | enum c_void {}
-   | ^^^^^^^^^^^
+   |      ^^^^^^
 
 error: foreign function is never used: `free`
   --> $DIR/lint-dead-code-3.rs:61:5
diff --git a/src/test/ui/lint/lint-dead-code-4.rs b/src/test/ui/lint/dead-code/lint-dead-code-4.rs
index 3f4a9e21040..3f4a9e21040 100644
--- a/src/test/ui/lint/lint-dead-code-4.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-4.rs
diff --git a/src/test/ui/lint/lint-dead-code-4.stderr b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr
index b7ceee99998..8eaf789f8f7 100644
--- a/src/test/ui/lint/lint-dead-code-4.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr
@@ -27,10 +27,10 @@ LL | |     },
    | |_____^
 
 error: enum is never used: `ABC`
-  --> $DIR/lint-dead-code-4.rs:24:1
+  --> $DIR/lint-dead-code-4.rs:24:6
    |
 LL | enum ABC {
-   | ^^^^^^^^
+   |      ^^^
 
 error: variant is never constructed: `I`
   --> $DIR/lint-dead-code-4.rs:36:5
diff --git a/src/test/ui/lint/lint-dead-code-5.rs b/src/test/ui/lint/dead-code/lint-dead-code-5.rs
index 764a23e4e49..764a23e4e49 100644
--- a/src/test/ui/lint/lint-dead-code-5.rs
+++ b/src/test/ui/lint/dead-code/lint-dead-code-5.rs
diff --git a/src/test/ui/lint/lint-dead-code-5.stderr b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr
index 740cfde2c06..9670d8e7a32 100644
--- a/src/test/ui/lint/lint-dead-code-5.stderr
+++ b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr
@@ -23,10 +23,10 @@ LL |     Variant6(isize),
    |     ^^^^^^^^^^^^^^^
 
 error: enum is never used: `Enum3`
-  --> $DIR/lint-dead-code-5.rs:18:1
+  --> $DIR/lint-dead-code-5.rs:18:6
    |
 LL | enum Enum3 {
-   | ^^^^^^^^^^
+   |      ^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/lint/dead-code/newline-span.rs b/src/test/ui/lint/dead-code/newline-span.rs
new file mode 100644
index 00000000000..a4342056419
--- /dev/null
+++ b/src/test/ui/lint/dead-code/newline-span.rs
@@ -0,0 +1,19 @@
+#![deny(dead_code)]
+
+fn unused() { //~ error: function is never used:
+    println!("blah");
+}
+
+fn unused2(var: i32) { //~ error: function is never used:
+    println!("foo {}", var);
+}
+
+fn unused3( //~ error: function is never used:
+    var: i32,
+) {
+    println!("bar {}", var);
+}
+
+fn main() {
+    println!("Hello world!");
+}
diff --git a/src/test/ui/lint/dead-code/newline-span.stderr b/src/test/ui/lint/dead-code/newline-span.stderr
new file mode 100644
index 00000000000..c5d0d605067
--- /dev/null
+++ b/src/test/ui/lint/dead-code/newline-span.stderr
@@ -0,0 +1,26 @@
+error: function is never used: `unused`
+  --> $DIR/newline-span.rs:3:4
+   |
+LL | fn unused() {
+   |    ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/newline-span.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: function is never used: `unused2`
+  --> $DIR/newline-span.rs:7:4
+   |
+LL | fn unused2(var: i32) {
+   |    ^^^^^^^
+
+error: function is never used: `unused3`
+  --> $DIR/newline-span.rs:11:4
+   |
+LL | fn unused3(
+   |    ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/dead-code-tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs
index 92a67950986..92a67950986 100644
--- a/src/test/ui/dead-code-tuple-struct-field.rs
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs
diff --git a/src/test/ui/lint/lint-dead-code-type-alias.rs b/src/test/ui/lint/dead-code/type-alias.rs
index 86daf3ea04d..86daf3ea04d 100644
--- a/src/test/ui/lint/lint-dead-code-type-alias.rs
+++ b/src/test/ui/lint/dead-code/type-alias.rs
diff --git a/src/test/ui/lint/lint-dead-code-type-alias.stderr b/src/test/ui/lint/dead-code/type-alias.stderr
index 4198ddfb6cb..82df23bd944 100644
--- a/src/test/ui/lint/lint-dead-code-type-alias.stderr
+++ b/src/test/ui/lint/dead-code/type-alias.stderr
@@ -1,11 +1,11 @@
 error: type alias is never used: `Unused`
-  --> $DIR/lint-dead-code-type-alias.rs:4:1
+  --> $DIR/type-alias.rs:4:1
    |
 LL | type Unused = u8;
    | ^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-type-alias.rs:1:9
+  --> $DIR/type-alias.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/lint/lint-dead-code-unused-enum.rs b/src/test/ui/lint/dead-code/unused-enum.rs
index e57fac259c5..e57fac259c5 100644
--- a/src/test/ui/lint/lint-dead-code-unused-enum.rs
+++ b/src/test/ui/lint/dead-code/unused-enum.rs
diff --git a/src/test/ui/lint/lint-dead-code-unused-enum.stderr b/src/test/ui/lint/dead-code/unused-enum.stderr
index ea711e7b05e..142c2ccb99b 100644
--- a/src/test/ui/lint/lint-dead-code-unused-enum.stderr
+++ b/src/test/ui/lint/dead-code/unused-enum.stderr
@@ -1,27 +1,27 @@
 error: struct is never constructed: `F`
-  --> $DIR/lint-dead-code-unused-enum.rs:3:1
+  --> $DIR/unused-enum.rs:3:8
    |
 LL | struct F;
-   | ^^^^^^^^^
+   |        ^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-unused-enum.rs:1:9
+  --> $DIR/unused-enum.rs:1:9
    |
 LL | #![deny(unused)]
    |         ^^^^^^
    = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
 
 error: struct is never constructed: `B`
-  --> $DIR/lint-dead-code-unused-enum.rs:4:1
+  --> $DIR/unused-enum.rs:4:8
    |
 LL | struct B;
-   | ^^^^^^^^^
+   |        ^
 
 error: enum is never used: `E`
-  --> $DIR/lint-dead-code-unused-enum.rs:6:1
+  --> $DIR/unused-enum.rs:6:6
    |
 LL | enum E {
-   | ^^^^^^
+   |      ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant.rs b/src/test/ui/lint/dead-code/unused-struct-variant.rs
index 69ab29042e5..69ab29042e5 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant.rs
+++ b/src/test/ui/lint/dead-code/unused-struct-variant.rs
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant.stderr b/src/test/ui/lint/dead-code/unused-struct-variant.stderr
index 919996ec300..0037592e3de 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-struct-variant.stderr
@@ -1,11 +1,11 @@
 error: variant is never constructed: `Bar`
-  --> $DIR/lint-dead-code-unused-variant.rs:8:5
+  --> $DIR/unused-struct-variant.rs:8:5
    |
 LL |     Bar(B),
    |     ^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-unused-variant.rs:1:9
+  --> $DIR/unused-struct-variant.rs:1:9
    |
 LL | #![deny(unused)]
    |         ^^^^^^
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs b/src/test/ui/lint/dead-code/unused-variant-pub.rs
index 3a9061340eb..3a9061340eb 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
+++ b/src/test/ui/lint/dead-code/unused-variant-pub.rs
diff --git a/src/test/ui/lint/lint-dead-code-variant.rs b/src/test/ui/lint/dead-code/unused-variant.rs
index 295ed16d4cf..295ed16d4cf 100644
--- a/src/test/ui/lint/lint-dead-code-variant.rs
+++ b/src/test/ui/lint/dead-code/unused-variant.rs
diff --git a/src/test/ui/lint/lint-dead-code-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr
index a79432dc68d..2167b9d910d 100644
--- a/src/test/ui/lint/lint-dead-code-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-variant.stderr
@@ -1,11 +1,11 @@
 error: variant is never constructed: `Variant1`
-  --> $DIR/lint-dead-code-variant.rs:5:5
+  --> $DIR/unused-variant.rs:5:5
    |
 LL |     Variant1,
    |     ^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-dead-code-variant.rs:1:9
+  --> $DIR/unused-variant.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/fail-no-dead-code-core.rs b/src/test/ui/lint/dead-code/with-core-crate.rs
index bc74e807783..bc74e807783 100644
--- a/src/test/ui/fail-no-dead-code-core.rs
+++ b/src/test/ui/lint/dead-code/with-core-crate.rs
diff --git a/src/test/ui/fail-no-dead-code-core.stderr b/src/test/ui/lint/dead-code/with-core-crate.stderr
index 2540242f9f6..0b6ab67d9bf 100644
--- a/src/test/ui/fail-no-dead-code-core.stderr
+++ b/src/test/ui/lint/dead-code/with-core-crate.stderr
@@ -1,11 +1,11 @@
 error: function is never used: `foo`
-  --> $DIR/fail-no-dead-code-core.rs:7:1
+  --> $DIR/with-core-crate.rs:7:4
    |
 LL | fn foo() {
-   | ^^^^^^^^
+   |    ^^^
    |
 note: lint level defined here
-  --> $DIR/fail-no-dead-code-core.rs:1:9
+  --> $DIR/with-core-crate.rs:1:9
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
diff --git a/src/test/ui/dead-code-impl.rs b/src/test/ui/lint/dead-code/with-impl.rs
index 84829c98e57..84829c98e57 100644
--- a/src/test/ui/dead-code-impl.rs
+++ b/src/test/ui/lint/dead-code/with-impl.rs
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
index 7870d394c8b..e7614355455 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(box_syntax)]
 #![feature(box_patterns)]
diff --git a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
index 47063a7c267..ab9baa79b8b 100644
--- a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
+++ b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(unused_parens)]
 
diff --git a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
index 3802e01a775..b2bf87358a4 100644
--- a/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
+++ b/src/test/ui/lint/issue-54099-camel-case-underscore-types.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![forbid(non_camel_case_types)]
 #![allow(dead_code)]
diff --git a/src/test/ui/lint/lint-ctypes-fn.rs b/src/test/ui/lint/lint-ctypes-fn.rs
new file mode 100644
index 00000000000..2daac70fedf
--- /dev/null
+++ b/src/test/ui/lint/lint-ctypes-fn.rs
@@ -0,0 +1,186 @@
+#![feature(rustc_private)]
+
+#![allow(private_in_public)]
+#![deny(improper_ctypes)]
+
+extern crate libc;
+
+use std::default::Default;
+use std::marker::PhantomData;
+
+trait Mirror { type It: ?Sized; }
+
+impl<T: ?Sized> Mirror for T { type It = Self; }
+
+#[repr(C)]
+pub struct StructWithProjection(*mut <StructWithProjection as Mirror>::It);
+
+#[repr(C)]
+pub struct StructWithProjectionAndLifetime<'a>(
+    &'a mut <StructWithProjectionAndLifetime<'a> as Mirror>::It
+);
+
+pub type I32Pair = (i32, i32);
+
+#[repr(C)]
+pub struct ZeroSize;
+
+pub type RustFn = fn();
+
+pub type RustBadRet = extern fn() -> Box<u32>;
+
+pub type CVoidRet = ();
+
+pub struct Foo;
+
+#[repr(transparent)]
+pub struct TransparentI128(i128);
+
+#[repr(transparent)]
+pub struct TransparentStr(&'static str);
+
+#[repr(transparent)]
+pub struct TransparentBadFn(RustBadRet);
+
+#[repr(transparent)]
+pub struct TransparentInt(u32);
+
+#[repr(transparent)]
+pub struct TransparentRef<'a>(&'a TransparentInt);
+
+#[repr(transparent)]
+pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>);
+
+#[repr(transparent)]
+pub struct TransparentUnit<U>(f32, PhantomData<U>);
+
+#[repr(transparent)]
+pub struct TransparentCustomZst(i32, ZeroSize);
+
+#[repr(C)]
+pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
+
+pub extern "C" fn ptr_type1(size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn ptr_type2(size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn slice_type(p: &[u32]) { }
+//~^ ERROR: uses type `[u32]`
+
+pub extern "C" fn str_type(p: &str) { }
+//~^ ERROR: uses type `str`
+
+pub extern "C" fn box_type(p: Box<u32>) { }
+//~^ ERROR uses type `std::boxed::Box<u32>`
+
+pub extern "C" fn char_type(p: char) { }
+//~^ ERROR uses type `char`
+
+pub extern "C" fn i128_type(p: i128) { }
+//~^ ERROR uses type `i128`
+
+pub extern "C" fn u128_type(p: u128) { }
+//~^ ERROR uses type `u128`
+
+pub extern "C" fn tuple_type(p: (i32, i32)) { }
+//~^ ERROR uses type `(i32, i32)`
+
+pub extern "C" fn tuple_type2(p: I32Pair) { }
+//~^ ERROR uses type `(i32, i32)`
+
+pub extern "C" fn zero_size(p: ZeroSize) { }
+//~^ ERROR uses type `ZeroSize`
+
+pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
+//~^ ERROR uses type `ZeroSizeWithPhantomData`
+
+pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
+//~^ ERROR uses type `std::marker::PhantomData<bool>`
+    Default::default()
+}
+
+pub extern "C" fn fn_type(p: RustFn) { }
+//~^ ERROR uses type `fn()`
+
+pub extern "C" fn fn_type2(p: fn()) { }
+//~^ ERROR uses type `fn()`
+
+pub extern "C" fn fn_contained(p: RustBadRet) { }
+//~^ ERROR: uses type `std::boxed::Box<u32>`
+
+pub extern "C" fn transparent_i128(p: TransparentI128) { }
+//~^ ERROR: uses type `i128`
+
+pub extern "C" fn transparent_str(p: TransparentStr) { }
+//~^ ERROR: uses type `str`
+
+pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
+//~^ ERROR: uses type `std::boxed::Box<u32>`
+
+pub extern "C" fn good3(fptr: Option<extern fn()>) { }
+
+pub extern "C" fn good4(aptr: &[u8; 4 as usize]) { }
+
+pub extern "C" fn good5(s: StructWithProjection) { }
+
+pub extern "C" fn good6(s: StructWithProjectionAndLifetime) { }
+
+pub extern "C" fn good7(fptr: extern fn() -> ()) { }
+
+pub extern "C" fn good8(fptr: extern fn() -> !) { }
+
+pub extern "C" fn good9() -> () { }
+
+pub extern "C" fn good10() -> CVoidRet { }
+
+pub extern "C" fn good11(size: isize) { }
+
+pub extern "C" fn good12(size: usize) { }
+
+pub extern "C" fn good13(n: TransparentInt) { }
+
+pub extern "C" fn good14(p: TransparentRef) { }
+
+pub extern "C" fn good15(p: TransparentLifetime) { }
+
+pub extern "C" fn good16(p: TransparentUnit<ZeroSize>) { }
+
+pub extern "C" fn good17(p: TransparentCustomZst) { }
+
+#[allow(improper_ctypes)]
+pub extern "C" fn good18(_: &String) { }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub extern "C" fn good1(size: *const libc::c_int) { }
+
+#[cfg(not(target_arch = "wasm32"))]
+pub extern "C" fn good2(size: *const libc::c_uint) { }
+
+pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
+//~^ ERROR uses type `std::marker::PhantomData<bool>`
+    Default::default()
+}
+
+pub extern "C" fn used_generic1<T>(x: T) { }
+
+pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
+//~^ ERROR: uses type `Foo`
+
+pub extern "C" fn used_generic3<T: Default>() -> T {
+    Default::default()
+}
+
+pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
+//~^ ERROR: uses type `std::vec::Vec<T>`
+
+pub extern "C" fn used_generic5<T>() -> Vec<T> {
+//~^ ERROR: uses type `std::vec::Vec<T>`
+    Default::default()
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr
new file mode 100644
index 00000000000..59bd6bfc5af
--- /dev/null
+++ b/src/test/ui/lint/lint-ctypes-fn.stderr
@@ -0,0 +1,247 @@
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:63:35
+   |
+LL | pub extern "C" fn ptr_type1(size: *const Foo) { }
+   |                                   ^^^^^^^^^^ not FFI-safe
+   |
+note: lint level defined here
+  --> $DIR/lint-ctypes-fn.rs:4:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:66:35
+   |
+LL | pub extern "C" fn ptr_type2(size: *const Foo) { }
+   |                                   ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `[u32]`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:69:33
+   |
+LL | pub extern "C" fn slice_type(p: &[u32]) { }
+   |                                 ^^^^^^ not FFI-safe
+   |
+   = help: consider using a raw pointer instead
+   = note: slices have no C equivalent
+
+error: `extern` fn uses type `str`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:72:31
+   |
+LL | pub extern "C" fn str_type(p: &str) { }
+   |                               ^^^^ not FFI-safe
+   |
+   = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
+
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:75:31
+   |
+LL | pub extern "C" fn box_type(p: Box<u32>) { }
+   |                               ^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `char`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:78:32
+   |
+LL | pub extern "C" fn char_type(p: char) { }
+   |                                ^^^^ not FFI-safe
+   |
+   = help: consider using `u32` or `libc::wchar_t` instead
+   = note: the `char` type has no C equivalent
+
+error: `extern` fn uses type `i128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:81:32
+   |
+LL | pub extern "C" fn i128_type(p: i128) { }
+   |                                ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `u128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:84:32
+   |
+LL | pub extern "C" fn u128_type(p: u128) { }
+   |                                ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:87:33
+   |
+LL | pub extern "C" fn tuple_type(p: (i32, i32)) { }
+   |                                 ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using a struct instead
+   = note: tuples have unspecified layout
+
+error: `extern` fn uses type `(i32, i32)`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:90:34
+   |
+LL | pub extern "C" fn tuple_type2(p: I32Pair) { }
+   |                                  ^^^^^^^ not FFI-safe
+   |
+   = help: consider using a struct instead
+   = note: tuples have unspecified layout
+
+error: `extern` fn uses type `ZeroSize`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:93:32
+   |
+LL | pub extern "C" fn zero_size(p: ZeroSize) { }
+   |                                ^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a member to this struct
+   = note: this struct has no fields
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:26:1
+   |
+LL | pub struct ZeroSize;
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:96:40
+   |
+LL | pub extern "C" fn zero_size_phantom(p: ZeroSizeWithPhantomData) { }
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:61:1
+   |
+LL | pub struct ZeroSizeWithPhantomData(PhantomData<i32>);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:99:51
+   |
+LL | pub extern "C" fn zero_size_phantom_toplevel() -> PhantomData<bool> {
+   |                                                   ^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+
+error: `extern` fn uses type `fn()`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:104:30
+   |
+LL | pub extern "C" fn fn_type(p: RustFn) { }
+   |                              ^^^^^^ not FFI-safe
+   |
+   = help: consider using an `extern fn(...) -> ...` function pointer instead
+   = note: this function pointer has Rust-specific calling convention
+
+error: `extern` fn uses type `fn()`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:107:31
+   |
+LL | pub extern "C" fn fn_type2(p: fn()) { }
+   |                               ^^^^ not FFI-safe
+   |
+   = help: consider using an `extern fn(...) -> ...` function pointer instead
+   = note: this function pointer has Rust-specific calling convention
+
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:110:35
+   |
+LL | pub extern "C" fn fn_contained(p: RustBadRet) { }
+   |                                   ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `i128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:113:39
+   |
+LL | pub extern "C" fn transparent_i128(p: TransparentI128) { }
+   |                                       ^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
+
+error: `extern` fn uses type `str`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:116:38
+   |
+LL | pub extern "C" fn transparent_str(p: TransparentStr) { }
+   |                                      ^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
+
+error: `extern` fn uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:119:37
+   |
+LL | pub extern "C" fn transparent_fn(p: TransparentBadFn) { }
+   |                                     ^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:161:44
+   |
+LL | pub extern "C" fn unused_generic1<T>(size: *const Foo) { }
+   |                                            ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:164:43
+   |
+LL | pub extern "C" fn unused_generic2<T>() -> PhantomData<bool> {
+   |                                           ^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+
+error: `extern` fn uses type `Foo`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:171:48
+   |
+LL | pub extern "C" fn used_generic2<T>(x: T, size: *const Foo) { }
+   |                                                ^^^^^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+note: type defined here
+  --> $DIR/lint-ctypes-fn.rs:34:1
+   |
+LL | pub struct Foo;
+   | ^^^^^^^^^^^^^^^
+
+error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:178:39
+   |
+LL | pub extern "C" fn used_generic4<T>(x: Vec<T>) { }
+   |                                       ^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: `extern` fn uses type `std::vec::Vec<T>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-fn.rs:181:41
+   |
+LL | pub extern "C" fn used_generic5<T>() -> Vec<T> {
+   |                                         ^^^^^^ not FFI-safe
+   |
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
+
+error: aborting due to 24 previous errors
+
diff --git a/src/test/ui/lint/uninitialized-zeroed.rs b/src/test/ui/lint/uninitialized-zeroed.rs
index 5cf62b86912..473be434a75 100644
--- a/src/test/ui/lint/uninitialized-zeroed.rs
+++ b/src/test/ui/lint/uninitialized-zeroed.rs
@@ -67,6 +67,9 @@ fn main() {
         let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization
         let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
 
+        let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization
+        let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
+
         // Things that can be zero, but not uninit.
         let _val: bool = mem::zeroed();
         let _val: bool = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized
@@ -82,10 +85,16 @@ fn main() {
         let _val: &'static [i32] = mem::transmute((0usize, 0usize)); //~ ERROR: does not permit zero-initialization
         let _val: NonZeroU32 = mem::transmute(0); //~ ERROR: does not permit zero-initialization
 
+        // `MaybeUninit` cases
+        let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); //~ ERROR: does not permit zero-initialization
+        let _val: NonNull<i32> = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized
+        let _val: bool = MaybeUninit::uninit().assume_init(); //~ ERROR: does not permit being left uninitialized
+
         // Some more types that should work just fine.
         let _val: Option<&'static i32> = mem::zeroed();
         let _val: Option<fn()> = mem::zeroed();
         let _val: MaybeUninit<&'static i32> = mem::zeroed();
         let _val: i32 = mem::zeroed();
+        let _val: bool = MaybeUninit::zeroed().assume_init();
     }
 }
diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr
index a36a32a39a1..bdb5959953f 100644
--- a/src/test/ui/lint/uninitialized-zeroed.stderr
+++ b/src/test/ui/lint/uninitialized-zeroed.stderr
@@ -5,7 +5,7 @@ LL |         let _val: &'static T = mem::zeroed();
    |                                ^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: lint level defined here
   --> $DIR/uninitialized-zeroed.rs:7:9
@@ -21,7 +21,7 @@ LL |         let _val: &'static T = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
@@ -32,7 +32,7 @@ LL |         let _val: Wrap<&'static T> = mem::zeroed();
    |                                      ^^^^^^^^^^^^^
    |                                      |
    |                                      this code causes undefined behavior when executed
-   |                                      help: use `MaybeUninit<T>` instead
+   |                                      help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -47,7 +47,7 @@ LL |         let _val: Wrap<&'static T> = mem::uninitialized();
    |                                      ^^^^^^^^^^^^^^^^^^^^
    |                                      |
    |                                      this code causes undefined behavior when executed
-   |                                      help: use `MaybeUninit<T>` instead
+   |                                      help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -62,7 +62,7 @@ LL |         let _val: ! = mem::zeroed();
    |                       ^^^^^^^^^^^^^
    |                       |
    |                       this code causes undefined behavior when executed
-   |                       help: use `MaybeUninit<T>` instead
+   |                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -73,7 +73,7 @@ LL |         let _val: ! = mem::uninitialized();
    |                       ^^^^^^^^^^^^^^^^^^^^
    |                       |
    |                       this code causes undefined behavior when executed
-   |                       help: use `MaybeUninit<T>` instead
+   |                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -84,7 +84,7 @@ LL |         let _val: (i32, !) = mem::zeroed();
    |                              ^^^^^^^^^^^^^
    |                              |
    |                              this code causes undefined behavior when executed
-   |                              help: use `MaybeUninit<T>` instead
+   |                              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -95,7 +95,7 @@ LL |         let _val: (i32, !) = mem::uninitialized();
    |                              ^^^^^^^^^^^^^^^^^^^^
    |                              |
    |                              this code causes undefined behavior when executed
-   |                              help: use `MaybeUninit<T>` instead
+   |                              help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: The never type (`!`) has no valid value
 
@@ -106,7 +106,7 @@ LL |         let _val: Void = mem::zeroed();
    |                          ^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: 0-variant enums have no valid value
 
@@ -117,7 +117,7 @@ LL |         let _val: Void = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: 0-variant enums have no valid value
 
@@ -128,7 +128,7 @@ LL |         let _val: &'static i32 = mem::zeroed();
    |                                  ^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
@@ -139,7 +139,7 @@ LL |         let _val: &'static i32 = mem::uninitialized();
    |                                  ^^^^^^^^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
@@ -150,7 +150,7 @@ LL |         let _val: Ref = mem::zeroed();
    |                         ^^^^^^^^^^^^^
    |                         |
    |                         this code causes undefined behavior when executed
-   |                         help: use `MaybeUninit<T>` instead
+   |                         help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:15:12
@@ -165,7 +165,7 @@ LL |         let _val: Ref = mem::uninitialized();
    |                         ^^^^^^^^^^^^^^^^^^^^
    |                         |
    |                         this code causes undefined behavior when executed
-   |                         help: use `MaybeUninit<T>` instead
+   |                         help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:15:12
@@ -180,7 +180,7 @@ LL |         let _val: fn() = mem::zeroed();
    |                          ^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: Function pointers must be non-null
 
@@ -191,7 +191,7 @@ LL |         let _val: fn() = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: Function pointers must be non-null
 
@@ -202,7 +202,7 @@ LL |         let _val: Wrap<fn()> = mem::zeroed();
    |                                ^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -217,7 +217,7 @@ LL |         let _val: Wrap<fn()> = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -232,7 +232,7 @@ LL |         let _val: WrapEnum<fn()> = mem::zeroed();
    |                                    ^^^^^^^^^^^^^
    |                                    |
    |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead
+   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this enum field)
   --> $DIR/uninitialized-zeroed.rs:19:28
@@ -247,7 +247,7 @@ LL |         let _val: WrapEnum<fn()> = mem::uninitialized();
    |                                    ^^^^^^^^^^^^^^^^^^^^
    |                                    |
    |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead
+   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Function pointers must be non-null (in this enum field)
   --> $DIR/uninitialized-zeroed.rs:19:28
@@ -262,7 +262,7 @@ LL |         let _val: Wrap<(RefPair, i32)> = mem::zeroed();
    |                                          ^^^^^^^^^^^^^
    |                                          |
    |                                          this code causes undefined behavior when executed
-   |                                          help: use `MaybeUninit<T>` instead
+   |                                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:16:16
@@ -277,7 +277,7 @@ LL |         let _val: Wrap<(RefPair, i32)> = mem::uninitialized();
    |                                          ^^^^^^^^^^^^^^^^^^^^
    |                                          |
    |                                          this code causes undefined behavior when executed
-   |                                          help: use `MaybeUninit<T>` instead
+   |                                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: References must be non-null (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:16:16
@@ -292,7 +292,7 @@ LL |         let _val: NonNull<i32> = mem::zeroed();
    |                                  ^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: std::ptr::NonNull<i32> must be non-null
 
@@ -303,29 +303,51 @@ LL |         let _val: NonNull<i32> = mem::uninitialized();
    |                                  ^^^^^^^^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: std::ptr::NonNull<i32> must be non-null
 
+error: the type `*const dyn std::marker::Send` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:70:37
+   |
+LL |         let _val: *const dyn Send = mem::zeroed();
+   |                                     ^^^^^^^^^^^^^
+   |                                     |
+   |                                     this code causes undefined behavior when executed
+   |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: The vtable of a wide raw pointer must be non-null
+
+error: the type `*const dyn std::marker::Send` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:71:37
+   |
+LL |         let _val: *const dyn Send = mem::uninitialized();
+   |                                     ^^^^^^^^^^^^^^^^^^^^
+   |                                     |
+   |                                     this code causes undefined behavior when executed
+   |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: The vtable of a wide raw pointer must be non-null
+
 error: the type `bool` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:72:26
+  --> $DIR/uninitialized-zeroed.rs:75:26
    |
 LL |         let _val: bool = mem::uninitialized();
    |                          ^^^^^^^^^^^^^^^^^^^^
    |                          |
    |                          this code causes undefined behavior when executed
-   |                          help: use `MaybeUninit<T>` instead
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: Booleans must be `true` or `false`
 
 error: the type `Wrap<char>` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:75:32
+  --> $DIR/uninitialized-zeroed.rs:78:32
    |
 LL |         let _val: Wrap<char> = mem::uninitialized();
    |                                ^^^^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
 note: Characters must be a valid unicode codepoint (in this struct field)
   --> $DIR/uninitialized-zeroed.rs:18:18
@@ -334,48 +356,81 @@ LL | struct Wrap<T> { wrapped: T }
    |                  ^^^^^^^^^^
 
 error: the type `NonBig` does not permit being left uninitialized
-  --> $DIR/uninitialized-zeroed.rs:78:28
+  --> $DIR/uninitialized-zeroed.rs:81:28
    |
 LL |         let _val: NonBig = mem::uninitialized();
    |                            ^^^^^^^^^^^^^^^^^^^^
    |                            |
    |                            this code causes undefined behavior when executed
-   |                            help: use `MaybeUninit<T>` instead
+   |                            help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: NonBig must be initialized inside its custom valid range
 
 error: the type `&'static i32` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:81:34
+  --> $DIR/uninitialized-zeroed.rs:84:34
    |
 LL |         let _val: &'static i32 = mem::transmute(0usize);
    |                                  ^^^^^^^^^^^^^^^^^^^^^^
    |                                  |
    |                                  this code causes undefined behavior when executed
-   |                                  help: use `MaybeUninit<T>` instead
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
 error: the type `&'static [i32]` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:82:36
+  --> $DIR/uninitialized-zeroed.rs:85:36
    |
 LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                    |
    |                                    this code causes undefined behavior when executed
-   |                                    help: use `MaybeUninit<T>` instead
+   |                                    help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: References must be non-null
 
 error: the type `std::num::NonZeroU32` does not permit zero-initialization
-  --> $DIR/uninitialized-zeroed.rs:83:32
+  --> $DIR/uninitialized-zeroed.rs:86:32
    |
 LL |         let _val: NonZeroU32 = mem::transmute(0);
    |                                ^^^^^^^^^^^^^^^^^
    |                                |
    |                                this code causes undefined behavior when executed
-   |                                help: use `MaybeUninit<T>` instead
+   |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: std::num::NonZeroU32 must be non-null
 
-error: aborting due to 30 previous errors
+error: the type `std::ptr::NonNull<i32>` does not permit zero-initialization
+  --> $DIR/uninitialized-zeroed.rs:89:34
+   |
+LL |         let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init();
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `std::ptr::NonNull<i32>` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:90:34
+   |
+LL |         let _val: NonNull<i32> = MaybeUninit::uninit().assume_init();
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                  |
+   |                                  this code causes undefined behavior when executed
+   |                                  help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: std::ptr::NonNull<i32> must be non-null
+
+error: the type `bool` does not permit being left uninitialized
+  --> $DIR/uninitialized-zeroed.rs:91:26
+   |
+LL |         let _val: bool = MaybeUninit::uninit().assume_init();
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                          |
+   |                          this code causes undefined behavior when executed
+   |                          help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+   |
+   = note: Booleans must be `true` or `false`
+
+error: aborting due to 35 previous errors
 
diff --git a/src/test/ui/lint/unused_import_warning_issue_45268.rs b/src/test/ui/lint/unused_import_warning_issue_45268.rs
index 68a5819c9c7..791bbb24196 100644
--- a/src/test/ui/lint/unused_import_warning_issue_45268.rs
+++ b/src/test/ui/lint/unused_import_warning_issue_45268.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![warn(unused_imports)] // Warning explanation here, it's OK
 
diff --git a/src/test/ui/mir/mir_cast_fn_ret.rs b/src/test/ui/mir/mir_cast_fn_ret.rs
index 69fd64c1c09..6b37ac37040 100644
--- a/src/test/ui/mir/mir_cast_fn_ret.rs
+++ b/src/test/ui/mir/mir_cast_fn_ret.rs
@@ -1,8 +1,10 @@
 // run-pass
+#[allow(improper_ctypes)]
 pub extern "C" fn tuple2() -> (u16, u8) {
     (1, 2)
 }
 
+#[allow(improper_ctypes)]
 pub extern "C" fn tuple3() -> (u8, u8, u8) {
     (1, 2, 3)
 }
diff --git a/src/test/ui/mir/mir_codegen_calls.rs b/src/test/ui/mir/mir_codegen_calls.rs
index fc0db03e3a9..c45629eddff 100644
--- a/src/test/ui/mir/mir_codegen_calls.rs
+++ b/src/test/ui/mir/mir_codegen_calls.rs
@@ -74,6 +74,7 @@ fn test8() -> isize {
     Two::two()
 }
 
+#[allow(improper_ctypes)]
 extern fn simple_extern(x: u32, y: (u32, u32)) -> u32 {
     x + y.0 * y.1
 }
diff --git a/src/test/ui/missing/missing-items/m2.stderr b/src/test/ui/missing/missing-items/m2.stderr
index d2dac4ca645..f8243528d72 100644
--- a/src/test/ui/missing/missing-items/m2.stderr
+++ b/src/test/ui/missing/missing-items/m2.stderr
@@ -4,9 +4,9 @@ error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `met
 LL | impl m1::X for X {
    | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method` in implementation
    |
-   = note: `CONSTANT` from trait: `const CONSTANT: u32;`
-   = note: `Type` from trait: `type Type;`
-   = note: `method` from trait: `fn(&Self, std::string::String) -> <Self as m1::X>::Type`
+   = help: implement the missing item: `const CONSTANT: u32 = 42;`
+   = help: implement the missing item: `type Type = Type;`
+   = help: implement the missing item: `fn method(&self, _: std::string::String) -> <Self as m1::X>::Type { unimplemented!() }`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
index 7679bf22e3c..a83ebc21f5f 100644
--- a/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
+++ b/src/test/ui/nll/closure-requirements/issue-58127-mutliple-requirements.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Test that we propagate region relations from closures precisely when there is
 // more than one non-local lower bound.
diff --git a/src/test/ui/nll/issue-16223.rs b/src/test/ui/nll/issue-16223.rs
index c1205ba96ad..0ae0ed3d87f 100644
--- a/src/test/ui/nll/issue-16223.rs
+++ b/src/test/ui/nll/issue-16223.rs
@@ -13,7 +13,7 @@
 //    |
 //    = note: move occurs because the value has type `A`, which does not implement the `Copy` trait
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(box_patterns)]
 
diff --git a/src/test/ui/nll/issue-21114-ebfull.rs b/src/test/ui/nll/issue-21114-ebfull.rs
index 5a5db1a17f3..fc4a6845a4f 100644
--- a/src/test/ui/nll/issue-21114-ebfull.rs
+++ b/src/test/ui/nll/issue-21114-ebfull.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::collections::HashMap;
 use std::sync::Mutex;
diff --git a/src/test/ui/nll/issue-21114-kixunil.rs b/src/test/ui/nll/issue-21114-kixunil.rs
index 32c97a651c5..666f89f356d 100644
--- a/src/test/ui/nll/issue-21114-kixunil.rs
+++ b/src/test/ui/nll/issue-21114-kixunil.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn from_stdin(min: u64) -> Vec<u64> {
     use std::io::BufRead;
diff --git a/src/test/ui/nll/issue-22323-temp-destruction.rs b/src/test/ui/nll/issue-22323-temp-destruction.rs
index 1add91b1bd0..3f2ece1cf6c 100644
--- a/src/test/ui/nll/issue-22323-temp-destruction.rs
+++ b/src/test/ui/nll/issue-22323-temp-destruction.rs
@@ -1,7 +1,7 @@
 // rust-lang/rust#22323: regression test demonstrating that NLL
 // precisely tracks temporary destruction order.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn main() {
     let _s = construct().borrow().consume_borrowed();
diff --git a/src/test/ui/nll/issue-30104.rs b/src/test/ui/nll/issue-30104.rs
index 3f4818a28c8..38850cd3fdf 100644
--- a/src/test/ui/nll/issue-30104.rs
+++ b/src/test/ui/nll/issue-30104.rs
@@ -1,6 +1,6 @@
 // Regression test for #30104
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
index bffff650158..a8a8e693026 100644
--- a/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
+++ b/src/test/ui/nll/issue-32382-index-assoc-type-with-lifetime.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#32382: Borrow checker used to complain about
 // `foobar_3` in the `impl` below, presumably due to some interaction
diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs
index 8bf9028690f..227888d17d3 100644
--- a/src/test/ui/nll/issue-43058.rs
+++ b/src/test/ui/nll/issue-43058.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::borrow::Cow;
 
diff --git a/src/test/ui/nll/issue-47022.rs b/src/test/ui/nll/issue-47022.rs
index ecd7071ecc7..521643c664d 100644
--- a/src/test/ui/nll/issue-47022.rs
+++ b/src/test/ui/nll/issue-47022.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct LoadedObject {
     bodies: Vec<Body>,
diff --git a/src/test/ui/nll/issue-50716-1.rs b/src/test/ui/nll/issue-50716-1.rs
index 1e602f27247..9c3e24de46e 100644
--- a/src/test/ui/nll/issue-50716-1.rs
+++ b/src/test/ui/nll/issue-50716-1.rs
@@ -3,7 +3,7 @@
 // bounds derived from `Sized` requirements” that checks that the fixed compiler
 // accepts this code fragment with both AST and MIR borrow checkers.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Qey<Q: ?Sized>(Q);
 
diff --git a/src/test/ui/nll/issue-51351.rs b/src/test/ui/nll/issue-51351.rs
index efffe80aae4..591d49584ee 100644
--- a/src/test/ui/nll/issue-51351.rs
+++ b/src/test/ui/nll/issue-51351.rs
@@ -6,7 +6,7 @@
 // of the closure, as they were not present in the closure's generic
 // declarations otherwise.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn creash<'a>() {
     let x: &'a () = &();
diff --git a/src/test/ui/nll/issue-52078.rs b/src/test/ui/nll/issue-52078.rs
index 935bf8cda5e..a2bcb91acf2 100644
--- a/src/test/ui/nll/issue-52078.rs
+++ b/src/test/ui/nll/issue-52078.rs
@@ -2,7 +2,7 @@
 // between `'a` and `'b` below due to inference variables introduced
 // during the normalization process.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Drain<'a, T: 'a> {
     _marker: ::std::marker::PhantomData<&'a T>,
diff --git a/src/test/ui/nll/issue-53119.rs b/src/test/ui/nll/issue-53119.rs
index f5400aaad8b..03c9c071c9b 100644
--- a/src/test/ui/nll/issue-53119.rs
+++ b/src/test/ui/nll/issue-53119.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::ops::Deref;
 
diff --git a/src/test/ui/nll/issue-53570.rs b/src/test/ui/nll/issue-53570.rs
index 25c1929b227..35860ba9c21 100644
--- a/src/test/ui/nll/issue-53570.rs
+++ b/src/test/ui/nll/issue-53570.rs
@@ -6,7 +6,7 @@
 // parameter `x` -- since `'b` cannot be expressed in the caller's
 // space, that got promoted th `'static`.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::cell::{RefCell, Ref};
 
diff --git a/src/test/ui/nll/issue-55344.rs b/src/test/ui/nll/issue-55344.rs
index a65635585db..20f18dc465d 100644
--- a/src/test/ui/nll/issue-55344.rs
+++ b/src/test/ui/nll/issue-55344.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![deny(unused_mut)]
 
diff --git a/src/test/ui/nll/issue-55651.rs b/src/test/ui/nll/issue-55651.rs
index 73fce288f8b..46255bf74a1 100644
--- a/src/test/ui/nll/issue-55651.rs
+++ b/src/test/ui/nll/issue-55651.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(untagged_unions)]
 
diff --git a/src/test/ui/nll/issue-57280-1.rs b/src/test/ui/nll/issue-57280-1.rs
index f9cea42e7c4..b8979624e50 100644
--- a/src/test/ui/nll/issue-57280-1.rs
+++ b/src/test/ui/nll/issue-57280-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo<'a> {
     const C: &'a u32;
diff --git a/src/test/ui/nll/issue-57280.rs b/src/test/ui/nll/issue-57280.rs
index 65ca23cc88f..b9d336ec395 100644
--- a/src/test/ui/nll/issue-57280.rs
+++ b/src/test/ui/nll/issue-57280.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo {
     const BLAH: &'static str;
diff --git a/src/test/ui/nll/issue-61311-normalize.rs b/src/test/ui/nll/issue-61311-normalize.rs
index 9237c27f57e..77d67b07a40 100644
--- a/src/test/ui/nll/issue-61311-normalize.rs
+++ b/src/test/ui/nll/issue-61311-normalize.rs
@@ -1,7 +1,7 @@
 // Regression test for #61311
 // We would ICE after failing to normalize `Self::Proj` in the `impl` below.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub struct Unit;
 trait Obj {}
diff --git a/src/test/ui/nll/issue-61320-normalize.rs b/src/test/ui/nll/issue-61320-normalize.rs
index 59bceed08f9..095bef03f7c 100644
--- a/src/test/ui/nll/issue-61320-normalize.rs
+++ b/src/test/ui/nll/issue-61320-normalize.rs
@@ -1,7 +1,7 @@
 // Regression test for #61320
 // This is the same issue as #61311, just a larger test case.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 pub struct AndThen<A, B, F>
 where
diff --git a/src/test/ui/nll/relate_tys/issue-48071.rs b/src/test/ui/nll/relate_tys/issue-48071.rs
index 36cd57a1b2d..73361a0d319 100644
--- a/src/test/ui/nll/relate_tys/issue-48071.rs
+++ b/src/test/ui/nll/relate_tys/issue-48071.rs
@@ -4,7 +4,7 @@
 // placeholder region, but in NLL land it would fail because we had
 // rewritten `'static` to a region variable.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait Foo {
     fn foo(&self) { }
diff --git a/src/test/ui/nll/ty-outlives/issue-53789-1.rs b/src/test/ui/nll/ty-outlives/issue-53789-1.rs
index 2293d7d4bbc..a5201d4bbe8 100644
--- a/src/test/ui/nll/ty-outlives/issue-53789-1.rs
+++ b/src/test/ui/nll/ty-outlives/issue-53789-1.rs
@@ -1,6 +1,6 @@
 // Regression test for #53789.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::collections::BTreeMap;
 
diff --git a/src/test/ui/nll/ty-outlives/issue-53789-2.rs b/src/test/ui/nll/ty-outlives/issue-53789-2.rs
index 313b615fe80..7dcdd58bb24 100644
--- a/src/test/ui/nll/ty-outlives/issue-53789-2.rs
+++ b/src/test/ui/nll/ty-outlives/issue-53789-2.rs
@@ -1,6 +1,6 @@
 // Regression test for #53789.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 use std::collections::BTreeMap;
 use std::ops::Range;
diff --git a/src/test/ui/nll/ty-outlives/issue-55756.rs b/src/test/ui/nll/ty-outlives/issue-55756.rs
index 147ea203489..e1a3bc3c4eb 100644
--- a/src/test/ui/nll/ty-outlives/issue-55756.rs
+++ b/src/test/ui/nll/ty-outlives/issue-55756.rs
@@ -16,7 +16,7 @@
 // Fixed by tweaking the solver to recognize that the constraint from
 // the environment duplicates one from the trait.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![crate_type="lib"]
 
diff --git a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
index 66b3110d2af..ff5b2244e48 100644
--- a/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
+++ b/src/test/ui/nll/user-annotations/issue-54570-bootstrapping.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // This test is reduced from a scenario pnkfelix encountered while
 // bootstrapping the compiler.
diff --git a/src/test/ui/no-send-res-ports.rs b/src/test/ui/no-send-res-ports.rs
index 01fc29713a4..85d812dd619 100644
--- a/src/test/ui/no-send-res-ports.rs
+++ b/src/test/ui/no-send-res-ports.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::thread;
 use std::rc::Rc;
 
diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr
index dc186f7c85e..f23a3bf832a 100644
--- a/src/test/ui/no-send-res-ports.stderr
+++ b/src/test/ui/no-send-res-ports.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
-  --> $DIR/no-send-res-ports.rs:27:5
+  --> $DIR/no-send-res-ports.rs:26:5
    |
 LL |     thread::spawn(move|| {
    |     ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -9,10 +9,10 @@ LL |     thread::spawn(move|| {
 LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |                          ---- required by this bound in `std::thread::spawn`
    |
-   = help: within `[closure@$DIR/no-send-res-ports.rs:27:19: 31:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
+   = help: within `[closure@$DIR/no-send-res-ports.rs:26:19: 30:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `Port<()>`
    = note: required because it appears within the type `main::Foo`
-   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:27:19: 31:6 x:main::Foo]`
+   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:26:19: 30:6 x:main::Foo]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no-warn-on-field-replace-issue-34101.rs b/src/test/ui/no-warn-on-field-replace-issue-34101.rs
index eb701b9184e..15df6d25c5d 100644
--- a/src/test/ui/no-warn-on-field-replace-issue-34101.rs
+++ b/src/test/ui/no-warn-on-field-replace-issue-34101.rs
@@ -18,7 +18,7 @@
 
 
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct Foo(String);
 
diff --git a/src/test/ui/on-unimplemented/bad-annotation.rs b/src/test/ui/on-unimplemented/bad-annotation.rs
index 5357c3bff9a..f05436b8c04 100644
--- a/src/test/ui/on-unimplemented/bad-annotation.rs
+++ b/src/test/ui/on-unimplemented/bad-annotation.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 #![allow(unused)]
 
diff --git a/src/test/ui/on-unimplemented/expected-comma-found-token.rs b/src/test/ui/on-unimplemented/expected-comma-found-token.rs
index d8717f360e9..77c0ea17269 100644
--- a/src/test/ui/on-unimplemented/expected-comma-found-token.rs
+++ b/src/test/ui/on-unimplemented/expected-comma-found-token.rs
@@ -2,7 +2,7 @@
 // access to the variable, whether that mutable access be used
 // for direct assignment or for taking mutable ref. Issue #6801.
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 #[rustc_on_unimplemented(
     message="the message"
diff --git a/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
new file mode 100644
index 00000000000..3cc50e3499a
--- /dev/null
+++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
@@ -0,0 +1,8 @@
+// Test that `#[rustc_on_unimplemented]` is gated by `rustc_attrs` feature gate.
+
+#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
+//~^ ERROR this is an internal attribute that will never be stable
+trait Foo<Bar>
+{}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr
index 6c230f8cada..ec1eaff52bd 100644
--- a/src/test/ui/feature-gates/feature-gate-on-unimplemented.stderr
+++ b/src/test/ui/on-unimplemented/feature-gate-on-unimplemented.stderr
@@ -1,11 +1,11 @@
-error[E0658]: the `#[rustc_on_unimplemented]` attribute is an experimental feature
-  --> $DIR/feature-gate-on-unimplemented.rs:4:1
+error[E0658]: this is an internal attribute that will never be stable
+  --> $DIR/feature-gate-on-unimplemented.rs:3:1
    |
 LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29628
-   = help: add `#![feature(on_unimplemented)]` to the crate attributes to enable
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.rs b/src/test/ui/on-unimplemented/multiple-impls.rs
index 0aee98b2090..b74957ebcd4 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.rs
+++ b/src/test/ui/on-unimplemented/multiple-impls.rs
@@ -1,6 +1,6 @@
 // Test if the on_unimplemented message override works
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 
 struct Foo<T>(T);
diff --git a/src/test/ui/on-unimplemented/on-impl.rs b/src/test/ui/on-unimplemented/on-impl.rs
index 9e4c2f6edd7..ab3e67d01fe 100644
--- a/src/test/ui/on-unimplemented/on-impl.rs
+++ b/src/test/ui/on-unimplemented/on-impl.rs
@@ -1,6 +1,6 @@
 // Test if the on_unimplemented message override works
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 
 #[rustc_on_unimplemented = "invalid"]
diff --git a/src/test/ui/on-unimplemented/on-trait.rs b/src/test/ui/on-unimplemented/on-trait.rs
index 109cb5ba969..556813cd479 100644
--- a/src/test/ui/on-unimplemented/on-trait.rs
+++ b/src/test/ui/on-unimplemented/on-trait.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
-#![feature(on_unimplemented)]
+#![feature(rustc_attrs)]
 
 pub mod Bar {
   #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]
diff --git a/src/test/ui/parser/bad-lit-suffixes.rs b/src/test/ui/parser/bad-lit-suffixes.rs
index 9f301db0995..7db83674efc 100644
--- a/src/test/ui/parser/bad-lit-suffixes.rs
+++ b/src/test/ui/parser/bad-lit-suffixes.rs
@@ -1,9 +1,9 @@
 extern
-    "C"suffix //~ ERROR suffixes on an ABI spec are invalid
+    "C"suffix //~ ERROR suffixes on a string literal are invalid
     fn foo() {}
 
 extern
-    "C"suffix //~ ERROR suffixes on an ABI spec are invalid
+    "C"suffix //~ ERROR suffixes on a string literal are invalid
 {}
 
 fn main() {
diff --git a/src/test/ui/parser/bad-lit-suffixes.stderr b/src/test/ui/parser/bad-lit-suffixes.stderr
index 208fcf43d91..6b0049298ff 100644
--- a/src/test/ui/parser/bad-lit-suffixes.stderr
+++ b/src/test/ui/parser/bad-lit-suffixes.stderr
@@ -1,10 +1,10 @@
-error: suffixes on an ABI spec are invalid
+error: suffixes on a string literal are invalid
   --> $DIR/bad-lit-suffixes.rs:2:5
    |
 LL |     "C"suffix
    |     ^^^^^^^^^ invalid suffix `suffix`
 
-error: suffixes on an ABI spec are invalid
+error: suffixes on a string literal are invalid
   --> $DIR/bad-lit-suffixes.rs:6:5
    |
 LL |     "C"suffix
diff --git a/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
new file mode 100644
index 00000000000..cb23f2c808c
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-from-mac-literal-frag.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+// In this test we check that the parser accepts an ABI string when it
+// comes from a macro `literal` fragment as opposed to a hardcoded string.
+
+fn main() {}
+
+macro_rules! abi_from_lit_frag {
+    ($abi:literal) => {
+        extern $abi {
+            fn _import();
+        }
+
+        extern $abi fn _export() {}
+
+        type _PTR = extern $abi fn();
+    }
+}
+
+mod rust {
+    abi_from_lit_frag!("Rust");
+}
+
+mod c {
+    abi_from_lit_frag!("C");
+}
diff --git a/src/test/ui/parser/extern-abi-raw-strings.rs b/src/test/ui/parser/extern-abi-raw-strings.rs
new file mode 100644
index 00000000000..fad855a21f6
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-raw-strings.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// Check that the string literal in `extern lit` will accept raw strings.
+
+fn main() {}
+
+extern r#"C"# fn foo() {}
+
+extern r#"C"# {
+    fn bar();
+}
+
+type T = extern r#"C"# fn();
diff --git a/src/test/ui/parser/extern-abi-string-escaping.rs b/src/test/ui/parser/extern-abi-string-escaping.rs
new file mode 100644
index 00000000000..87bd31aabb6
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-string-escaping.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+// Check that the string literal in `extern lit` will escapes.
+
+fn main() {}
+
+extern "\x43" fn foo() {}
+
+extern "\x43" {
+    fn bar();
+}
+
+type T = extern "\x43" fn();
diff --git a/src/test/ui/parser/extern-abi-syntactic.rs b/src/test/ui/parser/extern-abi-syntactic.rs
new file mode 100644
index 00000000000..7d2bbfe8a01
--- /dev/null
+++ b/src/test/ui/parser/extern-abi-syntactic.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// Check that from the grammar's point of view,
+// the specific set of ABIs is not part of it.
+
+fn main() {}
+
+#[cfg(FALSE)]
+extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn foo() {}
+
+#[cfg(FALSE)]
+extern "some_abi_that_we_are_sure_does_not_exist_semantically" {
+    fn foo();
+}
+
+#[cfg(FALSE)]
+type T = extern "some_abi_that_we_are_sure_does_not_exist_semantically" fn();
diff --git a/src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs b/src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs
new file mode 100644
index 00000000000..9d68a7bffde
--- /dev/null
+++ b/src/test/ui/parser/issue-65846-rollback-gating-failing-matcher.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+// Test that failing macro matchers will not cause pre-expansion errors
+// even though they use a feature that is pre-expansion gated.
+
+macro_rules! m {
+    ($e:expr) => { 0 }; // This fails on the input below due to `, foo`.
+    ($e:expr,) => { 1 }; // This also fails to match due to `foo`.
+    (box $e:expr, foo) => { 2 }; // Successful matcher, we should get `2`.
+}
+
+fn main() {
+    assert_eq!(2, m!(box 42, foo));
+}
diff --git a/src/test/ui/path-lookahead.rs b/src/test/ui/path-lookahead.rs
index fd7509a623e..86bcb08de40 100644
--- a/src/test/ui/path-lookahead.rs
+++ b/src/test/ui/path-lookahead.rs
@@ -1,14 +1,14 @@
 // run-pass
-
-#![warn(unused)]
+#![allow(dead_code)]
+#![warn(unused_parens)]
 
 // Parser test for #37765
 
-fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`
+fn with_parens<T: ToString>(arg: T) -> String {
   return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
 }
 
-fn no_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `no_parens`
+fn no_parens<T: ToString>(arg: T) -> String {
   return <T as ToString>::to_string(&arg);
 }
 
diff --git a/src/test/ui/path-lookahead.stderr b/src/test/ui/path-lookahead.stderr
index 197848e428a..caf9e8303ea 100644
--- a/src/test/ui/path-lookahead.stderr
+++ b/src/test/ui/path-lookahead.stderr
@@ -7,26 +7,6 @@ LL |   return (<T as ToString>::to_string(&arg));
 note: lint level defined here
   --> $DIR/path-lookahead.rs:3:9
    |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(unused_parens)]` implied by `#[warn(unused)]`
-
-warning: function is never used: `with_parens`
-  --> $DIR/path-lookahead.rs:7:1
-   |
-LL | fn with_parens<T: ToString>(arg: T) -> String {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/path-lookahead.rs:3:9
-   |
-LL | #![warn(unused)]
-   |         ^^^^^^
-   = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
-
-warning: function is never used: `no_parens`
-  --> $DIR/path-lookahead.rs:11:1
-   |
-LL | fn no_parens<T: ToString>(arg: T) -> String {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![warn(unused_parens)]
+   |         ^^^^^^^^^^^^^
 
diff --git a/src/test/ui/pathless-extern-ok.rs b/src/test/ui/pathless-extern-ok.rs
new file mode 100644
index 00000000000..0ffa5eb8940
--- /dev/null
+++ b/src/test/ui/pathless-extern-ok.rs
@@ -0,0 +1,9 @@
+// edition:2018
+// compile-flags:--extern alloc
+// build-pass
+
+// Test that `--extern alloc` will load from the sysroot without error.
+
+fn main() {
+    let _: Vec<i32> = alloc::vec::Vec::new();
+}
diff --git a/src/test/ui/privacy/issue-57264-1.rs b/src/test/ui/privacy/issue-57264-1.rs
index 5ef6a61fea1..59ebc4f54ee 100644
--- a/src/test/ui/privacy/issue-57264-1.rs
+++ b/src/test/ui/privacy/issue-57264-1.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // aux-build:issue-57264-1.rs
 
 extern crate issue_57264_1;
diff --git a/src/test/ui/privacy/issue-57264-2.rs b/src/test/ui/privacy/issue-57264-2.rs
index 4d5c9cfa1d5..36ce5fd3b3e 100644
--- a/src/test/ui/privacy/issue-57264-2.rs
+++ b/src/test/ui/privacy/issue-57264-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // aux-build:issue-57264-2.rs
 
 extern crate issue_57264_2;
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs
index 2495e72751b..fb13bb064c7 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-57089.rs
+++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 // aux-build:test-macros.rs
 
diff --git a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
index ee9e7a364b8..bdd1ae91f7d 100644
--- a/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
+++ b/src/test/ui/regions/issue-56537-closure-uses-region-from-container.rs
@@ -8,7 +8,7 @@
 // follow the same lifetime-elision rules used elsehwere. See
 // rust-lang/rust#56537
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 fn willy_no_annot<'w>(p: &'w str, q: &str) -> &'w str {
     let free_dumb = |_x| { p }; // no type annotation at all
diff --git a/src/test/ui/resolve/issue-57523.rs b/src/test/ui/resolve/issue-57523.rs
index 5dc467d97e2..976238cc3bd 100644
--- a/src/test/ui/resolve/issue-57523.rs
+++ b/src/test/ui/resolve/issue-57523.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 struct S(u8);
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
index c27cea302fc..a028247ec5c 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
@@ -1,6 +1,5 @@
 // compile-flags: --test
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 
 use std::num::ParseFloatError;
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 6aa95c308f2..9cefef58bf5 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `main` has invalid return type `std::result::Result<f32, std::num::ParseFloatError>`
-  --> $DIR/termination-trait-test-wrong-type.rs:8:1
+  --> $DIR/termination-trait-test-wrong-type.rs:7:1
    |
 LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
 LL | |     "0".parse()
diff --git a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
index b662685ae24..c712f15e324 100644
--- a/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
+++ b/src/test/ui/rfc-2093-infer-outlives/issue-54467.rs
@@ -6,7 +6,7 @@
 // strange errors. This test ensures that we do not give compilation
 // errors.
 //
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 trait MyIterator<'a>: Iterator where Self::Item: 'a { }
 
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
index 446b2d05717..9ea7e496d2b 100644
--- a/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
+++ b/src/test/ui/rust-2018/uniform-paths/issue-56596-2.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 // compile-flags: --extern issue_56596_2
 // aux-build:issue-56596-2.rs
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr
index 81409aac289..f23f421edc7 100644
--- a/src/test/ui/span/impl-wrong-item-for-trait.stderr
+++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr
@@ -64,7 +64,7 @@ error[E0046]: not all trait items implemented, missing: `fmt`
 LL | impl Debug for FooTypeForMethod {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
    |
-   = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+   = help: implement the missing item: `fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { unimplemented!() }`
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr
index 865fae917c5..f88ce6c88db 100644
--- a/src/test/ui/span/issue-23729.stderr
+++ b/src/test/ui/span/issue-23729.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item`
 LL |         impl Iterator for Recurrence {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
    |
-   = note: `Item` from trait: `type Item;`
+   = help: implement the missing item: `type Item = Type;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr
index a8e3e9b6b9a..46a820f1b76 100644
--- a/src/test/ui/span/issue-23827.stderr
+++ b/src/test/ui/span/issue-23827.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
 LL | impl<C: Component> FnOnce<(C,)> for Prototype {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
    |
-   = note: `Output` from trait: `type Output;`
+   = help: implement the missing item: `type Output = Type;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr
index 4827e9ddd50..a1f9b255020 100644
--- a/src/test/ui/span/issue-24356.stderr
+++ b/src/test/ui/span/issue-24356.stderr
@@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target`
 LL |         impl Deref for Thing {
    |         ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
    |
-   = note: `Target` from trait: `type Target;`
+   = help: implement the missing item: `type Target = Type;`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-24690.rs b/src/test/ui/span/issue-24690.rs
index f51ea55d4e6..2b7349c5503 100644
--- a/src/test/ui/span/issue-24690.rs
+++ b/src/test/ui/span/issue-24690.rs
@@ -1,7 +1,7 @@
 //! A test to ensure that helpful `note` messages aren't emitted more often
 //! than necessary.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Although there are three warnings, we should only get two "lint level defined
 // here" notes pointing at the `warnings` span, one for each error type.
diff --git a/src/test/ui/span/unused-warning-point-at-signature.rs b/src/test/ui/span/unused-warning-point-at-identifier.rs
index 3af272a012e..d4d5bc1cbc8 100644
--- a/src/test/ui/span/unused-warning-point-at-signature.rs
+++ b/src/test/ui/span/unused-warning-point-at-identifier.rs
@@ -20,8 +20,8 @@ fn func() -> usize { //~ WARN function is never used
     3
 }
 
-fn //~ WARN function is never used
-func_complete_span()
+fn
+func_complete_span() //~ WARN function is never used
 -> usize
 {
     3
diff --git a/src/test/ui/span/unused-warning-point-at-signature.stderr b/src/test/ui/span/unused-warning-point-at-identifier.stderr
index 83e2ec1987b..a4715d4adeb 100644
--- a/src/test/ui/span/unused-warning-point-at-signature.stderr
+++ b/src/test/ui/span/unused-warning-point-at-identifier.stderr
@@ -1,36 +1,31 @@
 warning: enum is never used: `Enum`
-  --> $DIR/unused-warning-point-at-signature.rs:5:1
+  --> $DIR/unused-warning-point-at-identifier.rs:5:6
    |
 LL | enum Enum {
-   | ^^^^^^^^^
+   |      ^^^^
    |
 note: lint level defined here
-  --> $DIR/unused-warning-point-at-signature.rs:3:9
+  --> $DIR/unused-warning-point-at-identifier.rs:3:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
 
 warning: struct is never constructed: `Struct`
-  --> $DIR/unused-warning-point-at-signature.rs:12:1
+  --> $DIR/unused-warning-point-at-identifier.rs:12:8
    |
 LL | struct Struct {
-   | ^^^^^^^^^^^^^
+   |        ^^^^^^
 
 warning: function is never used: `func`
-  --> $DIR/unused-warning-point-at-signature.rs:19:1
+  --> $DIR/unused-warning-point-at-identifier.rs:19:4
    |
 LL | fn func() -> usize {
-   | ^^^^^^^^^^^^^^^^^^
+   |    ^^^^
 
 warning: function is never used: `func_complete_span`
-  --> $DIR/unused-warning-point-at-signature.rs:23:1
+  --> $DIR/unused-warning-point-at-identifier.rs:24:1
    |
-LL | / fn
-LL | | func_complete_span()
-LL | | -> usize
-LL | | {
-LL | |     3
-LL | | }
-   | |_^
+LL | func_complete_span()
+   | ^^^^^^^^^^^^^^^^^^
 
diff --git a/src/test/ui/suggestions/issue-57672.rs b/src/test/ui/suggestions/issue-57672.rs
index 0881a631f3a..ee999d83ec2 100644
--- a/src/test/ui/suggestions/issue-57672.rs
+++ b/src/test/ui/suggestions/issue-57672.rs
@@ -1,6 +1,6 @@
 // aux-build:foo.rs
 // compile-flags:--extern foo
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 
 #![deny(unused_extern_crates)]
diff --git a/src/test/ui/suggestions/missing-trait-item.fixed b/src/test/ui/suggestions/missing-trait-item.fixed
new file mode 100644
index 00000000000..42f579a665e
--- /dev/null
+++ b/src/test/ui/suggestions/missing-trait-item.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+
+trait T {
+    unsafe fn foo(a: &usize, b: &usize) -> usize;
+    fn bar(&self, a: &usize, b: &usize) -> usize;
+}
+
+mod foo {
+    use super::T;
+    impl T for () {    fn bar(&self, _: &usize, _: &usize) -> usize { unimplemented!() }
+        unsafe fn foo(_: &usize, _: &usize) -> usize { unimplemented!() }
+    } //~ ERROR not all trait items
+
+    impl T for usize { //~ ERROR not all trait items
+        fn bar(&self, _: &usize, _: &usize) -> usize { unimplemented!() }
+        unsafe fn foo(_: &usize, _: &usize) -> usize { unimplemented!() }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-trait-item.rs b/src/test/ui/suggestions/missing-trait-item.rs
new file mode 100644
index 00000000000..b4fca25ba2f
--- /dev/null
+++ b/src/test/ui/suggestions/missing-trait-item.rs
@@ -0,0 +1,16 @@
+// run-rustfix
+
+trait T {
+    unsafe fn foo(a: &usize, b: &usize) -> usize;
+    fn bar(&self, a: &usize, b: &usize) -> usize;
+}
+
+mod foo {
+    use super::T;
+    impl T for () {} //~ ERROR not all trait items
+
+    impl T for usize { //~ ERROR not all trait items
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-trait-item.stderr b/src/test/ui/suggestions/missing-trait-item.stderr
new file mode 100644
index 00000000000..4a9d7b472c9
--- /dev/null
+++ b/src/test/ui/suggestions/missing-trait-item.stderr
@@ -0,0 +1,25 @@
+error[E0046]: not all trait items implemented, missing: `foo`, `bar`
+  --> $DIR/missing-trait-item.rs:10:5
+   |
+LL |     unsafe fn foo(a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `foo` from trait
+LL |     fn bar(&self, a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `bar` from trait
+...
+LL |     impl T for () {}
+   |     ^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
+
+error[E0046]: not all trait items implemented, missing: `foo`, `bar`
+  --> $DIR/missing-trait-item.rs:12:5
+   |
+LL |     unsafe fn foo(a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `foo` from trait
+LL |     fn bar(&self, a: &usize, b: &usize) -> usize;
+   |     --------------------------------------------- `bar` from trait
+...
+LL |     impl T for usize {
+   |     ^^^^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/test-attrs/test-warns-dead-code.stderr b/src/test/ui/test-attrs/test-warns-dead-code.stderr
index 62e99225dd9..cb118cdb410 100644
--- a/src/test/ui/test-attrs/test-warns-dead-code.stderr
+++ b/src/test/ui/test-attrs/test-warns-dead-code.stderr
@@ -1,8 +1,8 @@
 error: function is never used: `dead`
-  --> $DIR/test-warns-dead-code.rs:5:1
+  --> $DIR/test-warns-dead-code.rs:5:4
    |
 LL | fn dead() {}
-   | ^^^^^^^^^
+   |    ^^^^
    |
 note: lint level defined here
   --> $DIR/test-warns-dead-code.rs:3:9
diff --git a/src/test/ui/thread-local-not-in-prelude.rs b/src/test/ui/thread-local-not-in-prelude.rs
index 03974982625..e5ed09c600b 100644
--- a/src/test/ui/thread-local-not-in-prelude.rs
+++ b/src/test/ui/thread-local-not-in-prelude.rs
@@ -1,5 +1,4 @@
 // run-pass
-
 #![no_std]
 
 extern crate std;
diff --git a/src/test/ui/traits/trait-suggest-where-clause.rs b/src/test/ui/traits/trait-suggest-where-clause.rs
index 5ed14a6a866..5d3464d20f3 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.rs
+++ b/src/test/ui/traits/trait-suggest-where-clause.rs
@@ -1,5 +1,4 @@
-// ignore-x86
-// ^ due to stderr output differences
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 use std::mem;
 
 struct Misc<T:?Sized>(T);
diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr
index f1004ea9dc6..2bb7defdac7 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.stderr
+++ b/src/test/ui/traits/trait-suggest-where-clause.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:9:20
+  --> $DIR/trait-suggest-where-clause.rs:8:20
    |
 LL | fn check<T: Iterator, U: ?Sized>() {
    |                       -- help: consider further restricting this bound: `U: std::marker::Sized +`
@@ -16,7 +16,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:12:5
+  --> $DIR/trait-suggest-where-clause.rs:11:5
    |
 LL | fn check<T: Iterator, U: ?Sized>() {
    |                       -- help: consider further restricting this bound: `U: std::marker::Sized +`
@@ -34,7 +34,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: required because it appears within the type `Misc<U>`
 
 error[E0277]: the trait bound `u64: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:17:5
+  --> $DIR/trait-suggest-where-clause.rs:16:5
    |
 LL |     <u64 as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `u64`
@@ -42,7 +42,7 @@ LL |     <u64 as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `u64: std::convert::From<<T as std::iter::Iterator>::Item>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:20:5
+  --> $DIR/trait-suggest-where-clause.rs:19:5
    |
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<<T as std::iter::Iterator>::Item>` is not implemented for `u64`
@@ -50,7 +50,7 @@ LL |     <u64 as From<<T as Iterator>::Item>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `Misc<_>: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:25:5
+  --> $DIR/trait-suggest-where-clause.rs:24:5
    |
 LL |     <Misc<_> as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `Misc<_>`
@@ -58,7 +58,7 @@ LL |     <Misc<_> as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:30:20
+  --> $DIR/trait-suggest-where-clause.rs:29:20
    |
 LL |     mem::size_of::<[T]>();
    |                    ^^^ doesn't have a size known at compile-time
@@ -72,7 +72,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `[&U]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:33:5
+  --> $DIR/trait-suggest-where-clause.rs:32:5
    |
 LL |     mem::size_of::<[&U]>();
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/traits/traits-issue-23003-overflow.rs b/src/test/ui/traits/traits-issue-23003-overflow.rs
index 5538e0303ed..c5f471f23c2 100644
--- a/src/test/ui/traits/traits-issue-23003-overflow.rs
+++ b/src/test/ui/traits/traits-issue-23003-overflow.rs
@@ -2,7 +2,7 @@
 // types are required. This test now just compiles fine, since the
 // relevant rules that triggered the overflow were removed.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 #![allow(dead_code)]
 
 use std::marker::PhantomData;
diff --git a/src/test/ui/type-alias-enum-variants/issue-57866.rs b/src/test/ui/type-alias-enum-variants/issue-57866.rs
index 058b58e174c..5e105b20a89 100644
--- a/src/test/ui/type-alias-enum-variants/issue-57866.rs
+++ b/src/test/ui/type-alias-enum-variants/issue-57866.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 enum Outer<T> {
     A(T)
diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
index bff04daed0d..9c9eaab8da3 100644
--- a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
+++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs
@@ -1,7 +1,7 @@
 // In this regression test we check that a path pattern referring to a unit variant
 // through a type alias is successful in inferring the generic argument.
 
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 enum Opt<T> {
     N,
diff --git a/src/test/ui/type_length_limit.rs b/src/test/ui/type_length_limit.rs
index cd15f81a615..926f12911c5 100644
--- a/src/test/ui/type_length_limit.rs
+++ b/src/test/ui/type_length_limit.rs
@@ -1,5 +1,4 @@
-// ignore-musl
-// ignore-x86
+// ignore-x86 FIXME: missing sysroot spans (#53081)
 // error-pattern: reached the type-length limit while instantiating
 
 // Test that the type length limit can be changed.
diff --git a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
index 710b7c9bbee..23ea0ad61a7 100644
--- a/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
+++ b/src/test/ui/typeck/issue-55810-must-typeck-match-pats-before-guards.rs
@@ -1,4 +1,4 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // rust-lang/rust#55810: types for a binding in a match arm can be
 // inferred from arms that come later in the match.
diff --git a/src/test/ui/dead-code-ret.rs b/src/test/ui/unreachable-code-ret.rs
index fad35794fae..fad35794fae 100644
--- a/src/test/ui/dead-code-ret.rs
+++ b/src/test/ui/unreachable-code-ret.rs
diff --git a/src/test/ui/dead-code-ret.stderr b/src/test/ui/unreachable-code-ret.stderr
index 83841131599..c22342ce721 100644
--- a/src/test/ui/dead-code-ret.stderr
+++ b/src/test/ui/unreachable-code-ret.stderr
@@ -1,5 +1,5 @@
 error: unreachable statement
-  --> $DIR/dead-code-ret.rs:7:5
+  --> $DIR/unreachable-code-ret.rs:7:5
    |
 LL |     return;
    |     ------ any code following this expression is unreachable
@@ -7,7 +7,7 @@ LL |     println!("Paul is dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
-  --> $DIR/dead-code-ret.rs:3:9
+  --> $DIR/unreachable-code-ret.rs:3:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 93029099686..5abe481368d 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -160,6 +160,8 @@ pub fn check(path: &Path, bad: &mut bool) {
         let can_contain = contents.contains("// ignore-tidy-") ||
             contents.contains("# ignore-tidy-");
         let mut skip_cr = contains_ignore_directive(can_contain, &contents, "cr");
+        let mut skip_undocumented_unsafe =
+            contains_ignore_directive(can_contain, &contents, "undocumented-unsafe");
         let mut skip_tab = contains_ignore_directive(can_contain, &contents, "tab");
         let mut skip_line_length = contains_ignore_directive(can_contain, &contents, "linelength");
         let mut skip_file_length = contains_ignore_directive(can_contain, &contents, "filelength");
@@ -171,6 +173,7 @@ pub fn check(path: &Path, bad: &mut bool) {
         let mut leading_new_lines = false;
         let mut trailing_new_lines = 0;
         let mut lines = 0;
+        let mut last_safety_comment = false;
         for (i, line) in contents.split('\n').enumerate() {
             let mut err = |msg: &str| {
                 tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
@@ -200,6 +203,20 @@ pub fn check(path: &Path, bad: &mut bool) {
                     err("XXX is deprecated; use FIXME")
                 }
             }
+            let is_test = || file.components().any(|c| c.as_os_str() == "tests");
+            // for now we just check libcore
+            if line.contains("unsafe {") && !line.trim().starts_with("//") && !last_safety_comment {
+                if file.components().any(|c| c.as_os_str() == "libcore") && !is_test() {
+                    suppressible_tidy_err!(err, skip_undocumented_unsafe, "undocumented unsafe");
+                }
+            }
+            if line.contains("// SAFETY: ") || line.contains("// Safety: ") {
+                last_safety_comment = true;
+            } else if line.trim().starts_with("//") || line.trim().is_empty() {
+                // keep previous value
+            } else {
+                last_safety_comment = false;
+            }
             if (line.starts_with("// Copyright") ||
                 line.starts_with("# Copyright") ||
                 line.starts_with("Copyright"))