about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml8
-rw-r--r--Cargo.lock13
-rw-r--r--compiler/rustc_ast/src/ast.rs16
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs29
-rw-r--r--compiler/rustc_ast/src/token.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs19
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs65
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs13
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs22
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs13
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs1
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs32
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs27
-rw-r--r--compiler/rustc_codegen_llvm/src/base.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs21
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs24
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/asm.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/mod.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs22
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs7
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_check.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs12
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs32
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/active.rs2
-rw-r--r--compiler/rustc_feature/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs24
-rw-r--r--compiler/rustc_hir/src/intravisit.rs21
-rw-r--r--compiler/rustc_hir/src/lang_items.rs2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs11
-rw-r--r--compiler/rustc_infer/src/infer/at.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--compiler/rustc_infer/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs12
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs5
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp6
-rw-r--r--compiler/rustc_macros/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/creader.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs24
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs4
-rw-r--r--compiler/rustc_middle/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/middle/region.rs9
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs3
-rw-r--r--compiler/rustc_middle/src/thir.rs3
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs4
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs10
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs131
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs2
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs4
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs22
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs66
-rw-r--r--compiler/rustc_passes/src/dead.rs9
-rw-r--r--compiler/rustc_passes/src/intrinsicck.rs42
-rw-r--r--compiler/rustc_passes/src/liveness.rs10
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs4
-rw-r--r--compiler/rustc_passes/src/stability.rs4
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs6
-rw-r--r--compiler/rustc_resolve/src/ident.rs38
-rw-r--r--compiler/rustc_resolve/src/imports.rs58
-rw-r--r--compiler/rustc_resolve/src/late.rs27
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs4
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/session.rs7
-rw-r--r--compiler/rustc_span/src/edition.rs30
-rw-r--r--compiler/rustc_span/src/lib.rs5
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_target/src/abi/call/sparc64.rs6
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs4
-rw-r--r--compiler/rustc_typeck/src/check/_match.rs10
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs51
-rw-r--r--compiler/rustc_typeck/src/check/cast.rs146
-rw-r--r--compiler/rustc_typeck/src/check/check.rs310
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs85
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs28
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs280
-rw-r--r--compiler/rustc_typeck/src/check/dropck.rs9
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs144
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs8
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs343
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/checks.rs927
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs2
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs4
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs5
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs6
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs146
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs89
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs56
-rw-r--r--compiler/rustc_typeck/src/check/place_op.rs53
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs18
-rw-r--r--compiler/rustc_typeck/src/check/upvar.rs26
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs36
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls.rs7
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs3
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs7
-rw-r--r--compiler/rustc_typeck/src/lib.rs2
-rw-r--r--library/alloc/src/collections/btree/map/tests.rs105
-rw-r--r--library/alloc/src/collections/btree/set/tests.rs56
-rw-r--r--library/alloc/src/ffi/c_str.rs (renamed from library/std/src/ffi/c_str.rs)743
-rw-r--r--library/alloc/src/ffi/c_str/tests.rs (renamed from library/std/src/ffi/c_str/tests.rs)32
-rw-r--r--library/alloc/src/ffi/mod.rs91
-rw-r--r--library/alloc/src/lib.rs9
-rw-r--r--library/alloc/src/rc.rs38
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/tests/c_str.rs18
-rw-r--r--library/alloc/tests/lib.rs3
-rw-r--r--library/core/src/default.rs17
-rw-r--r--library/core/src/ffi/c_str.rs570
-rw-r--r--library/core/src/ffi/mod.rs5
-rw-r--r--library/core/src/iter/traits/iterator.rs4
-rw-r--r--library/core/src/lib.rs5
-rw-r--r--library/core/src/mem/maybe_uninit.rs21
-rw-r--r--library/core/src/prelude/mod.rs10
-rw-r--r--library/portable-simd/crates/core_simd/src/intrinsics.rs4
-rw-r--r--library/portable-simd/crates/core_simd/src/vector/ptr.rs11
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/error.rs43
-rw-r--r--library/std/src/ffi/mod.rs21
-rw-r--r--library/std/src/lib.rs5
-rw-r--r--library/std/src/prelude/mod.rs14
-rw-r--r--library/std/src/prelude/v1.rs4
-rw-r--r--library/std/src/sys/hermit/mod.rs10
-rw-r--r--library/std/src/sys/sgx/mod.rs10
-rw-r--r--library/std/src/sys/solid/mod.rs2
-rw-r--r--library/std/src/sys/unix/futex.rs30
-rw-r--r--library/std/src/sys/unix/locks/futex.rs12
-rw-r--r--library/std/src/sys/unix/locks/futex_rwlock.rs40
-rw-r--r--library/std/src/sys/unix/mod.rs1
-rw-r--r--library/std/src/sys/unsupported/common.rs16
-rw-r--r--library/std/src/sys/wasm/atomics/futex.rs14
-rw-r--r--library/std/src/sys/windows/mod.rs1
-rw-r--r--library/std/src/sys/windows/pipe.rs43
-rw-r--r--library/std/src/sys/windows/process.rs8
-rw-r--r--library/std/src/sys_common/thread_parker/futex.rs12
-rw-r--r--src/bootstrap/doc.rs36
-rw-r--r--src/ci/github-actions/ci.yml4
-rw-r--r--src/doc/rustc/src/SUMMARY.md5
-rw-r--r--src/doc/rustc/src/platform-support.md4
-rw-r--r--src/doc/rustc/src/tests/index.md4
-rw-r--r--src/librustdoc/html/render/span_map.rs7
-rw-r--r--src/librustdoc/passes/html_tags.rs2
-rw-r--r--src/librustdoc/visit_ast.rs2
-rw-r--r--src/test/assembly/asm/global_asm.rs13
-rw-r--r--src/test/codegen/simd_arith_offset.rs26
-rw-r--r--src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile19
-rw-r--r--src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs6
-rw-r--r--src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr11
-rw-r--r--src/test/ui/arg-count-mismatch.rs5
-rw-r--r--src/test/ui/arg-count-mismatch.stderr17
-rw-r--r--src/test/ui/arg-type-mismatch.rs5
-rw-r--r--src/test/ui/arg-type-mismatch.stderr9
-rw-r--r--src/test/ui/argument-suggestions/basic.rs25
-rw-r--r--src/test/ui/argument-suggestions/basic.stderr87
-rw-r--r--src/test/ui/argument-suggestions/complex.rs16
-rw-r--r--src/test/ui/argument-suggestions/complex.stderr19
-rw-r--r--src/test/ui/argument-suggestions/extra_arguments.rs35
-rw-r--r--src/test/ui/argument-suggestions/extra_arguments.stderr239
-rw-r--r--src/test/ui/argument-suggestions/invalid_arguments.rs43
-rw-r--r--src/test/ui/argument-suggestions/invalid_arguments.stderr299
-rw-r--r--src/test/ui/argument-suggestions/missing_arguments.rs40
-rw-r--r--src/test/ui/argument-suggestions/missing_arguments.stderr310
-rw-r--r--src/test/ui/argument-suggestions/mixed_cases.rs24
-rw-r--r--src/test/ui/argument-suggestions/mixed_cases.stderr117
-rw-r--r--src/test/ui/argument-suggestions/permuted_arguments.rs13
-rw-r--r--src/test/ui/argument-suggestions/permuted_arguments.stderr43
-rw-r--r--src/test/ui/argument-suggestions/swapped_arguments.rs14
-rw-r--r--src/test/ui/argument-suggestions/swapped_arguments.stderr95
-rw-r--r--src/test/ui/asm/aarch64/parse-error.rs2
-rw-r--r--src/test/ui/asm/aarch64/parse-error.stderr10
-rw-r--r--src/test/ui/asm/aarch64/type-check-2.rs15
-rw-r--r--src/test/ui/asm/aarch64/type-check-2.stderr34
-rw-r--r--src/test/ui/asm/type-check-1.rs9
-rw-r--r--src/test/ui/asm/type-check-1.stderr29
-rw-r--r--src/test/ui/asm/x86_64/parse-error.rs2
-rw-r--r--src/test/ui/asm/x86_64/parse-error.stderr10
-rw-r--r--src/test/ui/asm/x86_64/type-check-2.rs15
-rw-r--r--src/test/ui/asm/x86_64/type-check-2.stderr34
-rw-r--r--src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr40
-rw-r--r--src/test/ui/associated-types/associated-types-path-2.stderr9
-rw-r--r--src/test/ui/async-await/dont-suggest-missing-await.stderr9
-rw-r--r--src/test/ui/async-await/generator-desc.stderr53
-rw-r--r--src/test/ui/async-await/suggest-missing-await-closure.stderr9
-rw-r--r--src/test/ui/async-await/suggest-missing-await.stderr9
-rw-r--r--src/test/ui/binding/issue-53114-safety-checks.rs8
-rw-r--r--src/test/ui/binding/issue-53114-safety-checks.stderr64
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-1.stderr16
-rw-r--r--src/test/ui/cast/cast-int-to-char.stderr46
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs9
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr24
-rw-r--r--src/test/ui/closures/closure-reform-bad.stderr9
-rw-r--r--src/test/ui/closures/issue-84128.stderr9
-rw-r--r--src/test/ui/closures/issue-87461.stderr12
-rw-r--r--src/test/ui/coercion/coerce-mut.stderr9
-rw-r--r--src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr13
-rw-r--r--src/test/ui/coercion/coerce-to-bang.stderr45
-rw-r--r--src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr29
-rw-r--r--src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr8
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr23
-rw-r--r--src/test/ui/derives/deriving-with-repr-packed.stderr64
-rw-r--r--src/test/ui/deriving/deriving-default-enum.rs2
-rw-r--r--src/test/ui/deriving/deriving-with-helper.rs1
-rw-r--r--src/test/ui/did_you_mean/issue-42764.stderr9
-rw-r--r--src/test/ui/disambiguate-identical-names.stderr9
-rw-r--r--src/test/ui/error-codes/E0057.stderr18
-rw-r--r--src/test/ui/error-codes/E0060.rs1
-rw-r--r--src/test/ui/error-codes/E0060.stderr8
-rw-r--r--src/test/ui/error-codes/E0061.rs2
-rw-r--r--src/test/ui/error-codes/E0061.stderr18
-rw-r--r--src/test/ui/estr-subtyping.rs15
-rw-r--r--src/test/ui/estr-subtyping.stderr18
-rw-r--r--src/test/ui/feature-gates/feature-gate-derive_default_enum.rs7
-rw-r--r--src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr13
-rw-r--r--src/test/ui/fmt/ifmt-bad-arg.stderr20
-rw-r--r--src/test/ui/fn/fn-item-type.rs6
-rw-r--r--src/test/ui/fn/fn-item-type.stderr63
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs8
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr19
-rw-r--r--src/test/ui/generic-associated-types/issue-68648-2.stderr9
-rw-r--r--src/test/ui/generic-associated-types/missing-bounds.stderr27
-rw-r--r--src/test/ui/hello.rs11
-rw-r--r--src/test/ui/hello2021.rs6
-rw-r--r--src/test/ui/hrtb/issue-58451.stderr8
-rw-r--r--src/test/ui/impl-trait/issues/issue-74282.stderr9
-rw-r--r--src/test/ui/imports/overlapping_pub_trait.rs4
-rw-r--r--src/test/ui/imports/unnamed_pub_trait.rs4
-rw-r--r--src/test/ui/indexing-requires-a-uint.stderr11
-rw-r--r--src/test/ui/inference/deref-suggestion.stderr49
-rw-r--r--src/test/ui/inference/tutorial-suffix-inference-test.stderr27
-rw-r--r--src/test/ui/issues/issue-10764.stderr9
-rw-r--r--src/test/ui/issues/issue-11374.stderr14
-rw-r--r--src/test/ui/issues/issue-12997-2.stderr10
-rw-r--r--src/test/ui/issues/issue-13359.stderr22
-rw-r--r--src/test/ui/issues/issue-13853.stderr14
-rw-r--r--src/test/ui/issues/issue-1448-2.stderr9
-rw-r--r--src/test/ui/issues/issue-15783.stderr9
-rw-r--r--src/test/ui/issues/issue-16939.stderr8
-rw-r--r--src/test/ui/issues/issue-17033.stderr9
-rw-r--r--src/test/ui/issues/issue-18819.stderr17
-rw-r--r--src/test/ui/issues/issue-24819.stderr9
-rw-r--r--src/test/ui/issues/issue-26094.rs4
-rw-r--r--src/test/ui/issues/issue-26094.stderr8
-rw-r--r--src/test/ui/issues/issue-3044.rs3
-rw-r--r--src/test/ui/issues/issue-3044.stderr27
-rw-r--r--src/test/ui/issues/issue-43420-no-over-suggest.stderr9
-rw-r--r--src/test/ui/issues/issue-4517.stderr10
-rw-r--r--src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr30
-rw-r--r--src/test/ui/issues/issue-48364.stderr9
-rw-r--r--src/test/ui/issues/issue-4935.stderr8
-rw-r--r--src/test/ui/issues/issue-51154.stderr9
-rw-r--r--src/test/ui/issues/issue-5216.stderr9
-rw-r--r--src/test/ui/issues/issue-61106.stderr15
-rw-r--r--src/test/ui/issues/issue-69306.stderr45
-rw-r--r--src/test/ui/lint/unaligned_references.stderr119
-rw-r--r--src/test/ui/lint/unaligned_references_external_macro.stderr30
-rw-r--r--src/test/ui/macros/issue-29084.stderr12
-rw-r--r--src/test/ui/macros/macros-nonfatal-errors.rs1
-rw-r--r--src/test/ui/macros/macros-nonfatal-errors.stderr58
-rw-r--r--src/test/ui/methods/method-call-err-msg.stderr32
-rw-r--r--src/test/ui/methods/method-self-arg-1.stderr24
-rw-r--r--src/test/ui/mir/issue-92893.rs7
-rw-r--r--src/test/ui/mir/issue-92893.stderr20
-rw-r--r--src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs10
-rw-r--r--src/test/ui/mismatched_types/issue-26480.stderr11
-rw-r--r--src/test/ui/mismatched_types/issue-35030.stderr4
-rw-r--r--src/test/ui/mismatched_types/numeric-literal-cast.stderr27
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.rs1
-rw-r--r--src/test/ui/mismatched_types/overloaded-calls-bad.stderr34
-rw-r--r--src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr9
-rw-r--r--src/test/ui/mut/mut-cross-borrowing.stderr14
-rw-r--r--src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr9
-rw-r--r--src/test/ui/not-enough-arguments.stderr16
-rw-r--r--src/test/ui/numeric/integer-literal-suffix-inference.stderr468
-rw-r--r--src/test/ui/numeric/len.stderr9
-rw-r--r--src/test/ui/numeric/numeric-cast-without-suggestion.stderr210
-rw-r--r--src/test/ui/numeric/numeric-cast.stderr1017
-rw-r--r--src/test/ui/numeric/numeric-suffix.fixed298
-rw-r--r--src/test/ui/numeric/numeric-suffix.rs298
-rw-r--r--src/test/ui/numeric/numeric-suffix.stderr1477
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr201
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr201
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr201
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr201
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr201
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs73
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr201
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed427
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix.rs427
-rw-r--r--src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr1227
-rw-r--r--src/test/ui/packed/issue-27060-rpass.stderr68
-rw-r--r--src/test/ui/packed/issue-27060.rs1
-rw-r--r--src/test/ui/packed/issue-27060.stderr66
-rw-r--r--src/test/ui/packed/packed-struct-address-of-element.rs1
-rw-r--r--src/test/ui/packed/packed-struct-borrow-element-64bit.rs1
-rw-r--r--src/test/ui/packed/packed-struct-borrow-element-64bit.stderr25
-rw-r--r--src/test/ui/packed/packed-struct-borrow-element.rs1
-rw-r--r--src/test/ui/packed/packed-struct-borrow-element.stderr44
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.rs10
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.stderr48
-rw-r--r--src/test/ui/pattern/pattern-error-continue.stderr10
-rw-r--r--src/test/ui/proc-macro/signature.stderr5
-rw-r--r--src/test/ui/range/issue-54505-no-literals.stderr168
-rw-r--r--src/test/ui/range/issue-54505-no-std.stderr84
-rw-r--r--src/test/ui/range/issue-54505.stderr84
-rw-r--r--src/test/ui/range/issue-73553-misinterp-range-literal.stderr28
-rw-r--r--src/test/ui/resolve/resolve-primitive-fallback.stderr8
-rw-r--r--src/test/ui/self/issue-61882.stderr10
-rw-r--r--src/test/ui/span/E0057.rs6
-rw-r--r--src/test/ui/span/E0057.stderr25
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr18
-rw-r--r--src/test/ui/span/issue-34264.stderr26
-rw-r--r--src/test/ui/span/missing-unit-argument.stderr40
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple-errors.stderr42
-rw-r--r--src/test/ui/suggestions/args-instead-of-tuple.stderr24
-rw-r--r--src/test/ui/suggestions/as-ref.stderr44
-rw-r--r--src/test/ui/suggestions/boxed-variant-field.stderr9
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr6
-rw-r--r--src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr9
-rw-r--r--src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr9
-rw-r--r--src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr10
-rw-r--r--src/test/ui/suggestions/suggest-ref-macro.stderr39
-rw-r--r--src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr63
-rw-r--r--src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr73
-rw-r--r--src/test/ui/suggestions/use-placement-typeck.fixed1
-rw-r--r--src/test/ui/terminal-width/flag-json.rs2
-rw-r--r--src/test/ui/terr-in-field.stderr10
-rw-r--r--src/test/ui/terr-sorts.stderr9
-rw-r--r--src/test/ui/traits/bound/sugar.stderr9
-rw-r--r--src/test/ui/traits/issue-52893.stderr13
-rw-r--r--src/test/ui/traits/issue-95311.rs19
-rw-r--r--src/test/ui/traits/multidispatch-bad.stderr9
-rw-r--r--src/test/ui/tuple/tuple-arity-mismatch.stderr18
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-2.stderr2
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-3.stderr12
-rw-r--r--src/test/ui/tuple/wrong_argument_ice-4.stderr9
-rw-r--r--src/test/ui/tuple/wrong_argument_ice.stderr2
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr18
-rw-r--r--src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr8
-rw-r--r--src/test/ui/type/type-ascription-instead-of-initializer.stderr8
-rw-r--r--src/test/ui/type/type-mismatch-same-crate-name.stderr18
-rw-r--r--src/test/ui/type/type-mismatch.stderr437
-rw-r--r--src/test/ui/typeck/autoderef-with-param-env-error.rs9
-rw-r--r--src/test/ui/typeck/autoderef-with-param-env-error.stderr12
-rw-r--r--src/test/ui/typeck/issue-46112.stderr4
-rw-r--r--src/test/ui/typeck/issue-84768.stderr9
-rw-r--r--src/test/ui/typeck/issue-89856.stderr9
-rw-r--r--src/test/ui/typeck/struct-enum-wrong-args.stderr69
-rw-r--r--src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr18
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr4
-rw-r--r--src/test/ui/unterminated-nested-comment.rs4
-rw-r--r--src/test/ui/unterminated-nested-comment.stderr21
-rw-r--r--src/test/ui/use/use-super-global-path.rs2
-rw-r--r--src/test/ui/use/use-super-global-path.stderr16
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/shadow.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/inspector.rs23
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs2
-rw-r--r--src/tools/rustfmt/src/bin/main.rs1
-rw-r--r--src/tools/rustfmt/src/config/options.rs5
393 files changed, 14043 insertions, 5242 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ff3a8326315..451116f320d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -56,7 +56,7 @@ jobs:
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: configure the PR in which the error message will be posted
@@ -454,7 +454,7 @@ jobs:
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: configure the PR in which the error message will be posted
@@ -567,7 +567,7 @@ jobs:
       - name: disable git crlf conversion
         run: git config --global core.autocrlf false
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: configure the PR in which the error message will be posted
@@ -670,7 +670,7 @@ jobs:
     if: "github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'"
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
       - name: publish toolstate
diff --git a/Cargo.lock b/Cargo.lock
index 325503a0e95..9eba61f8d29 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -311,7 +311,7 @@ dependencies = [
 
 [[package]]
 name = "cargo"
-version = "0.62.0"
+version = "0.63.0"
 dependencies = [
  "anyhow",
  "atty",
@@ -348,6 +348,7 @@ dependencies = [
  "opener",
  "openssl",
  "os_info",
+ "pathdiff",
  "percent-encoding 2.1.0",
  "pretty_env_logger",
  "rustc-workspace-hack",
@@ -453,7 +454,7 @@ dependencies = [
 
 [[package]]
 name = "cargo-util"
-version = "0.1.2"
+version = "0.1.3"
 dependencies = [
  "anyhow",
  "core-foundation",
@@ -730,9 +731,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.70"
+version = "0.1.71"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80873f979f0a344a4ade87c2f70d9ccf5720b83b10c97ec7cd745895d021e85a"
+checksum = "163437f05ca8f29d7e9128ea728dedf5eb620e445fbca273641d3a3050305f23"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
@@ -2651,9 +2652,9 @@ dependencies = [
 
 [[package]]
 name = "pathdiff"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877630b3de15c0b64cc52f659345724fbf6bdad9bd9566699fc53688f3c34a34"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
 
 [[package]]
 name = "percent-encoding"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 42ec206fc65..714f9383bb2 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2061,6 +2061,20 @@ impl InlineAsmTemplatePiece {
     }
 }
 
+/// Inline assembly symbol operands get their own AST node that is somewhat
+/// similar to `AnonConst`.
+///
+/// The main difference is that we specifically don't assign it `DefId` in
+/// `DefCollector`. Instead this is deferred until AST lowering where we
+/// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
+/// depending on what the path resolves to.
+#[derive(Clone, Encodable, Decodable, Debug)]
+pub struct InlineAsmSym {
+    pub id: NodeId,
+    pub qself: Option<QSelf>,
+    pub path: Path,
+}
+
 /// Inline assembly operand.
 ///
 /// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
@@ -2090,7 +2104,7 @@ pub enum InlineAsmOperand {
         anon_const: AnonConst,
     },
     Sym {
-        expr: P<Expr>,
+        sym: InlineAsmSym,
     },
 }
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 15f7aceb83d..cba49835f69 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -280,6 +280,14 @@ pub trait MutVisitor: Sized {
     fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
         noop_flat_map_pat_field(fp, self)
     }
+
+    fn visit_inline_asm(&mut self, asm: &mut InlineAsm) {
+        noop_visit_inline_asm(asm, self)
+    }
+
+    fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) {
+        noop_visit_inline_asm_sym(sym, self)
+    }
 }
 
 /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
@@ -1019,7 +1027,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             }
         }
         ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
-        ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
+        ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
         ItemKind::TyAlias(box TyAlias {
             defaultness, generics, where_clauses, bounds, ty, ..
         }) => {
@@ -1237,13 +1245,12 @@ pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonCo
     vis.visit_expr(value);
 }
 
-fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
+pub fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
     for (op, _) in &mut asm.operands {
         match op {
             InlineAsmOperand::In { expr, .. }
             | InlineAsmOperand::Out { expr: Some(expr), .. }
-            | InlineAsmOperand::InOut { expr, .. }
-            | InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr),
+            | InlineAsmOperand::InOut { expr, .. } => vis.visit_expr(expr),
             InlineAsmOperand::Out { expr: None, .. } => {}
             InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                 vis.visit_expr(in_expr);
@@ -1251,11 +1258,21 @@ fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
                     vis.visit_expr(out_expr);
                 }
             }
-            InlineAsmOperand::Const { anon_const, .. } => vis.visit_anon_const(anon_const),
+            InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
+            InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
         }
     }
 }
 
+pub fn noop_visit_inline_asm_sym<T: MutVisitor>(
+    InlineAsmSym { id, qself, path }: &mut InlineAsmSym,
+    vis: &mut T,
+) {
+    vis.visit_id(id);
+    vis.visit_qself(qself);
+    vis.visit_path(path);
+}
+
 pub fn noop_visit_expr<T: MutVisitor>(
     Expr { kind, id, span, attrs, tokens }: &mut Expr,
     vis: &mut T,
@@ -1374,7 +1391,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
         ExprKind::Ret(expr) => {
             visit_opt(expr, |expr| vis.visit_expr(expr));
         }
-        ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis),
+        ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
         ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
         ExprKind::Struct(se) => {
             let StructExpr { qself, path, fields, rest } = se.deref_mut();
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 031c6cae793..5aa8011ca5e 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -722,7 +722,7 @@ impl NonterminalKind {
                 Edition::Edition2015 | Edition::Edition2018 => {
                     NonterminalKind::PatParam { inferred: true }
                 }
-                Edition::Edition2021 => NonterminalKind::PatWithOr,
+                Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
             },
             sym::pat_param => NonterminalKind::PatParam { inferred: false },
             sym::expr => NonterminalKind::Expr,
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index ed16c25d921..3183612597d 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -214,6 +214,12 @@ pub trait Visitor<'ast>: Sized {
     fn visit_crate(&mut self, krate: &'ast Crate) {
         walk_crate(self, krate)
     }
+    fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {
+        walk_inline_asm(self, asm)
+    }
+    fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
+        walk_inline_asm_sym(self, sym)
+    }
 }
 
 #[macro_export]
@@ -717,13 +723,12 @@ pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonCo
     visitor.visit_expr(&constant.value);
 }
 
-fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
+pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
     for (op, _) in &asm.operands {
         match op {
             InlineAsmOperand::In { expr, .. }
             | InlineAsmOperand::Out { expr: Some(expr), .. }
-            | InlineAsmOperand::InOut { expr, .. }
-            | InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
+            | InlineAsmOperand::InOut { expr, .. } => visitor.visit_expr(expr),
             InlineAsmOperand::Out { expr: None, .. } => {}
             InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                 visitor.visit_expr(in_expr);
@@ -732,10 +737,18 @@ fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
                 }
             }
             InlineAsmOperand::Const { anon_const, .. } => visitor.visit_anon_const(anon_const),
+            InlineAsmOperand::Sym { sym } => visitor.visit_inline_asm_sym(sym),
         }
     }
 }
 
+pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineAsmSym) {
+    if let Some(ref qself) = sym.qself {
+        visitor.visit_ty(&qself.ty);
+    }
+    visitor.visit_path(&sym.path, sym.id);
+}
+
 pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
     walk_list!(visitor, visit_attribute, expression.attrs.iter());
 
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 171cc60dfd7..ae3e3675962 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -1,12 +1,17 @@
+use crate::{ImplTraitContext, ImplTraitPosition, ParamMode};
+
 use super::LoweringContext;
 
+use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::definitions::DefPathData;
 use rustc_session::parse::feature_err;
-use rustc_span::{sym, Span};
+use rustc_span::{sym, ExpnId, Span};
 use rustc_target::asm;
 use std::collections::hash_map::Entry;
 use std::fmt::Write;
@@ -188,7 +193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             anon_const: self.lower_anon_const(anon_const),
                         }
                     }
-                    InlineAsmOperand::Sym { ref expr } => {
+                    InlineAsmOperand::Sym { ref sym } => {
                         if !self.sess.features_untracked().asm_sym {
                             feature_err(
                                 &self.sess.parse_sess,
@@ -198,7 +203,54 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             )
                             .emit();
                         }
-                        hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
+
+                        let static_def_id = self
+                            .resolver
+                            .get_partial_res(sym.id)
+                            .filter(|res| res.unresolved_segments() == 0)
+                            .and_then(|res| {
+                                if let Res::Def(DefKind::Static(_), def_id) = res.base_res() {
+                                    Some(def_id)
+                                } else {
+                                    None
+                                }
+                            });
+
+                        if let Some(def_id) = static_def_id {
+                            let path = self.lower_qpath(
+                                sym.id,
+                                &sym.qself,
+                                &sym.path,
+                                ParamMode::Optional,
+                                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            );
+                            hir::InlineAsmOperand::SymStatic { path, def_id }
+                        } else {
+                            // Replace the InlineAsmSym AST node with an
+                            // Expr using the name node id.
+                            let expr = Expr {
+                                id: sym.id,
+                                kind: ExprKind::Path(sym.qself.clone(), sym.path.clone()),
+                                span: *op_sp,
+                                attrs: AttrVec::new(),
+                                tokens: None,
+                            };
+
+                            // Wrap the expression in an AnonConst.
+                            let parent_def_id = self.current_hir_id_owner;
+                            let node_id = self.resolver.next_node_id();
+                            self.resolver.create_def(
+                                parent_def_id,
+                                node_id,
+                                DefPathData::AnonConst,
+                                ExpnId::root(),
+                                *op_sp,
+                            );
+                            let anon_const = AnonConst { id: node_id, value: P(expr) };
+                            hir::InlineAsmOperand::SymFn {
+                                anon_const: self.lower_anon_const(&anon_const),
+                            }
+                        }
                     }
                 };
                 (op, self.lower_span(*op_sp))
@@ -260,7 +312,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         err.span_label(op_sp, "argument");
                         err.emit();
                     }
-                    hir::InlineAsmOperand::Sym { .. } => {
+                    hir::InlineAsmOperand::SymFn { .. }
+                    | hir::InlineAsmOperand::SymStatic { .. } => {
                         let mut err = sess.struct_span_err(
                             placeholder_span,
                             "asm template modifiers are not allowed for `sym` arguments",
@@ -308,7 +361,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         hir::InlineAsmOperand::InOut { .. }
                         | hir::InlineAsmOperand::SplitInOut { .. } => (true, true),
 
-                        hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {
+                        hir::InlineAsmOperand::Const { .. }
+                        | hir::InlineAsmOperand::SymFn { .. }
+                        | hir::InlineAsmOperand::SymStatic { .. } => {
                             unreachable!()
                         }
                     };
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 62935a2b1f7..5eab21bf79a 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -52,7 +52,9 @@ pub(super) fn index_hir<'hir>(
     };
 
     match item {
-        OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID),
+        OwnerNode::Crate(citem) => {
+            collector.visit_mod(&citem, citem.spans.inner_span, hir::CRATE_HIR_ID)
+        }
         OwnerNode::Item(item) => collector.visit_item(item),
         OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
         OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c8fd96309a6..a8bd8c92a41 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -124,7 +124,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
         debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
 
         self.with_lctx(CRATE_NODE_ID, |lctx| {
-            let module = lctx.lower_mod(&c.items, c.spans.inner_span);
+            let module = lctx.lower_mod(&c.items, &c.spans);
             lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
             hir::OwnerNode::Crate(lctx.arena.alloc(module))
         })
@@ -186,9 +186,12 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
 }
 
 impl<'hir> LoweringContext<'_, 'hir> {
-    pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
+    pub(super) fn lower_mod(&mut self, items: &[P<Item>], spans: &ModSpans) -> hir::Mod<'hir> {
         hir::Mod {
-            inner: self.lower_span(inner),
+            spans: hir::ModSpans {
+                inner_span: self.lower_span(spans.inner_span),
+                inject_use_span: self.lower_span(spans.inject_use_span),
+            },
             item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
         }
     }
@@ -308,8 +311,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 })
             }
             ItemKind::Mod(_, ref mod_kind) => match mod_kind {
-                ModKind::Loaded(items, _, ModSpans { inner_span, inject_use_span: _ }) => {
-                    hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
+                ModKind::Loaded(items, _, spans) => {
+                    hir::ItemKind::Mod(self.lower_mod(items, spans))
                 }
                 ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
             },
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 719fd271093..c2247150d09 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1266,10 +1266,14 @@ impl<'a> State<'a> {
                         s.space();
                         s.print_expr(&anon_const.value);
                     }
-                    InlineAsmOperand::Sym { expr } => {
+                    InlineAsmOperand::Sym { sym } => {
                         s.word("sym");
                         s.space();
-                        s.print_expr(expr);
+                        if let Some(qself) = &sym.qself {
+                            s.print_qpath(&sym.path, qself, true);
+                        } else {
+                            s.print_path(&sym.path, true, 0);
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 57ef46475dd..030295d3d8d 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -154,17 +154,19 @@ pub fn parse_asm_args<'a>(
         } else if p.eat_keyword(kw::Const) {
             let anon_const = p.parse_anon_const_expr()?;
             ast::InlineAsmOperand::Const { anon_const }
-        } else if !is_global_asm && p.eat_keyword(sym::sym) {
+        } else if p.eat_keyword(sym::sym) {
             let expr = p.parse_expr()?;
-            match expr.kind {
-                ast::ExprKind::Path(..) => {}
-                _ => {
-                    let err = diag
-                        .struct_span_err(expr.span, "argument to `sym` must be a path expression");
-                    return Err(err);
-                }
-            }
-            ast::InlineAsmOperand::Sym { expr }
+            let ast::ExprKind::Path(qself, path) = &expr.kind else {
+                let err = diag
+                    .struct_span_err(expr.span, "expected a path for argument to `sym`");
+                return Err(err);
+            };
+            let sym = ast::InlineAsmSym {
+                id: ast::DUMMY_NODE_ID,
+                qself: qself.clone(),
+                path: path.clone(),
+            };
+            ast::InlineAsmOperand::Sym { sym }
         } else if allow_templates {
             let template = p.parse_expr()?;
             // If it can't possibly expand to a string, provide diagnostics here to include other
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index ca83941f600..2c5260616c7 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -46,18 +46,7 @@ pub fn expand_deriving_default(
                     StaticStruct(_, fields) => {
                         default_struct_substructure(cx, trait_span, substr, fields)
                     }
-                    StaticEnum(enum_def, _) => {
-                        if !cx.sess.features_untracked().derive_default_enum {
-                            rustc_session::parse::feature_err(
-                                cx.parse_sess(),
-                                sym::derive_default_enum,
-                                span,
-                                "deriving `Default` on enums is experimental",
-                            )
-                            .emit();
-                        }
-                        default_enum_substructure(cx, trait_span, enum_def)
-                    }
+                    StaticEnum(enum_def, _) => default_enum_substructure(cx, trait_span, enum_def),
                     _ => cx.span_bug(trait_span, "method in `derive(Default)`"),
                 }
             })),
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index 3571517d2b2..09ad5f9b3ea 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -70,6 +70,7 @@ pub fn inject(
             Edition2015 => sym::rust_2015,
             Edition2018 => sym::rust_2018,
             Edition2021 => sym::rust_2021,
+            Edition2024 => sym::rust_2024,
         }])
         .map(|&symbol| Ident::new(symbol, span))
         .collect();
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 8a74c4c07e0..2af050f0c75 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -258,9 +258,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                 }
 
                 InlineAsmOperandRef::SymFn { instance } => {
+                    // TODO(@Amanieu): Additional mangling is needed on
+                    // some targets to add a leading underscore (Mach-O)
+                    // or byte count suffixes (x86 Windows).
                     constants_len += self.tcx.symbol_name(instance).name.len();
                 }
                 InlineAsmOperandRef::SymStatic { def_id } => {
+                    // TODO(@Amanieu): Additional mangling is needed on
+                    // some targets to add a leading underscore (Mach-O).
                     constants_len += self.tcx.symbol_name(Instance::mono(self.tcx, def_id)).name.len();
                 }
             }
@@ -412,13 +417,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                         }
 
                         InlineAsmOperandRef::SymFn { instance } => {
+                            // TODO(@Amanieu): Additional mangling is needed on
+                            // some targets to add a leading underscore (Mach-O)
+                            // or byte count suffixes (x86 Windows).
                             let name = self.tcx.symbol_name(instance).name;
                             template_str.push_str(name);
                         }
 
                         InlineAsmOperandRef::SymStatic { def_id } => {
-                            // TODO(@Commeownist): This may not be sufficient for all kinds of statics.
-                            // Some statics may need the `@plt` suffix, like thread-local vars.
+                            // TODO(@Amanieu): Additional mangling is needed on
+                            // some targets to add a leading underscore (Mach-O).
                             let instance = Instance::mono(self.tcx, def_id);
                             let name = self.tcx.symbol_name(instance).name;
                             template_str.push_str(name);
@@ -656,8 +664,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
     }
 }
 
-impl<'gcc, 'tcx> AsmMethods for CodegenCx<'gcc, 'tcx> {
-    fn codegen_global_asm(&self, template: &[InlineAsmTemplatePiece], operands: &[GlobalAsmOperandRef], options: InlineAsmOptions, _line_spans: &[Span]) {
+impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+    fn codegen_global_asm(&self, template: &[InlineAsmTemplatePiece], operands: &[GlobalAsmOperandRef<'tcx>], options: InlineAsmOptions, _line_spans: &[Span]) {
         let asm_arch = self.tcx.sess.asm_arch.unwrap();
 
         // Default to Intel syntax on x86
@@ -690,6 +698,22 @@ impl<'gcc, 'tcx> AsmMethods for CodegenCx<'gcc, 'tcx> {
                             // here unlike normal inline assembly.
                             template_str.push_str(string);
                         }
+
+                        GlobalAsmOperandRef::SymFn { instance } => {
+                            // TODO(@Amanieu): Additional mangling is needed on
+                            // some targets to add a leading underscore (Mach-O)
+                            // or byte count suffixes (x86 Windows).
+                            let name = self.tcx.symbol_name(instance).name;
+                            template_str.push_str(name);
+                        }
+
+                        GlobalAsmOperandRef::SymStatic { def_id } => {
+                            // TODO(@Amanieu): Additional mangling is needed on
+                            // some targets to add a leading underscore (Mach-O).
+                            let instance = Instance::mono(self.tcx, def_id);
+                            let name = self.tcx.symbol_name(instance).name;
+                            template_str.push_str(name);
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 91d132eb343..dff32007918 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -312,11 +312,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 }
 
-impl AsmMethods for CodegenCx<'_, '_> {
+impl<'tcx> AsmMethods<'tcx> for CodegenCx<'_, 'tcx> {
     fn codegen_global_asm(
         &self,
         template: &[InlineAsmTemplatePiece],
-        operands: &[GlobalAsmOperandRef],
+        operands: &[GlobalAsmOperandRef<'tcx>],
         options: InlineAsmOptions,
         _line_spans: &[Span],
     ) {
@@ -342,6 +342,29 @@ impl AsmMethods for CodegenCx<'_, '_> {
                             // here unlike normal inline assembly.
                             template_str.push_str(string);
                         }
+                        GlobalAsmOperandRef::SymFn { instance } => {
+                            let llval = self.get_fn(instance);
+                            self.add_compiler_used_global(llval);
+                            let symbol = llvm::build_string(|s| unsafe {
+                                llvm::LLVMRustGetMangledName(llval, s);
+                            })
+                            .expect("symbol is not valid UTF-8");
+                            template_str.push_str(&symbol);
+                        }
+                        GlobalAsmOperandRef::SymStatic { def_id } => {
+                            let llval = self
+                                .renamed_statics
+                                .borrow()
+                                .get(&def_id)
+                                .copied()
+                                .unwrap_or_else(|| self.get_static(def_id));
+                            self.add_compiler_used_global(llval);
+                            let symbol = llvm::build_string(|s| unsafe {
+                                llvm::LLVMRustGetMangledName(llval, s);
+                            })
+                            .expect("symbol is not valid UTF-8");
+                            template_str.push_str(&symbol);
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs
index dd3ada44389..c163c7d8692 100644
--- a/compiler/rustc_codegen_llvm/src/base.rs
+++ b/compiler/rustc_codegen_llvm/src/base.rs
@@ -99,15 +99,6 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
                 attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs);
             }
 
-            // Run replace-all-uses-with for statics that need it
-            for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {
-                unsafe {
-                    let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g));
-                    llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
-                    llvm::LLVMDeleteGlobal(old_g);
-                }
-            }
-
             // Finalize code coverage by injecting the coverage map. Note, the coverage map will
             // also be added to the `llvm.compiler.used` variable, created next.
             if cx.sess().instrument_coverage() {
@@ -122,6 +113,16 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
                 cx.create_compiler_used_variable()
             }
 
+            // Run replace-all-uses-with for statics that need it. This must
+            // happen after the llvm.used variables are created.
+            for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {
+                unsafe {
+                    let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g));
+                    llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
+                    llvm::LLVMDeleteGlobal(old_g);
+                }
+            }
+
             // Finalize debuginfo
             if cx.sess().opts.debuginfo != DebugInfo::None {
                 cx.debuginfo_finalize();
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index cb4073528e1..4d3f3f318b8 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -412,6 +412,13 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
                 llvm::LLVMRustSetLinkage(new_g, linkage);
                 llvm::LLVMRustSetVisibility(new_g, visibility);
 
+                // The old global has had its name removed but is returned by
+                // get_static since it is in the instance cache. Provide an
+                // alternative lookup that points to the new global so that
+                // global_asm! can compute the correct mangled symbol name
+                // for the global.
+                self.renamed_statics.borrow_mut().insert(def_id, new_g);
+
                 // To avoid breaking any invariants, we leave around the old
                 // global for the moment; we'll replace all references to it
                 // with the new global later. (See base::codegen_backend.)
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 98cf873ebbd..d296ee3b42c 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -14,6 +14,7 @@ use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::small_c_str::SmallCStr;
+use rustc_hir::def_id::DefId;
 use rustc_middle::mir::mono::CodegenUnit;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
@@ -105,6 +106,12 @@ pub struct CodegenCx<'ll, 'tcx> {
 
     /// A counter that is used for generating local symbol names
     local_gen_sym_counter: Cell<usize>,
+
+    /// `codegen_static` will sometimes create a second global variable with a
+    /// different type and clear the symbol name of the original global.
+    /// `global_asm!` needs to be able to find this new global so that it can
+    /// compute the correct mangled symbol name to insert into the asm.
+    pub renamed_statics: RefCell<FxHashMap<DefId, &'ll Value>>,
 }
 
 pub struct TypeLowering<'ll> {
@@ -436,6 +443,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
             rust_try_fn: Cell::new(None),
             intrinsics: Default::default(),
             local_gen_sym_counter: Cell::new(0),
+            renamed_statics: Default::default(),
         }
     }
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index 31bb9ed3185..d6e2c8ccdf4 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -372,7 +372,6 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
 
     // Build the type node for each field.
     let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range
-        .clone()
         .map(|variant_index| {
             let variant_struct_type_di_node = super::build_generator_variant_struct_type_di_node(
                 cx,
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 48840c76cac..cf9cf1b70aa 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1839,6 +1839,27 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         simd_neg: Int => neg, Float => fneg;
     }
 
+    if name == sym::simd_arith_offset {
+        // This also checks that the first operand is a ptr type.
+        let pointee = in_elem.builtin_deref(true).unwrap_or_else(|| {
+            span_bug!(span, "must be called with a vector of pointer types as first argument")
+        });
+        let layout = bx.layout_of(pointee.ty);
+        let ptrs = args[0].immediate();
+        // The second argument must be a ptr-sized integer.
+        // (We don't care about the signedness, this is wrapping anyway.)
+        let (_offsets_len, offsets_elem) = arg_tys[1].simd_size_and_type(bx.tcx());
+        if !matches!(offsets_elem.kind(), ty::Int(ty::IntTy::Isize) | ty::Uint(ty::UintTy::Usize)) {
+            span_bug!(
+                span,
+                "must be called with a vector of pointer-sized integers as second argument"
+            );
+        }
+        let offsets = args[1].immediate();
+
+        return Ok(bx.gep(bx.backend_type(layout), ptrs, &[offsets]));
+    }
+
     if name == sym::simd_saturating_add || name == sym::simd_saturating_sub {
         let lhs = args[0].immediate();
         let rhs = args[1].immediate();
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 375b9927c86..7f533b0552a 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2537,4 +2537,6 @@ extern "C" {
         remark_passes_len: usize,
     );
 
+    #[allow(improper_ctypes)]
+    pub fn LLVMRustGetMangledName(V: &Value, out: &RustString);
 }
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index 5414c619dcb..5006a2157fc 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -4,7 +4,9 @@ use crate::traits::*;
 use rustc_hir as hir;
 use rustc_middle::mir::mono::MonoItem;
 use rustc_middle::mir::mono::{Linkage, Visibility};
+use rustc_middle::ty;
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::ty::Instance;
 
 pub trait MonoItemExt<'a, 'tcx> {
     fn define<Bx: BuilderMethods<'a, 'tcx>>(&self, cx: &'a Bx::CodegenCx);
@@ -56,7 +58,27 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                                 );
                                 GlobalAsmOperandRef::Const { string }
                             }
-                            _ => span_bug!(*op_sp, "invalid operand type for global_asm!"),
+                            hir::InlineAsmOperand::SymFn { ref anon_const } => {
+                                let ty = cx
+                                    .tcx()
+                                    .typeck_body(anon_const.body)
+                                    .node_type(anon_const.hir_id);
+                                let instance = match ty.kind() {
+                                    &ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
+                                    _ => span_bug!(*op_sp, "asm sym is not a function"),
+                                };
+
+                                GlobalAsmOperandRef::SymFn { instance }
+                            }
+                            hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
+                                GlobalAsmOperandRef::SymStatic { def_id }
+                            }
+                            hir::InlineAsmOperand::In { .. }
+                            | hir::InlineAsmOperand::Out { .. }
+                            | hir::InlineAsmOperand::InOut { .. }
+                            | hir::InlineAsmOperand::SplitInOut { .. } => {
+                                span_bug!(*op_sp, "invalid operand type for global_asm!")
+                            }
                         })
                         .collect();
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs
index 11111a79744..c2ae74b18d8 100644
--- a/compiler/rustc_codegen_ssa/src/traits/asm.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs
@@ -36,8 +36,10 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
 }
 
 #[derive(Debug)]
-pub enum GlobalAsmOperandRef {
+pub enum GlobalAsmOperandRef<'tcx> {
     Const { string: String },
+    SymFn { instance: Instance<'tcx> },
+    SymStatic { def_id: DefId },
 }
 
 pub trait AsmBuilderMethods<'tcx>: BackendTypes {
@@ -53,11 +55,11 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
     );
 }
 
-pub trait AsmMethods {
+pub trait AsmMethods<'tcx> {
     fn codegen_global_asm(
         &self,
         template: &[InlineAsmTemplatePiece],
-        operands: &[GlobalAsmOperandRef],
+        operands: &[GlobalAsmOperandRef<'tcx>],
         options: InlineAsmOptions,
         line_spans: &[Span],
     );
diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs
index c529fbbf518..396768e0a42 100644
--- a/compiler/rustc_codegen_ssa/src/traits/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs
@@ -60,7 +60,7 @@ pub trait CodegenMethods<'tcx>:
     + StaticMethods
     + CoverageInfoMethods<'tcx>
     + DebugInfoMethods<'tcx>
-    + AsmMethods
+    + AsmMethods<'tcx>
     + PreDefineMethods<'tcx>
     + HasParamEnv<'tcx>
     + HasTyCtxt<'tcx>
@@ -76,7 +76,7 @@ impl<'tcx, T> CodegenMethods<'tcx> for T where
         + StaticMethods
         + CoverageInfoMethods<'tcx>
         + DebugInfoMethods<'tcx>
-        + AsmMethods
+        + AsmMethods<'tcx>
         + PreDefineMethods<'tcx>
         + HasParamEnv<'tcx>
         + HasTyCtxt<'tcx>
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index eb1a184bf9b..e6dfdf54a32 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -196,27 +196,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.write_immediate(*val, &dest)?;
             }
 
-            Aggregate(ref kind, ref operands) => {
-                // active_field_index is for union initialization.
-                let (dest, active_field_index) = match **kind {
-                    mir::AggregateKind::Adt(adt_did, variant_index, _, _, active_field_index) => {
-                        self.write_discriminant(variant_index, &dest)?;
-                        if self.tcx.adt_def(adt_did).is_enum() {
-                            assert!(active_field_index.is_none());
-                            (self.place_downcast(&dest, variant_index)?, None)
-                        } else {
-                            if active_field_index.is_some() {
-                                assert_eq!(operands.len(), 1);
-                            }
-                            (dest, active_field_index)
-                        }
-                    }
-                    _ => (dest, None),
-                };
+            Aggregate(box ref kind, ref operands) => {
+                assert!(matches!(kind, mir::AggregateKind::Array(..)));
 
-                for (i, operand) in operands.iter().enumerate() {
+                for (field_index, operand) in operands.iter().enumerate() {
                     let op = self.eval_operand(operand, None)?;
-                    let field_index = active_field_index.unwrap_or(i);
                     let field_dest = self.place_field(&dest, field_index)?;
                     self.copy_op(&op, &field_dest)?;
                 }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 01af9585135..79d427ccc44 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -315,9 +315,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                                     | ty::FnPtr(..)
                             )
                         }
-                        // None of the possible types have lifetimes, so we can just compare
-                        // directly
-                        if a != b {
+                        // The function pointer types can have lifetimes
+                        if !self.mir_assign_valid_types(a, b) {
                             self.fail(
                                 location,
                                 format!("Cannot compare unequal types {:?} and {:?}", a, b),
@@ -464,7 +463,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 };
                 // since CopyNonOverlapping is parametrized by 1 type,
                 // we only need to check that they are equal and not keep an extra parameter.
-                if op_src_ty != op_dst_ty {
+                if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) {
                     self.fail(location, format!("bad arg ({:?} != {:?})", op_src_ty, op_dst_ty));
                 }
 
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 1a3fe652521..98d4870e645 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -27,7 +27,6 @@
 #![feature(thread_id_value)]
 #![feature(vec_into_raw_parts)]
 #![allow(rustc::default_hash_types)]
-#![deny(unaligned_references)]
 #![allow(rustc::potential_query_instability)]
 
 #[macro_use]
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index ecb3cdd627c..9cd072c8b4c 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -832,7 +832,7 @@ impl Diagnostic {
         name: impl Into<Cow<'static, str>>,
         arg: DiagnosticArgValue<'static>,
     ) -> &mut Self {
-        self.args.push((name.into(), arg.into()));
+        self.args.push((name.into(), arg));
         self
     }
 
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index cfad1fc01ab..416bc4e2e3b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1208,7 +1208,7 @@ impl HandlerInner {
             (0, 0) => return,
             (0, _) => self.emitter.emit_diagnostic(&Diagnostic::new(
                 Level::Warning,
-                DiagnosticMessage::Str(warnings.to_owned()),
+                DiagnosticMessage::Str(warnings),
             )),
             (_, 0) => {
                 let _ = self.fatal(&errors);
diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs
index 4298475767e..c6a6e3d125f 100644
--- a/compiler/rustc_expand/src/mbe/macro_check.rs
+++ b/compiler/rustc_expand/src/mbe/macro_check.rs
@@ -270,7 +270,7 @@ fn check_binders(
                     MISSING_FRAGMENT_SPECIFIER,
                     span,
                     node_id,
-                    &format!("missing fragment specifier"),
+                    "missing fragment specifier",
                 );
             }
             if !macros.is_empty() {
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 74b8450f756..8f260e1cdb5 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -77,7 +77,6 @@ use crate::mbe::{KleeneOp, TokenTree};
 
 use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token};
 use rustc_parse::parser::{NtOrTt, Parser};
-use rustc_session::parse::ParseSess;
 use rustc_span::symbol::MacroRulesNormalizedIdent;
 use rustc_span::Span;
 
@@ -128,9 +127,8 @@ pub(super) enum MatcherLoc {
     Eof,
 }
 
-pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<MatcherLoc> {
+pub(super) fn compute_locs(matcher: &[TokenTree]) -> Vec<MatcherLoc> {
     fn inner(
-        sess: &ParseSess,
         tts: &[TokenTree],
         locs: &mut Vec<MatcherLoc>,
         next_metavar: &mut usize,
@@ -147,7 +145,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match
 
                     locs.push(MatcherLoc::Delimited);
                     locs.push(MatcherLoc::Token { token: open_token });
-                    inner(sess, &delimited.tts, locs, next_metavar, seq_depth);
+                    inner(&delimited.tts, locs, next_metavar, seq_depth);
                     locs.push(MatcherLoc::Token { token: close_token });
                 }
                 TokenTree::Sequence(_, seq) => {
@@ -162,7 +160,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match
                     let op = seq.kleene.op;
                     let idx_first = locs.len();
                     let idx_seq = idx_first - 1;
-                    inner(sess, &seq.tts, locs, next_metavar, seq_depth + 1);
+                    inner(&seq.tts, locs, next_metavar, seq_depth + 1);
 
                     if let Some(separator) = &seq.separator {
                         locs.push(MatcherLoc::SequenceSep { separator: separator.clone() });
@@ -197,7 +195,7 @@ pub(super) fn compute_locs(sess: &ParseSess, matcher: &[TokenTree]) -> Vec<Match
 
     let mut locs = vec![];
     let mut next_metavar = 0;
-    inner(sess, matcher, &mut locs, &mut next_metavar, /* seq_depth */ 0);
+    inner(matcher, &mut locs, &mut next_metavar, /* seq_depth */ 0);
 
     // A final entry is needed for eof.
     locs.push(MatcherLoc::Eof);
@@ -592,7 +590,7 @@ impl TtParser {
                 (_, 0) => {
                     // Dump all possible `next_mps` into `cur_mps` for the next iteration. Then
                     // process the next token.
-                    self.cur_mps.extend(self.next_mps.drain(..));
+                    self.cur_mps.append(&mut self.next_mps);
                     parser.to_mut().bump();
                 }
 
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index ef174c3c45e..2cfd6968acc 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -435,7 +435,7 @@ pub fn compile_declarative_macro(
         ),
     ];
     // Convert it into `MatcherLoc` form.
-    let argument_gram = mbe::macro_parser::compute_locs(&sess.parse_sess, &argument_gram);
+    let argument_gram = mbe::macro_parser::compute_locs(&argument_gram);
 
     let parser = Parser::new(&sess.parse_sess, body, true, rustc_parse::MACRO_ARGUMENTS);
     let mut tt_parser =
@@ -478,7 +478,7 @@ pub fn compile_declarative_macro(
                     )
                     .pop()
                     .unwrap();
-                    valid &= check_lhs_nt_follows(&sess.parse_sess, features, &def, &tt);
+                    valid &= check_lhs_nt_follows(&sess.parse_sess, &def, &tt);
                     return tt;
                 }
                 sess.parse_sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs")
@@ -540,7 +540,7 @@ pub fn compile_declarative_macro(
                 // Ignore the delimiters around the matcher.
                 match lhs {
                     mbe::TokenTree::Delimited(_, delimited) => {
-                        mbe::macro_parser::compute_locs(&sess.parse_sess, &delimited.tts)
+                        mbe::macro_parser::compute_locs(&delimited.tts)
                     }
                     _ => sess.parse_sess.span_diagnostic.span_bug(def.span, "malformed macro lhs"),
                 }
@@ -563,16 +563,11 @@ pub fn compile_declarative_macro(
     }))
 }
 
-fn check_lhs_nt_follows(
-    sess: &ParseSess,
-    features: &Features,
-    def: &ast::Item,
-    lhs: &mbe::TokenTree,
-) -> bool {
+fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool {
     // lhs is going to be like TokenTree::Delimited(...), where the
     // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
     if let mbe::TokenTree::Delimited(_, delimited) = lhs {
-        check_matcher(sess, features, def, &delimited.tts)
+        check_matcher(sess, def, &delimited.tts)
     } else {
         let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
         sess.span_diagnostic.span_err(lhs.span(), msg);
@@ -632,16 +627,11 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
     false
 }
 
-fn check_matcher(
-    sess: &ParseSess,
-    features: &Features,
-    def: &ast::Item,
-    matcher: &[mbe::TokenTree],
-) -> bool {
+fn check_matcher(sess: &ParseSess, def: &ast::Item, matcher: &[mbe::TokenTree]) -> bool {
     let first_sets = FirstSets::new(matcher);
     let empty_suffix = TokenSet::empty();
     let err = sess.span_diagnostic.err_count();
-    check_matcher_core(sess, features, def, &first_sets, matcher, &empty_suffix);
+    check_matcher_core(sess, def, &first_sets, matcher, &empty_suffix);
     err == sess.span_diagnostic.err_count()
 }
 
@@ -955,7 +945,6 @@ impl<'tt> TokenSet<'tt> {
 // see `FirstSets::new`.
 fn check_matcher_core<'tt>(
     sess: &ParseSess,
-    features: &Features,
     def: &ast::Item,
     first_sets: &FirstSets<'tt>,
     matcher: &'tt [mbe::TokenTree],
@@ -1008,7 +997,7 @@ fn check_matcher_core<'tt>(
                     token::CloseDelim(d.delim),
                     span.close,
                 ));
-                check_matcher_core(sess, features, def, first_sets, &d.tts, &my_suffix);
+                check_matcher_core(sess, def, first_sets, &d.tts, &my_suffix);
                 // don't track non NT tokens
                 last.replace_with_irrelevant();
 
@@ -1040,8 +1029,7 @@ fn check_matcher_core<'tt>(
                 // At this point, `suffix_first` is built, and
                 // `my_suffix` is some TokenSet that we can use
                 // for checking the interior of `seq_rep`.
-                let next =
-                    check_matcher_core(sess, features, def, first_sets, &seq_rep.tts, my_suffix);
+                let next = check_matcher_core(sess, def, first_sets, &seq_rep.tts, my_suffix);
                 if next.maybe_empty {
                     last.add_all(&next);
                 } else {
@@ -1114,7 +1102,7 @@ fn check_matcher_core<'tt>(
                             err.span_label(sp, format!("not allowed after `{}` fragments", kind));
 
                             if kind == NonterminalKind::PatWithOr
-                                && sess.edition == Edition::Edition2021
+                                && sess.edition.rust_2021()
                                 && next_token.is_token(&BinOp(token::BinOpToken::Or))
                             {
                                 let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index e37251c9c24..048039343a7 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -126,6 +126,8 @@ declare_features! (
     (accepted, default_type_params, "1.0.0", None, None),
     /// Allows `#[deprecated]` attribute.
     (accepted, deprecated, "1.9.0", Some(29935), None),
+    /// Allows `#[derive(Default)]` and `#[default]` on enums.
+    (accepted, derive_default_enum, "1.62.0", Some(86985), None),
     /// Allows the use of destructuring assignments.
     (accepted, destructuring_assignment, "1.59.0", Some(71126), None),
     /// Allows `#[doc(alias = "...")]`.
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 8340a0b360e..f3d4c8ab438 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -368,8 +368,6 @@ declare_features! (
     (active, deprecated_safe, "1.61.0", Some(94978), None),
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (active, deprecated_suggestion, "1.61.0", Some(94785), None),
-    /// Allows `#[derive(Default)]` and `#[default]` on enums.
-    (active, derive_default_enum, "1.56.0", Some(86985), None),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
     (active, doc_auto_cfg, "1.58.0", Some(43781), None),
     /// Allows `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index bfc537cfae2..940c4ecdcc2 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -11,7 +11,7 @@
 //! even if it is stabilized or removed, *do not remove it*. Instead, move the
 //! symbol to the `accepted` or `removed` modules respectively.
 
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(once_cell)]
 
 mod accepted;
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index ff8b13d3112..83193746432 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2425,8 +2425,12 @@ pub enum InlineAsmOperand<'hir> {
     Const {
         anon_const: AnonConst,
     },
-    Sym {
-        expr: Expr<'hir>,
+    SymFn {
+        anon_const: AnonConst,
+    },
+    SymStatic {
+        path: QPath<'hir>,
+        def_id: DefId,
     },
 }
 
@@ -2437,7 +2441,7 @@ impl<'hir> InlineAsmOperand<'hir> {
             | Self::Out { reg, .. }
             | Self::InOut { reg, .. }
             | Self::SplitInOut { reg, .. } => Some(reg),
-            Self::Const { .. } | Self::Sym { .. } => None,
+            Self::Const { .. } | Self::SymFn { .. } | Self::SymStatic { .. } => None,
         }
     }
 
@@ -2557,11 +2561,17 @@ impl FnRetTy<'_> {
 
 #[derive(Encodable, Debug, HashStable_Generic)]
 pub struct Mod<'hir> {
+    pub spans: ModSpans,
+    pub item_ids: &'hir [ItemId],
+}
+
+#[derive(Copy, Clone, Debug, HashStable_Generic, Encodable)]
+pub struct ModSpans {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
     /// to the last token in the external file.
-    pub inner: Span,
-    pub item_ids: &'hir [ItemId],
+    pub inner_span: Span,
+    pub inject_use_span: Span,
 }
 
 #[derive(Debug, HashStable_Generic)]
@@ -3059,8 +3069,8 @@ impl<'hir> OwnerNode<'hir> {
             OwnerNode::Item(Item { span, .. })
             | OwnerNode::ForeignItem(ForeignItem { span, .. })
             | OwnerNode::ImplItem(ImplItem { span, .. })
-            | OwnerNode::TraitItem(TraitItem { span, .. })
-            | OwnerNode::Crate(Mod { inner: span, .. }) => *span,
+            | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
+            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
         }
     }
 
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 1b40f3d390e..445b856e513 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -484,6 +484,9 @@ pub trait Visitor<'v>: Sized {
     fn visit_defaultness(&mut self, defaultness: &'v Defaultness) {
         walk_defaultness(self, defaultness);
     }
+    fn visit_inline_asm(&mut self, asm: &'v InlineAsm<'v>, id: HirId) {
+        walk_inline_asm(self, asm, id);
+    }
 }
 
 pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod<'v>, mod_hir_id: HirId) {
@@ -588,7 +591,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
         }
         ItemKind::GlobalAsm(asm) => {
             visitor.visit_id(item.hir_id());
-            walk_inline_asm(visitor, asm);
+            visitor.visit_inline_asm(asm, item.hir_id());
         }
         ItemKind::TyAlias(ref ty, ref generics) => {
             visitor.visit_id(item.hir_id());
@@ -648,12 +651,12 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
     }
 }
 
-fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>) {
-    for (op, _op_sp) in asm.operands {
+pub fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>, id: HirId) {
+    for (op, op_sp) in asm.operands {
         match op {
-            InlineAsmOperand::In { expr, .. }
-            | InlineAsmOperand::InOut { expr, .. }
-            | InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
+            InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
+                visitor.visit_expr(expr)
+            }
             InlineAsmOperand::Out { expr, .. } => {
                 if let Some(expr) = expr {
                     visitor.visit_expr(expr);
@@ -665,7 +668,9 @@ fn walk_inline_asm<'v, V: Visitor<'v>>(visitor: &mut V, asm: &'v InlineAsm<'v>)
                     visitor.visit_expr(out_expr);
                 }
             }
-            InlineAsmOperand::Const { anon_const } => visitor.visit_anon_const(anon_const),
+            InlineAsmOperand::Const { anon_const, .. }
+            | InlineAsmOperand::SymFn { anon_const, .. } => visitor.visit_anon_const(anon_const),
+            InlineAsmOperand::SymStatic { path, .. } => visitor.visit_qpath(path, id, *op_sp),
         }
     }
 }
@@ -1221,7 +1226,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
             walk_list!(visitor, visit_expr, optional_expression);
         }
         ExprKind::InlineAsm(ref asm) => {
-            walk_inline_asm(visitor, asm);
+            visitor.visit_inline_asm(asm, expression.hir_id);
         }
         ExprKind::Yield(ref subexpression, _) => {
             visitor.visit_expr(subexpression);
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index b8df1632144..9318ebb40b0 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -326,6 +326,8 @@ language_item_table! {
     Range,                   sym::Range,               range_struct,               Target::Struct,         GenericRequirement::None;
     RangeToInclusive,        sym::RangeToInclusive,    range_to_inclusive_struct,  Target::Struct,         GenericRequirement::None;
     RangeTo,                 sym::RangeTo,             range_to_struct,            Target::Struct,         GenericRequirement::None;
+
+    CStr,                    sym::CStr,                c_str,                      Target::Struct,         GenericRequirement::None;
 }
 
 pub enum GenericRequirement {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index b3042c61002..27f07a479b1 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1352,10 +1352,15 @@ impl<'a> State<'a> {
                     s.space();
                     s.print_anon_const(anon_const);
                 }
-                hir::InlineAsmOperand::Sym { expr } => {
-                    s.word("sym");
+                hir::InlineAsmOperand::SymFn { anon_const } => {
+                    s.word("sym_fn");
                     s.space();
-                    s.print_expr(expr);
+                    s.print_anon_const(anon_const);
+                }
+                hir::InlineAsmOperand::SymStatic { path, def_id: _ } => {
+                    s.word("sym_static");
+                    s.space();
+                    s.print_qpath(path, true);
                 }
             },
             AsmArg::Options(opts) => {
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 09b02ba74a8..58c309a5c52 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -63,9 +63,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// common state. Used in coherence.
     pub fn fork(&self) -> Self {
         Self {
-            tcx: self.tcx.clone(),
-            defining_use_anchor: self.defining_use_anchor.clone(),
-            in_progress_typeck_results: self.in_progress_typeck_results.clone(),
+            tcx: self.tcx,
+            defining_use_anchor: self.defining_use_anchor,
+            in_progress_typeck_results: self.in_progress_typeck_results,
             inner: self.inner.clone(),
             skip_leak_check: self.skip_leak_check.clone(),
             lexical_region_resolutions: self.lexical_region_resolutions.clone(),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index f25215fe813..f2dd4f5d5cb 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1448,6 +1448,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         mut values: Option<ValuePairs<'tcx>>,
         terr: &TypeError<'tcx>,
         swap_secondary_and_primary: bool,
+        force_label: bool,
     ) {
         let span = cause.span(self.tcx);
         debug!("note_type_err cause={:?} values={:?}, terr={:?}", cause, values, terr);
@@ -1623,7 +1624,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             TypeError::ObjectUnsafeCoercion(_) => {}
             _ => {
                 let mut label_or_note = |span: Span, msg: &str| {
-                    if &[span] == diag.span.primary_spans() {
+                    if force_label || &[span] == diag.span.primary_spans() {
                         diag.span_label(span, msg);
                     } else {
                         diag.span_note(span, msg);
@@ -2171,7 +2172,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 struct_span_err!(self.tcx.sess, span, E0644, "{}", failure_str)
             }
         };
-        self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false);
+        self.note_type_err(&mut diag, &trace.cause, None, Some(trace.values), terr, false, false);
         diag
     }
 
@@ -2765,7 +2766,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     }
 }
 
-enum FailureCode {
+pub enum FailureCode {
     Error0038(DefId),
     Error0317(&'static str),
     Error0580(&'static str),
@@ -2773,7 +2774,7 @@ enum FailureCode {
     Error0644(&'static str),
 }
 
-trait ObligationCauseExt<'tcx> {
+pub trait ObligationCauseExt<'tcx> {
     fn as_failure_code(&self, terr: &TypeError<'tcx>) -> FailureCode;
     fn as_requirement_str(&self) -> &'static str;
 }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2524bd78355..919b89396d6 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -385,8 +385,8 @@ impl<'tcx> ValuePairs<'tcx> {
 /// See the `error_reporting` module for more details.
 #[derive(Clone, Debug)]
 pub struct TypeTrace<'tcx> {
-    cause: ObligationCause<'tcx>,
-    values: ValuePairs<'tcx>,
+    pub cause: ObligationCause<'tcx>,
+    pub values: ValuePairs<'tcx>,
 }
 
 /// The origin of a `r1 <= r2` constraint.
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 08e005364ce..e859bcaec12 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -17,7 +17,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(extend_one)]
 #![feature(label_break_value)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 2a01b677e33..08987dff660 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -629,11 +629,15 @@ fn write_out_deps(
         });
         files.extend(extra_tracked_files);
 
-        if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
-            files.push(backend.to_string());
-        }
-
         if sess.binary_dep_depinfo() {
+            if let Some(ref backend) = sess.opts.debugging_opts.codegen_backend {
+                if backend.contains('.') {
+                    // If the backend name contain a `.`, it is the path to an external dynamic
+                    // library. If not, it is not a path.
+                    files.push(backend.to_string());
+                }
+            }
+
             boxed_resolver.borrow_mut().access(|resolver| {
                 for cnum in resolver.cstore().crates_untracked() {
                     let source = resolver.cstore().crate_source_untracked(cnum);
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 89ce307d12c..a42e3d5d957 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1110,8 +1110,6 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust,compile_fail
-    /// #![deny(unaligned_references)]
-    ///
     /// #[repr(packed)]
     /// pub struct Foo {
     ///     field1: u64,
@@ -1139,10 +1137,11 @@ declare_lint! {
     /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
     /// [issue #82523]: https://github.com/rust-lang/rust/issues/82523
     pub UNALIGNED_REFERENCES,
-    Warn,
+    Deny,
     "detects unaligned references to fields of packed structs",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>",
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
     };
     report_in_external_macro
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 51739df067f..3ed4396d1e9 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1835,3 +1835,9 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
   unwrap(C)->setDiagnosticHandler(std::make_unique<RustDiagnosticHandler>(
       DiagnosticHandlerCallback, DiagnosticHandlerContext, RemarkAllPasses, Passes));
 }
+
+extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
+  RawRustStringOstream OS(Str);
+  GlobalValue *GV = unwrap<GlobalValue>(V);
+  Mangler().getNameWithPrefix(OS, GV, true);
+}
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 3589860eb0e..b53ef816135 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -44,7 +44,7 @@ pub fn symbols(input: TokenStream) -> TokenStream {
 #[proc_macro]
 #[allow_internal_unstable(step_trait, rustc_attrs, trusted_step)]
 pub fn newtype_index(input: TokenStream) -> TokenStream {
-    newtype::newtype(input).into()
+    newtype::newtype(input)
 }
 
 decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index a9e3b55aeee..566d27212d0 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -417,6 +417,7 @@ impl<'a> CrateLoader<'a> {
 
         let crate_metadata = CrateMetadata::new(
             self.sess,
+            &self.cstore,
             metadata,
             crate_root,
             raw_proc_macros,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 3933a0d19a4..8d0e8467404 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -1,6 +1,6 @@
 // Decoding metadata from a single crate's metadata
 
-use crate::creader::CrateMetadataRef;
+use crate::creader::{CStore, CrateMetadataRef};
 use crate::rmeta::table::{FixedSizeEncoding, Table};
 use crate::rmeta::*;
 
@@ -1737,6 +1737,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 impl CrateMetadata {
     crate fn new(
         sess: &Session,
+        cstore: &CStore,
         blob: MetadataBlob,
         root: CrateRoot<'static>,
         raw_proc_macros: Option<&'static [ProcMacro]>,
@@ -1752,11 +1753,6 @@ impl CrateMetadata {
             .decode((&blob, sess))
             .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
             .collect();
-        let incoherent_impls = root
-            .incoherent_impls
-            .decode((&blob, sess))
-            .map(|incoherent_impls| (incoherent_impls.self_ty, incoherent_impls.impls))
-            .collect();
         let alloc_decoding_state =
             AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
         let dependencies = Lock::new(cnum_map.iter().cloned().collect());
@@ -1765,11 +1761,11 @@ impl CrateMetadata {
         // that does not copy any data. It just does some data verification.
         let def_path_hash_map = root.def_path_hash_map.decode(&blob);
 
-        CrateMetadata {
+        let mut cdata = CrateMetadata {
             blob,
             root,
             trait_impls,
-            incoherent_impls,
+            incoherent_impls: Default::default(),
             raw_proc_macros,
             source_map_import_info: OnceCell::new(),
             def_path_hash_map,
@@ -1786,7 +1782,17 @@ impl CrateMetadata {
             hygiene_context: Default::default(),
             def_key_cache: Default::default(),
             def_path_hash_cache: Default::default(),
-        }
+        };
+
+        // Need `CrateMetadataRef` to decode `DefId`s in simplified types.
+        cdata.incoherent_impls = cdata
+            .root
+            .incoherent_impls
+            .decode(CrateMetadataRef { cdata: &cdata, cstore })
+            .map(|incoherent_impls| (incoherent_impls.self_ty, incoherent_impls.impls))
+            .collect();
+
+        cdata
     }
 
     crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 65796fbc698..08cd40f38ef 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -584,7 +584,7 @@ impl<'hir> Map<'hir> {
             Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => {
                 (m, span, hir_id)
             }
-            Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id),
+            Some(OwnerNode::Crate(item)) => (item, item.spans.inner_span, hir_id),
             node => panic!("not a module: {:?}", node),
         }
     }
@@ -1012,7 +1012,7 @@ impl<'hir> Map<'hir> {
             Node::Infer(i) => i.span,
             Node::Visibility(v) => bug!("unexpected Visibility {:?}", v),
             Node::Local(local) => local.span,
-            Node::Crate(item) => item.inner,
+            Node::Crate(item) => item.spans.inner_span,
         };
         Some(span)
     }
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index fd2b5f5335f..199b5fa0314 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -30,7 +30,7 @@
 #![feature(bool_to_option)]
 #![feature(box_patterns)]
 #![feature(core_intrinsics)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(discriminant_kind)]
 #![feature(exhaustive_patterns)]
 #![feature(get_mut_unchecked)]
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 98da20baf02..af16e5e3fc8 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -362,12 +362,9 @@ impl ScopeTree {
         self.parent_map.get(&id).cloned().map(|(p, _)| p)
     }
 
-    /// Returns the lifetime of the local variable `var_id`
-    pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Scope {
-        self.var_map
-            .get(&var_id)
-            .cloned()
-            .unwrap_or_else(|| bug!("no enclosing scope for id {:?}", var_id))
+    /// Returns the lifetime of the local variable `var_id`, if any.
+    pub fn var_scope(&self, var_id: hir::ItemLocalId) -> Option<Scope> {
+        self.var_map.get(&var_id).cloned()
     }
 
     /// Returns the scope when the temp created by `expr_id` will be cleaned up.
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index db7e973fb62..49769b7ae3d 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2518,7 +2518,8 @@ pub enum Rvalue<'tcx> {
     /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
     ///   parameter may be a `usize` as well.
     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
-    ///   raw pointers, or function pointers of matching types and return a `bool`.
+    ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
+    ///   matching, up to the usual caveat of the lifetimes in function pointers.
     /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
     ///   same type and return a value of the same type as their LHS. Like in Rust, the RHS is
     ///   truncated as needed.
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index b17343d7692..e56efb8d497 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -526,7 +526,8 @@ pub enum InlineAsmOperand<'tcx> {
         span: Span,
     },
     SymFn {
-        expr: ExprId,
+        value: mir::ConstantKind<'tcx>,
+        span: Span,
     },
     SymStatic {
         def_id: DefId,
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index ef7becde69a..f57569522d5 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -138,8 +138,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
                 match op {
                     In { expr, reg: _ }
                     | Out { expr: Some(expr), reg: _, late: _ }
-                    | InOut { expr, reg: _, late: _ }
-                    | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]),
+                    | InOut { expr, reg: _, late: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
                     SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
                         visitor.visit_expr(&visitor.thir()[*in_expr]);
                         if let Some(out_expr) = out_expr {
@@ -148,6 +147,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
                     }
                     Out { expr: None, reg: _, late: _ }
                     | Const { value: _, span: _ }
+                    | SymFn { value: _, span: _ }
                     | SymStatic { def_id: _ } => {}
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
index 2c78c1f63d8..226456588e7 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs
@@ -191,7 +191,7 @@ impl<'tcx> Ty<'tcx> {
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> DefIdForest<'tcx> {
-        tcx.type_uninhabited_from(param_env.and(self)).clone()
+        tcx.type_uninhabited_from(param_env.and(self))
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 8b9b1847e7f..3a6e59db90b 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         }
                     };
 
-                Constant { span, user_ty: None, literal: literal.into() }
+                Constant { span, user_ty: None, literal }
             }
             ExprKind::NonHirLiteral { lit, user_ty } => {
                 let user_ty = user_ty.map(|user_ty| {
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index a8f623dbe46..a04ac338274 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -423,6 +423,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         }
                         thir::InlineAsmOperand::Const { value, span } => {
                             mir::InlineAsmOperand::Const {
+                                value: Box::new(Constant { span, user_ty: None, literal: value }),
+                            }
+                        }
+                        thir::InlineAsmOperand::SymFn { value, span } => {
+                            mir::InlineAsmOperand::SymFn {
                                 value: Box::new(Constant {
                                     span,
                                     user_ty: None,
@@ -430,9 +435,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                                 }),
                             }
                         }
-                        thir::InlineAsmOperand::SymFn { expr } => mir::InlineAsmOperand::SymFn {
-                            value: Box::new(this.as_constant(&this.thir[expr])),
-                        },
                         thir::InlineAsmOperand::SymStatic { def_id } => {
                             mir::InlineAsmOperand::SymStatic { def_id }
                         }
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 219d101aa7c..d45ae19752e 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -701,8 +701,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let local_id = self.var_local_id(var, for_guard);
         let source_info = self.source_info(span);
         self.cfg.push(block, Statement { source_info, kind: StatementKind::StorageLive(local_id) });
-        let region_scope = self.region_scope_tree.var_scope(var.local_id);
-        if schedule_drop {
+        // Altough there is almost always scope for given variable in corner cases
+        // like #92893 we might get variable with no scope.
+        if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) && schedule_drop{
             self.schedule_drop(span, region_scope, local_id, DropKind::Storage);
         }
         Place::from(local_id)
@@ -710,8 +711,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     crate fn schedule_drop_for_binding(&mut self, var: HirId, span: Span, for_guard: ForGuard) {
         let local_id = self.var_local_id(var, for_guard);
-        let region_scope = self.region_scope_tree.var_scope(var.local_id);
-        self.schedule_drop(span, region_scope, local_id, DropKind::Value);
+        if let Some(region_scope) = self.region_scope_tree.var_scope(var.local_id) {
+            self.schedule_drop(span, region_scope, local_id, DropKind::Value);
+        }
     }
 
     /// Visit all of the primary bindings in a patterns, that is, visit the
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 806c260d110..0e9e9869376 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -441,7 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     // Need to experiment.
                     user_ty: None,
 
-                    literal: method.into(),
+                    literal: method,
                 })),
                 args: vec![val, expect],
                 destination: Some((eq_result, eq_block)),
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 7ef33011234..f382f79af29 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -462,95 +462,56 @@ impl<'tcx> Cx<'tcx> {
                 operands: asm
                     .operands
                     .iter()
-                    .map(|(op, _op_sp)| {
-                        match *op {
-                            hir::InlineAsmOperand::In { reg, ref expr } => {
-                                InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) }
-                            }
-                            hir::InlineAsmOperand::Out { reg, late, ref expr } => {
-                                InlineAsmOperand::Out {
-                                    reg,
-                                    late,
-                                    expr: expr.as_ref().map(|expr| self.mirror_expr(expr)),
-                                }
-                            }
-                            hir::InlineAsmOperand::InOut { reg, late, ref expr } => {
-                                InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) }
-                            }
-                            hir::InlineAsmOperand::SplitInOut {
-                                reg,
-                                late,
-                                ref in_expr,
-                                ref out_expr,
-                            } => InlineAsmOperand::SplitInOut {
+                    .map(|(op, _op_sp)| match *op {
+                        hir::InlineAsmOperand::In { reg, ref expr } => {
+                            InlineAsmOperand::In { reg, expr: self.mirror_expr(expr) }
+                        }
+                        hir::InlineAsmOperand::Out { reg, late, ref expr } => {
+                            InlineAsmOperand::Out {
                                 reg,
                                 late,
-                                in_expr: self.mirror_expr(in_expr),
-                                out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)),
-                            },
-                            hir::InlineAsmOperand::Const { ref anon_const } => {
-                                let anon_const_def_id =
-                                    self.tcx.hir().local_def_id(anon_const.hir_id);
-                                let value = mir::ConstantKind::from_anon_const(
-                                    self.tcx,
-                                    anon_const_def_id,
-                                    self.param_env,
-                                );
-                                let span = self.tcx.hir().span(anon_const.hir_id);
-
-                                InlineAsmOperand::Const { value, span }
-                            }
-                            hir::InlineAsmOperand::Sym { ref expr } => {
-                                let hir::ExprKind::Path(ref qpath) = expr.kind else {
-                                    span_bug!(
-                                        expr.span,
-                                        "asm `sym` operand should be a path, found {:?}",
-                                        expr.kind
-                                    );
-                                };
-                                let temp_lifetime =
-                                    self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
-                                let res = self.typeck_results().qpath_res(qpath, expr.hir_id);
-                                let ty;
-                                match res {
-                                    Res::Def(DefKind::Fn, _) | Res::Def(DefKind::AssocFn, _) => {
-                                        ty = self.typeck_results().node_type(expr.hir_id);
-                                        let user_ty =
-                                            self.user_substs_applied_to_res(expr.hir_id, res);
-                                        InlineAsmOperand::SymFn {
-                                            expr: self.thir.exprs.push(Expr {
-                                                ty,
-                                                temp_lifetime,
-                                                span: expr.span,
-                                                kind: ExprKind::zero_sized_literal(user_ty),
-                                            }),
-                                        }
-                                    }
-
-                                    Res::Def(DefKind::Static(_), def_id) => {
-                                        InlineAsmOperand::SymStatic { def_id }
-                                    }
-
-                                    _ => {
-                                        self.tcx.sess.span_err(
-                                            expr.span,
-                                            "asm `sym` operand must point to a fn or static",
-                                        );
-
-                                        // Not a real fn, but we're not reaching codegen anyways...
-                                        ty = self.tcx.ty_error();
-                                        InlineAsmOperand::SymFn {
-                                            expr: self.thir.exprs.push(Expr {
-                                                ty,
-                                                temp_lifetime,
-                                                span: expr.span,
-                                                kind: ExprKind::zero_sized_literal(None),
-                                            }),
-                                        }
-                                    }
-                                }
+                                expr: expr.as_ref().map(|expr| self.mirror_expr(expr)),
                             }
                         }
+                        hir::InlineAsmOperand::InOut { reg, late, ref expr } => {
+                            InlineAsmOperand::InOut { reg, late, expr: self.mirror_expr(expr) }
+                        }
+                        hir::InlineAsmOperand::SplitInOut {
+                            reg,
+                            late,
+                            ref in_expr,
+                            ref out_expr,
+                        } => InlineAsmOperand::SplitInOut {
+                            reg,
+                            late,
+                            in_expr: self.mirror_expr(in_expr),
+                            out_expr: out_expr.as_ref().map(|expr| self.mirror_expr(expr)),
+                        },
+                        hir::InlineAsmOperand::Const { ref anon_const } => {
+                            let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
+                            let value = mir::ConstantKind::from_anon_const(
+                                self.tcx,
+                                anon_const_def_id,
+                                self.param_env,
+                            );
+                            let span = self.tcx.hir().span(anon_const.hir_id);
+
+                            InlineAsmOperand::Const { value, span }
+                        }
+                        hir::InlineAsmOperand::SymFn { ref anon_const } => {
+                            let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
+                            let value = mir::ConstantKind::from_anon_const(
+                                self.tcx,
+                                anon_const_def_id,
+                                self.param_env,
+                            );
+                            let span = self.tcx.hir().span(anon_const.hir_id);
+
+                            InlineAsmOperand::SymFn { value, span }
+                        }
+                        hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
+                            InlineAsmOperand::SymStatic { def_id }
+                        }
                     })
                     .collect(),
                 options: asm.options,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 44caa2ac076..58e484e413d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -844,7 +844,7 @@ fn non_exhaustive_match<'p, 'tcx>(
                     format!(
                         "{}{}{} => todo!()",
                         comma,
-                        snippet.strip_prefix(",").unwrap_or(&snippet),
+                        snippet.strip_prefix(',').unwrap_or(&snippet),
                         pattern
                     ),
                 ));
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index d1d6e7cfe2f..1b4510b6220 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -539,13 +539,13 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
             UnusedUnsafe::InUnsafeBlock(id) => {
                 db.span_label(
                     tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
-                    format!("because it's nested under this `unsafe` block"),
+                    "because it's nested under this `unsafe` block",
                 );
             }
             UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => {
                 db.span_label(
                     tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
-                    format!("because it's nested under this `unsafe` fn"),
+                    "because it's nested under this `unsafe` fn",
                 )
                 .note(
                     "this `unsafe` block does contain unsafe operations, \
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 2a659a97db5..fdb14e45d98 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -435,7 +435,27 @@ fn collect_items_rec<'tcx>(
                             // are supported. Therefore the value should not
                             // depend on any other items.
                         }
-                        _ => span_bug!(*op_sp, "invalid operand type for global_asm!"),
+                        hir::InlineAsmOperand::SymFn { anon_const } => {
+                            let def_id = tcx.hir().body_owner_def_id(anon_const.body).to_def_id();
+                            if let Ok(val) = tcx.const_eval_poly(def_id) {
+                                rustc_data_structures::stack::ensure_sufficient_stack(|| {
+                                    collect_const_value(tcx, val, &mut neighbors);
+                                });
+                            }
+                        }
+                        hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
+                            let instance = Instance::mono(tcx, *def_id);
+                            if should_codegen_locally(tcx, &instance) {
+                                trace!("collecting static {:?}", def_id);
+                                neighbors.push(dummy_spanned(MonoItem::Static(*def_id)));
+                            }
+                        }
+                        hir::InlineAsmOperand::In { .. }
+                        | hir::InlineAsmOperand::Out { .. }
+                        | hir::InlineAsmOperand::InOut { .. }
+                        | hir::InlineAsmOperand::SplitInOut { .. } => {
+                            span_bug!(*op_sp, "invalid operand type for global_asm!")
+                        }
                     }
                 }
             } else {
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 5ab412dc777..bfa13ce79ba 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -182,16 +182,7 @@ impl<'a> StringReader<'a> {
             }
             rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
                 if !terminated {
-                    let msg = match doc_style {
-                        Some(_) => "unterminated block doc-comment",
-                        None => "unterminated block comment",
-                    };
-                    let last_bpos = self.pos;
-                    self.sess.span_diagnostic.span_fatal_with_code(
-                        self.mk_sp(start, last_bpos),
-                        msg,
-                        error_code!(E0758),
-                    );
+                    self.report_unterminated_block_comment(start, doc_style);
                 }
 
                 // Skip non-doc comments
@@ -234,13 +225,13 @@ impl<'a> StringReader<'a> {
             rustc_lexer::TokenKind::InvalidIdent
                 // Do not recover an identifier with emoji if the codepoint is a confusable
                 // with a recoverable substitution token, like `âž–`.
-                if UNICODE_ARRAY
+                if !UNICODE_ARRAY
                     .iter()
-                    .find(|&&(c, _, _)| {
+                    .any(|&(c, _, _)| {
                         let sym = self.str_from(start);
                         sym.chars().count() == 1 && c == sym.chars().next().unwrap()
                     })
-                    .is_none() =>
+                     =>
             {
                 let sym = nfc_normalize(self.str_from(start));
                 let span = self.mk_sp(start, self.pos);
@@ -553,6 +544,55 @@ impl<'a> StringReader<'a> {
         err.emit()
     }
 
+    fn report_unterminated_block_comment(&self, start: BytePos, doc_style: Option<DocStyle>) {
+        let msg = match doc_style {
+            Some(_) => "unterminated block doc-comment",
+            None => "unterminated block comment",
+        };
+        let last_bpos = self.pos;
+        let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
+            self.mk_sp(start, last_bpos),
+            msg,
+            error_code!(E0758),
+        );
+        let mut nested_block_comment_open_idxs = vec![];
+        let mut last_nested_block_comment_idxs = None;
+        let mut content_chars = self.str_from(start).char_indices().peekable();
+
+        while let Some((idx, current_char)) = content_chars.next() {
+            match content_chars.peek() {
+                Some((_, '*')) if current_char == '/' => {
+                    nested_block_comment_open_idxs.push(idx);
+                }
+                Some((_, '/')) if current_char == '*' => {
+                    last_nested_block_comment_idxs =
+                        nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
+                }
+                _ => {}
+            };
+        }
+
+        if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs {
+            err.span_label(self.mk_sp(start, start + BytePos(2)), msg)
+                .span_label(
+                    self.mk_sp(
+                        start + BytePos(nested_open_idx as u32),
+                        start + BytePos(nested_open_idx as u32 + 2),
+                    ),
+                    "...as last nested comment starts here, maybe you want to close this instead?",
+                )
+                .span_label(
+                    self.mk_sp(
+                        start + BytePos(nested_close_idx as u32),
+                        start + BytePos(nested_close_idx as u32 + 2),
+                    ),
+                    "...and last nested comment terminates here.",
+                );
+        }
+
+        err.emit();
+    }
+
     // RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
     // using a (unknown) prefix is an error. In earlier editions, however, they
     // only result in a (allowed by default) lint, and are treated as regular
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index c777074df46..261ea0b4deb 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -158,7 +158,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
     #[allow(dead_code)] // FIXME(81658): should be used + lint reinstated after #83171 relands.
     fn check_for_self_assign(&mut self, assign: &'tcx hir::Expr<'tcx>) {
         fn check_for_self_assign_helper<'tcx>(
-            tcx: TyCtxt<'tcx>,
             typeck_results: &'tcx ty::TypeckResults<'tcx>,
             lhs: &'tcx hir::Expr<'tcx>,
             rhs: &'tcx hir::Expr<'tcx>,
@@ -177,7 +176,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 }
                 (hir::ExprKind::Field(lhs_l, ident_l), hir::ExprKind::Field(lhs_r, ident_r)) => {
                     if ident_l == ident_r {
-                        return check_for_self_assign_helper(tcx, typeck_results, lhs_l, lhs_r);
+                        return check_for_self_assign_helper(typeck_results, lhs_l, lhs_r);
                     }
                     return false;
                 }
@@ -188,7 +187,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
         }
 
         if let hir::ExprKind::Assign(lhs, rhs, _) = assign.kind {
-            if check_for_self_assign_helper(self.tcx, self.typeck_results(), lhs, rhs)
+            if check_for_self_assign_helper(self.typeck_results(), lhs, rhs)
                 && !assign.span.from_expansion()
             {
                 let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..));
@@ -537,6 +536,10 @@ impl<'v, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'tcx> {
                         .insert(self.tcx.hir().local_def_id(ctor_hir_id), item.def_id);
                 }
             }
+            hir::ItemKind::GlobalAsm(_) => {
+                // global_asm! is always live.
+                self.worklist.push(item.def_id);
+            }
             _ => (),
         }
     }
diff --git a/compiler/rustc_passes/src/intrinsicck.rs b/compiler/rustc_passes/src/intrinsicck.rs
index 027eac16bad..7028fc44126 100644
--- a/compiler/rustc_passes/src/intrinsicck.rs
+++ b/compiler/rustc_passes/src/intrinsicck.rs
@@ -1,3 +1,4 @@
+use hir::intravisit::walk_inline_asm;
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_data_structures::stable_set::FxHashSet;
 use rustc_errors::struct_span_err;
@@ -483,7 +484,10 @@ impl<'tcx> ExprVisitor<'tcx> {
                         );
                     }
                 }
-                hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {}
+                // These are checked in ItemVisitor.
+                hir::InlineAsmOperand::Const { .. }
+                | hir::InlineAsmOperand::SymFn { .. }
+                | hir::InlineAsmOperand::SymStatic { .. } => {}
             }
         }
     }
@@ -498,6 +502,42 @@ impl<'tcx> Visitor<'tcx> for ItemVisitor<'tcx> {
         ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body);
         self.visit_body(body);
     }
+
+    fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) {
+        for (op, op_sp) in asm.operands.iter() {
+            match *op {
+                // These are checked in ExprVisitor.
+                hir::InlineAsmOperand::In { .. }
+                | hir::InlineAsmOperand::Out { .. }
+                | hir::InlineAsmOperand::InOut { .. }
+                | hir::InlineAsmOperand::SplitInOut { .. } => {}
+                // No special checking is needed for these:
+                // - Typeck has checked that Const operands are integers.
+                // - AST lowering guarantees that SymStatic points to a static.
+                hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::SymStatic { .. } => {}
+                // Check that sym actually points to a function. Later passes
+                // depend on this.
+                hir::InlineAsmOperand::SymFn { anon_const } => {
+                    let ty = self.tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
+                    match ty.kind() {
+                        ty::Never | ty::Error(_) => {}
+                        ty::FnDef(..) => {}
+                        _ => {
+                            let mut err =
+                                self.tcx.sess.struct_span_err(*op_sp, "invalid `sym` operand");
+                            err.span_label(
+                                self.tcx.hir().span(anon_const.body.hir_id),
+                                &format!("is {} `{}`", ty.kind().article(), ty),
+                            );
+                            err.help("`sym` operands must refer to either a function or a static");
+                            err.emit();
+                        }
+                    };
+                }
+            }
+        }
+        walk_inline_asm(self, asm, id);
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for ExprVisitor<'tcx> {
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 7298aba7e87..99ea73fe2fe 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -1043,7 +1043,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     match op {
                         hir::InlineAsmOperand::In { .. }
                         | hir::InlineAsmOperand::Const { .. }
-                        | hir::InlineAsmOperand::Sym { .. } => {}
+                        | hir::InlineAsmOperand::SymFn { .. }
+                        | hir::InlineAsmOperand::SymStatic { .. } => {}
                         hir::InlineAsmOperand::Out { expr, .. } => {
                             if let Some(expr) = expr {
                                 succ = self.write_place(expr, succ, ACC_WRITE);
@@ -1064,8 +1065,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 let mut succ = succ;
                 for (op, _op_sp) in asm.operands.iter().rev() {
                     match op {
-                        hir::InlineAsmOperand::In { expr, .. }
-                        | hir::InlineAsmOperand::Sym { expr, .. } => {
+                        hir::InlineAsmOperand::In { expr, .. } => {
                             succ = self.propagate_through_expr(expr, succ)
                         }
                         hir::InlineAsmOperand::Out { expr, .. } => {
@@ -1082,7 +1082,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                             }
                             succ = self.propagate_through_expr(in_expr, succ);
                         }
-                        hir::InlineAsmOperand::Const { .. } => {}
+                        hir::InlineAsmOperand::Const { .. }
+                        | hir::InlineAsmOperand::SymFn { .. }
+                        | hir::InlineAsmOperand::SymStatic { .. } => {}
                     }
                 }
                 succ
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index af78fd5a6f2..e85720952da 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -252,7 +252,9 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
             .operands
             .iter()
             .filter_map(|&(ref op, op_sp)| match op {
-                InlineAsmOperand::Const { .. } | InlineAsmOperand::Sym { .. } => None,
+                InlineAsmOperand::Const { .. }
+                | InlineAsmOperand::SymFn { .. }
+                | InlineAsmOperand::SymStatic { .. } => None,
                 InlineAsmOperand::In { .. }
                 | InlineAsmOperand::Out { .. }
                 | InlineAsmOperand::InOut { .. }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index ff033cbb572..01ba9e35c24 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -133,9 +133,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
 
             // `Deprecation` is just two pointers, no need to intern it
-            let depr_entry = DeprecationEntry::local(depr.clone(), def_id);
+            let depr_entry = DeprecationEntry::local(*depr, def_id);
             self.index.depr_map.insert(def_id, depr_entry);
-        } else if let Some(parent_depr) = self.parent_depr.clone() {
+        } else if let Some(parent_depr) = self.parent_depr {
             if inherit_deprecation.yes() {
                 is_deprecated = true;
                 info!("tagging child {:?} as deprecated from parent", def_id);
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index d979311171b..f3b8c1e266c 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1012,6 +1012,12 @@ impl<'a> Resolver<'a> {
                 err.span_label(trait_item_span, "item in trait");
                 err
             }
+            ResolutionError::InvalidAsmSym => {
+                let mut err = self.session.struct_span_err(span, "invalid `sym` operand");
+                err.span_label(span, &format!("is a local variable"));
+                err.help("`sym` operands must refer to either a function or a static");
+                err
+            }
         }
     }
 
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 25ab3f7dacf..24b6d656981 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1182,6 +1182,12 @@ impl<'a> Resolver<'a> {
                             }
                             return Res::Err;
                         }
+                        InlineAsmSymRibKind => {
+                            if let Some(span) = finalize {
+                                self.report_error(span, InvalidAsmSym);
+                            }
+                            return Res::Err;
+                        }
                     }
                 }
                 if let Some((span, res_err)) = res_err {
@@ -1242,6 +1248,22 @@ impl<'a> Resolver<'a> {
                             }
                             return Res::Err;
                         }
+                        InlineAsmSymRibKind => {
+                            let features = self.session.features_untracked();
+                            if !features.generic_const_exprs {
+                                if let Some(span) = finalize {
+                                    self.report_error(
+                                        span,
+                                        ResolutionError::ParamInNonTrivialAnonConst {
+                                            name: rib_ident.name,
+                                            is_type: true,
+                                        },
+                                    );
+                                }
+                                return Res::Err;
+                            }
+                            continue;
+                        }
                     };
 
                     if let Some(span) = finalize {
@@ -1306,6 +1328,22 @@ impl<'a> Resolver<'a> {
                             }
                             return Res::Err;
                         }
+                        InlineAsmSymRibKind => {
+                            let features = self.session.features_untracked();
+                            if !features.generic_const_exprs {
+                                if let Some(span) = finalize {
+                                    self.report_error(
+                                        span,
+                                        ResolutionError::ParamInNonTrivialAnonConst {
+                                            name: rib_ident.name,
+                                            is_type: false,
+                                        },
+                                    );
+                                }
+                                return Res::Err;
+                            }
+                            continue;
+                        }
                     };
 
                     // This was an attempt to use a const parameter outside its scope.
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index aab0c1f9771..01dc727737a 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -310,18 +310,23 @@ impl<'a> Resolver<'a> {
         t
     }
 
-    // Define a "dummy" resolution containing a Res::Err as a placeholder for a
-    // failed resolution
+    // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed resolution,
+    // also mark such failed imports as used to avoid duplicate diagnostics.
     fn import_dummy_binding(&mut self, import: &'a Import<'a>) {
-        if let ImportKind::Single { target, .. } = import.kind {
+        if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
+            if target_bindings.iter().any(|binding| binding.get().is_some()) {
+                return; // Has resolution, do not create the dummy binding
+            }
             let dummy_binding = self.dummy_binding;
             let dummy_binding = self.import(dummy_binding, import);
             self.per_ns(|this, ns| {
                 let key = this.new_key(target, ns);
                 let _ = this.try_define(import.parent_scope.module, key, dummy_binding);
             });
-            // Consider erroneous imports used to avoid duplicate diagnostics.
             self.record_use(target, dummy_binding, false);
+        } else if import.imported_module.get().is_none() {
+            import.used.set(true);
+            self.used_imports.insert(import.id);
         }
     }
 }
@@ -386,7 +391,13 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             .map(|i| (false, i))
             .chain(indeterminate_imports.into_iter().map(|i| (true, i)))
         {
-            if let Some(err) = self.finalize_import(import) {
+            let unresolved_import_error = self.finalize_import(import);
+
+            // If this import is unresolved then create a dummy import
+            // resolution for it so that later resolve stages won't complain.
+            self.r.import_dummy_binding(import);
+
+            if let Some(err) = unresolved_import_error {
                 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
                     if source.name == kw::SelfLower {
                         // Silence `unresolved import` error if E0429 is already emitted
@@ -396,9 +407,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     }
                 }
 
-                // If the error is a single failed import then create a "fake" import
-                // resolution for it so that later resolve stages won't complain.
-                self.r.import_dummy_binding(import);
                 if prev_root_id.as_u32() != 0
                     && prev_root_id.as_u32() != import.root_id.as_u32()
                     && !errors.is_empty()
@@ -418,8 +426,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     prev_root_id = import.root_id;
                 }
             } else if is_indeterminate {
-                // Consider erroneous imports used to avoid duplicate diagnostics.
-                self.r.used_imports.insert(import.id);
                 let path = import_path_to_string(
                     &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
                     &import.kind,
@@ -553,26 +559,23 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     Err(Undetermined) => indeterminate = true,
                     // Don't update the resolution, because it was never added.
                     Err(Determined) if target.name == kw::Underscore => {}
-                    Err(Determined) => {
+                    Ok(binding) if binding.is_importable() => {
+                        let imported_binding = this.import(binding, import);
+                        target_bindings[ns].set(Some(imported_binding));
+                        this.define(parent, target, ns, imported_binding);
+                    }
+                    source_binding @ (Ok(..) | Err(Determined)) => {
+                        if source_binding.is_ok() {
+                            let msg = format!("`{}` is not directly importable", target);
+                            struct_span_err!(this.session, import.span, E0253, "{}", &msg)
+                                .span_label(import.span, "cannot be imported directly")
+                                .emit();
+                        }
                         let key = this.new_key(target, ns);
                         this.update_resolution(parent, key, |_, resolution| {
                             resolution.single_imports.remove(&Interned::new_unchecked(import));
                         });
                     }
-                    Ok(binding) if !binding.is_importable() => {
-                        let msg = format!("`{}` is not directly importable", target);
-                        struct_span_err!(this.session, import.span, E0253, "{}", &msg)
-                            .span_label(import.span, "cannot be imported directly")
-                            .emit();
-                        // Do not import this illegal binding. Import a dummy binding and pretend
-                        // everything is fine
-                        this.import_dummy_binding(import);
-                    }
-                    Ok(binding) => {
-                        let imported_binding = this.import(binding, import);
-                        target_bindings[ns].set(Some(imported_binding));
-                        this.define(parent, target, ns, imported_binding);
-                    }
                 }
             }
         });
@@ -605,10 +608,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
         );
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
         import.vis.set(orig_vis);
-        if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
-            // Consider erroneous imports used to avoid duplicate diagnostics.
-            self.r.used_imports.insert(import.id);
-        }
         let module = match path_res {
             PathResult::Module(module) => {
                 // Consistency checks, analogous to `finalize_macro_resolutions`.
@@ -872,7 +871,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 })
             } else {
                 // `resolve_ident_in_module` reported a privacy error.
-                self.r.import_dummy_binding(import);
                 None
             };
         }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f27b60e889f..763f31622bc 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -140,6 +140,10 @@ crate enum RibKind<'a> {
     /// We are inside of the type of a const parameter. Can't refer to any
     /// parameters.
     ConstParamTyRibKind,
+
+    /// We are inside a `sym` inline assembly operand. Can only refer to
+    /// globals.
+    InlineAsmSymRibKind,
 }
 
 impl RibKind<'_> {
@@ -153,7 +157,8 @@ impl RibKind<'_> {
             | ConstantItemRibKind(..)
             | ModuleRibKind(_)
             | MacroDefinition(_)
-            | ConstParamTyRibKind => false,
+            | ConstParamTyRibKind
+            | InlineAsmSymRibKind => false,
             AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true,
         }
     }
@@ -722,6 +727,23 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
         visit::walk_where_predicate(self, p);
         self.diagnostic_metadata.current_where_predicate = previous_value;
     }
+
+    fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
+        // This is similar to the code for AnonConst.
+        self.with_rib(ValueNS, InlineAsmSymRibKind, |this| {
+            this.with_rib(TypeNS, InlineAsmSymRibKind, |this| {
+                this.with_label_rib(InlineAsmSymRibKind, |this| {
+                    this.smart_resolve_path(
+                        sym.id,
+                        sym.qself.as_ref(),
+                        &sym.path,
+                        PathSource::Expr(None),
+                    );
+                    visit::walk_inline_asm_sym(this, sym);
+                });
+            })
+        });
+    }
 }
 
 impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
@@ -909,7 +931,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 | ConstantItemRibKind(..)
                 | ModuleRibKind(..)
                 | ForwardGenericParamBanRibKind
-                | ConstParamTyRibKind => {
+                | ConstParamTyRibKind
+                | InlineAsmSymRibKind => {
                     return false;
                 }
             }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index b2c7a4d18de..0335c40d70d 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -260,6 +260,8 @@ enum ResolutionError<'a> {
         trait_item_span: Span,
         code: rustc_errors::DiagnosticId,
     },
+    /// Inline asm `sym` operand must refer to a `fn` or `static`.
+    InvalidAsmSym,
 }
 
 enum VisResolutionError<'a> {
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 1eb575e0db2..22d0a20395e 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -1095,11 +1095,11 @@ impl<'tcx> DumpVisitor<'tcx> {
 
         let sm = self.tcx.sess.source_map();
         let krate_mod = self.tcx.hir().root_module();
-        let filename = sm.span_to_filename(krate_mod.inner);
+        let filename = sm.span_to_filename(krate_mod.spans.inner_span);
         let data_id = id_from_hir_id(id, &self.save_ctxt);
         let children =
             krate_mod.item_ids.iter().map(|i| id_from_def_id(i.def_id.to_def_id())).collect();
-        let span = self.span_from_span(krate_mod.inner);
+        let span = self.span_from_span(krate_mod.spans.inner_span);
         let attrs = self.tcx.hir().attrs(id);
 
         self.dumper.dump_def(
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index 08a990c65ff..102268c6ca3 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -282,7 +282,7 @@ impl<'tcx> SaveContext<'tcx> {
                 let qualname = format!("::{}", self.tcx.def_path_str(def_id));
 
                 let sm = self.tcx.sess.source_map();
-                let filename = sm.span_to_filename(m.inner);
+                let filename = sm.span_to_filename(m.spans.inner_span);
 
                 filter!(self.span_utils, item.ident.span);
 
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 3151b025fff..054b18b6b63 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,7 +1,7 @@
 #![feature(crate_visibility_modifier)]
-#![feature(derive_default_enum)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(let_else)]
 #![feature(min_specialization)]
 #![feature(never_type)]
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index c461b26788a..b4548129689 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -238,7 +238,7 @@ impl Session {
             }
             diag.emit();
             // If we should err, make sure we did.
-            if must_err && !self.has_errors().is_some() {
+            if must_err && self.has_errors().is_none() {
                 // We have skipped a feature gate, and not run into other errors... reject.
                 self.err(
                     "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \
@@ -991,6 +991,11 @@ impl Session {
         self.opts.edition >= Edition::Edition2021
     }
 
+    /// Are we allowed to use features from the Rust 2024 edition?
+    pub fn rust_2024(&self) -> bool {
+        self.opts.edition >= Edition::Edition2024
+    }
+
     pub fn edition(&self) -> Edition {
         self.opts.edition
     }
diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs
index 511c2e86626..065d3660e50 100644
--- a/compiler/rustc_span/src/edition.rs
+++ b/compiler/rustc_span/src/edition.rs
@@ -22,13 +22,15 @@ pub enum Edition {
     Edition2018,
     /// The 2021 edition
     Edition2021,
+    /// The 2024 edition
+    Edition2024,
 }
 
 // Must be in order from oldest to newest.
 pub const ALL_EDITIONS: &[Edition] =
-    &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021];
+    &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024];
 
-pub const EDITION_NAME_LIST: &str = "2015|2018|2021";
+pub const EDITION_NAME_LIST: &str = "2015|2018|2021|2024";
 
 pub const DEFAULT_EDITION: Edition = Edition::Edition2015;
 
@@ -40,6 +42,7 @@ impl fmt::Display for Edition {
             Edition::Edition2015 => "2015",
             Edition::Edition2018 => "2018",
             Edition::Edition2021 => "2021",
+            Edition::Edition2024 => "2024",
         };
         write!(f, "{}", s)
     }
@@ -51,6 +54,7 @@ impl Edition {
             Edition::Edition2015 => "rust_2015_compatibility",
             Edition::Edition2018 => "rust_2018_compatibility",
             Edition::Edition2021 => "rust_2021_compatibility",
+            Edition::Edition2024 => "rust_2024_compatibility",
         }
     }
 
@@ -59,6 +63,7 @@ impl Edition {
             Edition::Edition2015 => sym::rust_2015_preview,
             Edition::Edition2018 => sym::rust_2018_preview,
             Edition::Edition2021 => sym::rust_2021_preview,
+            Edition::Edition2024 => sym::rust_2024_preview,
         }
     }
 
@@ -67,8 +72,28 @@ impl Edition {
             Edition::Edition2015 => true,
             Edition::Edition2018 => true,
             Edition::Edition2021 => true,
+            Edition::Edition2024 => false,
         }
     }
+
+    pub fn rust_2015(&self) -> bool {
+        *self == Edition::Edition2015
+    }
+
+    /// Are we allowed to use features from the Rust 2018 edition?
+    pub fn rust_2018(&self) -> bool {
+        *self >= Edition::Edition2018
+    }
+
+    /// Are we allowed to use features from the Rust 2021 edition?
+    pub fn rust_2021(&self) -> bool {
+        *self >= Edition::Edition2021
+    }
+
+    /// Are we allowed to use features from the Rust 2024 edition?
+    pub fn rust_2024(&self) -> bool {
+        *self >= Edition::Edition2024
+    }
 }
 
 impl FromStr for Edition {
@@ -78,6 +103,7 @@ impl FromStr for Edition {
             "2015" => Ok(Edition::Edition2015),
             "2018" => Ok(Edition::Edition2018),
             "2021" => Ok(Edition::Edition2021),
+            "2024" => Ok(Edition::Edition2024),
             _ => Err(()),
         }
     }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 45b0e0c2dd1..b132c0a2132 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -684,6 +684,11 @@ impl Span {
         self.edition() >= edition::Edition::Edition2021
     }
 
+    #[inline]
+    pub fn rust_2024(self) -> bool {
+        self.edition() >= edition::Edition::Edition2024
+    }
+
     /// Returns the source callee.
     ///
     /// Returns `None` if the supplied span has no expansion trace,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index dc4d10f699c..d9bada29589 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1149,6 +1149,8 @@ symbols! {
         rust_2018_preview,
         rust_2021,
         rust_2021_preview,
+        rust_2024,
+        rust_2024_preview,
         rust_begin_unwind,
         rust_eh_catch_typeinfo,
         rust_eh_personality,
@@ -1245,6 +1247,7 @@ symbols! {
         simd,
         simd_add,
         simd_and,
+        simd_arith_offset,
         simd_as,
         simd_bitmask,
         simd_cast,
diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs
index 5a92ebdd9e8..cc3a0a69999 100644
--- a/compiler/rustc_target/src/abi/call/sparc64.rs
+++ b/compiler/rustc_target/src/abi/call/sparc64.rs
@@ -113,11 +113,11 @@ where
             data = arg_scalar(cx, &scalar, offset, data);
         }
         abi::Abi::Aggregate { .. } => {
-            for i in 0..layout.fields.count().clone() {
+            for i in 0..layout.fields.count() {
                 if offset < layout.fields.offset(i) {
                     offset = layout.fields.offset(i);
                 }
-                data = parse_structure(cx, layout.field(cx, i).clone(), data.clone(), offset);
+                data = parse_structure(cx, layout.field(cx, i), data.clone(), offset);
             }
         }
         _ => {
@@ -161,7 +161,7 @@ where
 
             let mut data = parse_structure(
                 cx,
-                arg.layout.clone(),
+                arg.layout,
                 Sdata {
                     prefix: [None; 8],
                     prefix_index: 0,
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 7523b844101..2ae7f34a91e 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -16,7 +16,7 @@
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(crate_visibility_modifier)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![feature(label_break_value)]
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 0cb70de2415..50e4fafdd6c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1654,7 +1654,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
                     }),
                 _ => None,
             };
-            self.note_type_err(&mut diag, &obligation.cause, secondary_span, values, err, true);
+            self.note_type_err(
+                &mut diag,
+                &obligation.cause,
+                secondary_span,
+                values,
+                err,
+                true,
+                false,
+            );
             self.note_obligation_cause(&mut diag, obligation);
             diag.emit();
         });
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index ead1f0126c4..7485c082f4e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2724,9 +2724,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 &format!(
                     "consider annotating `{}` with `#[derive({})]`",
                     trait_pred.skip_binder().self_ty(),
-                    diagnostic_name.to_string(),
+                    diagnostic_name,
                 ),
-                format!("#[derive({})]\n", diagnostic_name.to_string()),
+                format!("#[derive({})]\n", diagnostic_name),
                 Applicability::MaybeIncorrect,
             );
         }
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index 38be28c07ff..ce0e0a21ff5 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -258,7 +258,7 @@ impl<'tcx> OnUnimplementedDirective {
                 enclosing_scope = Some(enclosing_scope_.clone());
             }
 
-            append_const_msg = command.append_const_msg.clone();
+            append_const_msg = command.append_const_msg;
         }
 
         OnUnimplementedNote {
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 4734a843a9c..8ba390c71db 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -19,6 +19,7 @@ use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
 use crate::traits::error_reporting::InferCtxtExt as _;
+use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::select::ProjectionMatchesProjection;
 use rustc_data_structures::sso::SsoHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -1562,7 +1563,16 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                     // type parameters, opaques, and unnormalized projections have pointer
                     // metadata if they're known (e.g. by the param_env) to be sized
                     ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
-                        if tail.is_sized(selcx.tcx().at(obligation.cause.span), obligation.param_env) =>
+                        if selcx.infcx().predicate_must_hold_modulo_regions(
+                            &obligation.with(
+                                ty::Binder::dummy(ty::TraitRef::new(
+                                    selcx.tcx().require_lang_item(LangItem::Sized, None),
+                                    selcx.tcx().mk_substs_trait(self_ty, &[]),
+                                ))
+                                .without_const()
+                                .to_predicate(selcx.tcx()),
+                            ),
+                        ) =>
                     {
                         true
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 06f58240992..dbb6c54fcd9 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -231,8 +231,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid
             // emitting additional spurious errors, since we're guaranteed
             // to have emitted at least one.
-            if stack.obligation.references_error() {
-                debug!("no results for error type, treating as ambiguous");
+            if stack.obligation.predicate.references_error() {
+                debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous");
                 return Ok(None);
             }
             return Err(Unimplemented);
diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs
index 26f7c267ed1..1c7e7c935c4 100644
--- a/compiler/rustc_typeck/src/check/_match.rs
+++ b/compiler/rustc_typeck/src/check/_match.rs
@@ -260,10 +260,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             &mut |err| {
                 if let Some((span, msg)) = &ret_reason {
                     err.span_label(*span, msg.as_str());
-                } else if let ExprKind::Block(block, _) = &then_expr.kind {
-                    if let Some(expr) = &block.expr {
-                        err.span_label(expr.span, "found here".to_string());
-                    }
+                } else if let ExprKind::Block(block, _) = &then_expr.kind
+                    && let Some(expr) = &block.expr
+                {
+                    err.span_label(expr.span, "found here".to_string());
                 }
                 err.note("`if` expressions without `else` evaluate to `()`");
                 err.help("consider adding an `else` block that evaluates to the expected type");
@@ -293,7 +293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| {
                         let span = fn_decl.output.span();
                         let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
-                        Some((span, format!("expected `{}` because of this return type", snippet)))
+                        Some((span, format!("expected `{snippet}` because of this return type")))
                     });
                 }
             }
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 2a5cf03e9d0..580fb7c3e0f 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -43,7 +43,7 @@ pub fn check_legal_trait_for_method_call(
         let (sp, suggestion) = receiver
             .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
             .filter(|snippet| !snippet.is_empty())
-            .map(|snippet| (expr_span, format!("drop({})", snippet)))
+            .map(|snippet| (expr_span, format!("drop({snippet})")))
             .unwrap_or_else(|| (span, "drop".to_string()));
 
         err.span_suggestion(
@@ -315,17 +315,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             hir::ExprKind::Tup(exp),
             hir::ExprKind::Call(_, args),
         ) = (parent_node, &callee_expr.kind, &call_expr.kind)
+            && args.len() == exp.len()
         {
-            if args.len() == exp.len() {
-                let start = callee_expr.span.shrink_to_hi();
-                err.span_suggestion(
-                    start,
-                    "consider separating array elements with a comma",
-                    ",".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-                return true;
-            }
+            let start = callee_expr.span.shrink_to_hi();
+            err.span_suggestion(
+                start,
+                "consider separating array elements with a comma",
+                ",".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+            return true;
         }
         false
     }
@@ -373,15 +372,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ref t => {
                 let mut unit_variant = None;
                 let mut removal_span = call_expr.span;
-                if let ty::Adt(adt_def, ..) = t {
-                    if adt_def.is_enum() {
-                        if let hir::ExprKind::Call(expr, _) = call_expr.kind {
-                            removal_span =
-                                expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
-                            unit_variant =
-                                self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
-                        }
-                    }
+                if let ty::Adt(adt_def, ..) = t
+                    && adt_def.is_enum()
+                    && let hir::ExprKind::Call(expr, _) = call_expr.kind
+                {
+                    removal_span =
+                        expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi());
+                    unit_variant =
+                        self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
                 }
 
                 let callee_ty = self.resolve_vars_if_possible(callee_ty);
@@ -392,8 +390,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     E0618,
                     "expected function, found {}",
                     match unit_variant {
-                        Some(ref path) => format!("enum variant `{}`", path),
-                        None => format!("`{}`", callee_ty),
+                        Some(ref path) => format!("enum variant `{path}`"),
+                        None => format!("`{callee_ty}`"),
                     }
                 );
 
@@ -408,8 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     err.span_suggestion_verbose(
                         removal_span,
                         &format!(
-                            "`{}` is a unit variant, you need to write it without the parentheses",
-                            path
+                            "`{path}` is a unit variant, you need to write it without the parentheses",
                         ),
                         String::new(),
                         Applicability::MachineApplicable,
@@ -452,14 +449,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let Some(span) = self.tcx.hir().res_span(def) {
                     let callee_ty = callee_ty.to_string();
                     let label = match (unit_variant, inner_callee_path) {
-                        (Some(path), _) => Some(format!("`{}` defined here", path)),
+                        (Some(path), _) => Some(format!("`{path}` defined here")),
                         (_, Some(hir::QPath::Resolved(_, path))) => self
                             .tcx
                             .sess
                             .source_map()
                             .span_to_snippet(path.span)
                             .ok()
-                            .map(|p| format!("`{}` defined here returns `{}`", p, callee_ty)),
+                            .map(|p| format!("`{p}` defined here returns `{callee_ty}`")),
                         _ => {
                             match def {
                                 // Emit a different diagnostic for local variables, as they are not
@@ -475,7 +472,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                         self.tcx.def_path_str(def_id),
                                     ))
                                 }
-                                _ => Some(format!("`{}` defined here", callee_ty)),
+                                _ => Some(format!("`{callee_ty}` defined here")),
                             }
                         }
                     };
diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs
index 47292b3e339..049940d19a6 100644
--- a/compiler/rustc_typeck/src/check/cast.rs
+++ b/compiler/rustc_typeck/src/check/cast.rs
@@ -322,7 +322,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             err.span_suggestion(
                                 self.span,
                                 "compare with zero instead",
-                                format!("{} != 0", snippet),
+                                format!("{snippet} != 0"),
                                 Applicability::MachineApplicable,
                             );
                         }
@@ -373,8 +373,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 let mut sugg = None;
                 let mut sugg_mutref = false;
                 if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
-                    if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind() {
-                        if fcx
+                    if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind()
+                        && fcx
                             .try_coerce(
                                 self.expr,
                                 fcx.tcx.mk_ref(
@@ -386,27 +386,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                                 None,
                             )
                             .is_ok()
-                        {
-                            sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty));
-                        }
-                    } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind() {
-                        if expr_mutbl == Mutability::Not
-                            && mutbl == Mutability::Mut
-                            && fcx
-                                .try_coerce(
-                                    self.expr,
-                                    fcx.tcx.mk_ref(
-                                        expr_reg,
-                                        TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
-                                    ),
-                                    self.cast_ty,
-                                    AllowTwoPhase::No,
-                                    None,
-                                )
-                                .is_ok()
-                        {
-                            sugg_mutref = true;
-                        }
+                    {
+                        sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty));
+                    } else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind()
+                        && expr_mutbl == Mutability::Not
+                        && mutbl == Mutability::Mut
+                        && fcx
+                            .try_coerce(
+                                self.expr,
+                                fcx.tcx.mk_ref(
+                                    expr_reg,
+                                    TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
+                                ),
+                                self.cast_ty,
+                                AllowTwoPhase::No,
+                                None,
+                            )
+                            .is_ok()
+                    {
+                        sugg_mutref = true;
                     }
 
                     if !sugg_mutref
@@ -423,8 +421,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     {
                         sugg = Some((format!("&{}", mutbl.prefix_str()), false));
                     }
-                } else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind() {
-                    if fcx
+                } else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind()
+                    && fcx
                         .try_coerce(
                             self.expr,
                             fcx.tcx.mk_ref(
@@ -436,9 +434,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             None,
                         )
                         .is_ok()
-                    {
-                        sugg = Some((format!("&{}", mutbl.prefix_str()), false));
-                    }
+                {
+                    sugg = Some((format!("&{}", mutbl.prefix_str()), false));
                 }
                 if sugg_mutref {
                     err.span_label(self.span, "invalid cast");
@@ -483,28 +480,28 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 ) {
                     let mut label = true;
                     // Check `impl From<self.expr_ty> for self.cast_ty {}` for accurate suggestion:
-                    if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) {
-                        if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) {
-                            let ty = fcx.resolve_vars_if_possible(self.cast_ty);
-                            // Erase regions to avoid panic in `prove_value` when calling
-                            // `type_implements_trait`.
-                            let ty = fcx.tcx.erase_regions(ty);
-                            let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
-                            let expr_ty = fcx.tcx.erase_regions(expr_ty);
-                            let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
-                            if fcx
-                                .infcx
-                                .type_implements_trait(from_trait, ty, ty_params, fcx.param_env)
-                                .must_apply_modulo_regions()
-                            {
-                                label = false;
-                                err.span_suggestion(
-                                    self.span,
-                                    "consider using the `From` trait instead",
-                                    format!("{}::from({})", self.cast_ty, snippet),
-                                    Applicability::MaybeIncorrect,
-                                );
-                            }
+                    if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span)
+                        && let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From)
+                    {
+                        let ty = fcx.resolve_vars_if_possible(self.cast_ty);
+                        // Erase regions to avoid panic in `prove_value` when calling
+                        // `type_implements_trait`.
+                        let ty = fcx.tcx.erase_regions(ty);
+                        let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
+                        let expr_ty = fcx.tcx.erase_regions(expr_ty);
+                        let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]);
+                        if fcx
+                            .infcx
+                            .type_implements_trait(from_trait, ty, ty_params, fcx.param_env)
+                            .must_apply_modulo_regions()
+                        {
+                            label = false;
+                            err.span_suggestion(
+                                self.span,
+                                "consider using the `From` trait instead",
+                                format!("{}::from({})", self.cast_ty, snippet),
+                                Applicability::MaybeIncorrect,
+                            );
                         }
                     }
                     let msg = "an `as` expression can only be used to convert between primitive \
@@ -627,10 +624,8 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         }
                     }
                 } else {
-                    let msg = &format!(
-                        "consider using an implicit coercion to `&{}{}` instead",
-                        mtstr, tstr
-                    );
+                    let msg =
+                        &format!("consider using an implicit coercion to `&{mtstr}{tstr}` instead");
                     err.span_help(self.span, msg);
                 }
             }
@@ -640,14 +635,14 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                         err.span_suggestion(
                             self.cast_span,
                             "you can cast to a `Box` instead",
-                            format!("Box<{}>", s),
+                            format!("Box<{s}>"),
                             Applicability::MachineApplicable,
                         );
                     }
                     Err(_) => {
                         err.span_help(
                             self.cast_span,
-                            &format!("you might have meant `Box<{}>`", tstr),
+                            &format!("you might have meant `Box<{tstr}>`"),
                         );
                     }
                 }
@@ -678,8 +673,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
             ))
             .help(&format!(
                 "cast can be replaced by coercion; this might \
-                                   require {}a temporary variable",
-                type_asc_or
+                                   require {type_asc_or}a temporary variable"
             ))
             .emit();
         });
@@ -969,21 +963,21 @@ impl<'a, 'tcx> CastCheck<'tcx> {
     }
 
     fn cenum_impl_drop_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
-        if let ty::Adt(d, _) = self.expr_ty.kind() {
-            if d.has_dtor(fcx.tcx) {
-                fcx.tcx.struct_span_lint_hir(
-                    lint::builtin::CENUM_IMPL_DROP_CAST,
-                    self.expr.hir_id,
-                    self.span,
-                    |err| {
-                        err.build(&format!(
-                            "cannot cast enum `{}` into integer `{}` because it implements `Drop`",
-                            self.expr_ty, self.cast_ty
-                        ))
-                        .emit();
-                    },
-                );
-            }
+        if let ty::Adt(d, _) = self.expr_ty.kind()
+            && d.has_dtor(fcx.tcx)
+        {
+            fcx.tcx.struct_span_lint_hir(
+                lint::builtin::CENUM_IMPL_DROP_CAST,
+                self.expr.hir_id,
+                self.span,
+                |err| {
+                    err.build(&format!(
+                        "cannot cast enum `{}` into integer `{}` because it implements `Drop`",
+                        self.expr_ty, self.cast_ty
+                    ))
+                    .emit();
+                },
+            );
         }
     }
 
@@ -1007,7 +1001,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     err.span_suggestion(
                         self.span,
                         msg,
-                        format!("({}).addr(){}", snippet, scalar_cast),
+                        format!("({snippet}).addr(){scalar_cast}"),
                         Applicability::MaybeIncorrect
                     );
                 } else {
@@ -1038,7 +1032,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                     err.span_suggestion(
                         self.span,
                         msg,
-                        format!("(...).with_addr({})", snippet),
+                        format!("(...).with_addr({snippet})"),
                         Applicability::HasPlaceholders,
                     );
                 } else {
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 1841451580f..314236b1cdf 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -43,8 +43,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
                 tcx.sess,
                 span,
                 E0570,
-                "`{}` is not a supported ABI for the current target",
-                abi
+                "`{abi}` is not a supported ABI for the current target",
             )
             .emit();
         }
@@ -249,84 +248,84 @@ pub(super) fn check_fn<'a, 'tcx>(
     fcx.demand_suptype(span, declared_ret_ty, actual_return_ty);
 
     // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
-    if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
-        if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
-            if let Some(panic_info_did) = tcx.lang_items().panic_info() {
-                if *declared_ret_ty.kind() != ty::Never {
-                    sess.span_err(decl.output.span(), "return type should be `!`");
-                }
+    if let Some(panic_impl_did) = tcx.lang_items().panic_impl()
+        && panic_impl_did == hir.local_def_id(fn_id).to_def_id()
+    {
+        if let Some(panic_info_did) = tcx.lang_items().panic_info() {
+            if *declared_ret_ty.kind() != ty::Never {
+                sess.span_err(decl.output.span(), "return type should be `!`");
+            }
 
-                let inputs = fn_sig.inputs();
-                let span = hir.span(fn_id);
-                if inputs.len() == 1 {
-                    let arg_is_panic_info = match *inputs[0].kind() {
-                        ty::Ref(region, ty, mutbl) => match *ty.kind() {
-                            ty::Adt(ref adt, _) => {
-                                adt.did() == panic_info_did
-                                    && mutbl == hir::Mutability::Not
-                                    && !region.is_static()
-                            }
-                            _ => false,
-                        },
+            let inputs = fn_sig.inputs();
+            let span = hir.span(fn_id);
+            if inputs.len() == 1 {
+                let arg_is_panic_info = match *inputs[0].kind() {
+                    ty::Ref(region, ty, mutbl) => match *ty.kind() {
+                        ty::Adt(ref adt, _) => {
+                            adt.did() == panic_info_did
+                                && mutbl == hir::Mutability::Not
+                                && !region.is_static()
+                        }
                         _ => false,
-                    };
-
-                    if !arg_is_panic_info {
-                        sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
-                    }
+                    },
+                    _ => false,
+                };
 
-                    if let Node::Item(item) = hir.get(fn_id)
-                        && let ItemKind::Fn(_, ref generics, _) = item.kind
-                        && !generics.params.is_empty()
-                    {
-                                sess.span_err(span, "should have no type parameters");
-                            }
-                } else {
-                    let span = sess.source_map().guess_head_span(span);
-                    sess.span_err(span, "function should have one argument");
+                if !arg_is_panic_info {
+                    sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
                 }
+
+                if let Node::Item(item) = hir.get(fn_id)
+                    && let ItemKind::Fn(_, ref generics, _) = item.kind
+                    && !generics.params.is_empty()
+                {
+                            sess.span_err(span, "should have no type parameters");
+                        }
             } else {
-                sess.err("language item required, but not found: `panic_info`");
+                let span = sess.source_map().guess_head_span(span);
+                sess.span_err(span, "function should have one argument");
             }
+        } else {
+            sess.err("language item required, but not found: `panic_info`");
         }
     }
 
     // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
-    if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
-        if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
-            if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
-                if *declared_ret_ty.kind() != ty::Never {
-                    sess.span_err(decl.output.span(), "return type should be `!`");
-                }
-
-                let inputs = fn_sig.inputs();
-                let span = hir.span(fn_id);
-                if inputs.len() == 1 {
-                    let arg_is_alloc_layout = match inputs[0].kind() {
-                        ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
-                        _ => false,
-                    };
+    if let Some(alloc_error_handler_did) = tcx.lang_items().oom()
+        && alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id()
+    {
+        if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
+            if *declared_ret_ty.kind() != ty::Never {
+                sess.span_err(decl.output.span(), "return type should be `!`");
+            }
 
-                    if !arg_is_alloc_layout {
-                        sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
-                    }
+            let inputs = fn_sig.inputs();
+            let span = hir.span(fn_id);
+            if inputs.len() == 1 {
+                let arg_is_alloc_layout = match inputs[0].kind() {
+                    ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
+                    _ => false,
+                };
 
-                    if let Node::Item(item) = hir.get(fn_id)
-                        && let ItemKind::Fn(_, ref generics, _) = item.kind
-                        && !generics.params.is_empty()
-                    {
-                                sess.span_err(
-                                    span,
-                            "`#[alloc_error_handler]` function should have no type parameters",
-                                );
-                            }
-                } else {
-                    let span = sess.source_map().guess_head_span(span);
-                    sess.span_err(span, "function should have one argument");
+                if !arg_is_alloc_layout {
+                    sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
                 }
+
+                if let Node::Item(item) = hir.get(fn_id)
+                    && let ItemKind::Fn(_, ref generics, _) = item.kind
+                    && !generics.params.is_empty()
+                {
+                            sess.span_err(
+                                span,
+                        "`#[alloc_error_handler]` function should have no type parameters",
+                            );
+                        }
             } else {
-                sess.err("language item required, but not found: `alloc_layout`");
+                let span = sess.source_map().guess_head_span(span);
+                sess.span_err(span, "function should have one argument");
             }
+        } else {
+            sess.err("language item required, but not found: `alloc_layout`");
         }
     }
 
@@ -670,7 +669,7 @@ fn check_opaque_meets_bounds<'tcx>(
             Err(ty_err) => {
                 tcx.sess.delay_span_bug(
                     span,
-                    &format!("could not unify `{}` with revealed type:\n{}", hidden_type, ty_err,),
+                    &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"),
                 );
             }
         }
@@ -817,10 +816,9 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
                             tcx.sess,
                             item.span,
                             E0044,
-                            "foreign items may not have {} parameters",
-                            kinds,
+                            "foreign items may not have {kinds} parameters",
                         )
-                        .span_label(item.span, &format!("can't have {} parameters", kinds))
+                        .span_label(item.span, &format!("can't have {kinds} parameters"))
                         .help(
                             // FIXME: once we start storing spans for type arguments, turn this
                             // into a suggestion.
@@ -1065,68 +1063,67 @@ pub(super) fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalD
 
 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
     let t = tcx.type_of(def_id);
-    if let ty::Adt(def, substs) = t.kind() {
-        if def.is_struct() {
-            let fields = &def.non_enum_variant().fields;
-            if fields.is_empty() {
+    if let ty::Adt(def, substs) = t.kind()
+        && def.is_struct()
+    {
+        let fields = &def.non_enum_variant().fields;
+        if fields.is_empty() {
+            struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
+            return;
+        }
+        let e = fields[0].ty(tcx, substs);
+        if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
+            struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
+                .span_label(sp, "SIMD elements must have the same type")
+                .emit();
+            return;
+        }
+
+        let len = if let ty::Array(_ty, c) = e.kind() {
+            c.try_eval_usize(tcx, tcx.param_env(def.did()))
+        } else {
+            Some(fields.len() as u64)
+        };
+        if let Some(len) = len {
+            if len == 0 {
                 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
                 return;
-            }
-            let e = fields[0].ty(tcx, substs);
-            if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
-                struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
-                    .span_label(sp, "SIMD elements must have the same type")
-                    .emit();
+            } else if len > MAX_SIMD_LANES {
+                struct_span_err!(
+                    tcx.sess,
+                    sp,
+                    E0075,
+                    "SIMD vector cannot have more than {MAX_SIMD_LANES} elements",
+                )
+                .emit();
                 return;
             }
+        }
 
-            let len = if let ty::Array(_ty, c) = e.kind() {
-                c.try_eval_usize(tcx, tcx.param_env(def.did()))
-            } else {
-                Some(fields.len() as u64)
-            };
-            if let Some(len) = len {
-                if len == 0 {
-                    struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
-                    return;
-                } else if len > MAX_SIMD_LANES {
-                    struct_span_err!(
-                        tcx.sess,
-                        sp,
-                        E0075,
-                        "SIMD vector cannot have more than {} elements",
-                        MAX_SIMD_LANES,
-                    )
-                    .emit();
-                    return;
-                }
-            }
-
-            // Check that we use types valid for use in the lanes of a SIMD "vector register"
-            // These are scalar types which directly match a "machine" type
-            // Yes: Integers, floats, "thin" pointers
-            // No: char, "fat" pointers, compound types
-            match e.kind() {
-                ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
-                ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
-                ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
-                ty::Array(t, _clen)
-                    if matches!(
-                        t.kind(),
-                        ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)
-                    ) =>
-                { /* struct([f32; 4]) is ok */ }
-                _ => {
-                    struct_span_err!(
-                        tcx.sess,
-                        sp,
-                        E0077,
-                        "SIMD vector element type should be a \
-                         primitive scalar (integer/float/pointer) type"
-                    )
-                    .emit();
-                    return;
-                }
+        // Check that we use types valid for use in the lanes of a SIMD "vector register"
+        // These are scalar types which directly match a "machine" type
+        // Yes: Integers, floats, "thin" pointers
+        // No: char, "fat" pointers, compound types
+        match e.kind() {
+            ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
+            ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
+            ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
+            ty::Array(t, _clen)
+                if matches!(
+                    t.kind(),
+                    ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)
+                ) =>
+            { /* struct([f32; 4]) is ok */ }
+            _ => {
+                struct_span_err!(
+                    tcx.sess,
+                    sp,
+                    E0077,
+                    "SIMD vector element type should be a \
+                        primitive scalar (integer/float/pointer) type"
+                )
+                .emit();
+                return;
             }
         }
     }
@@ -1189,7 +1186,7 @@ pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
                                     ident
                                 )
                             } else {
-                                format!("...which contains a field of type `{}`", ident)
+                                format!("...which contains a field of type `{ident}`")
                             },
                         );
                         first = false;
@@ -1215,13 +1212,12 @@ pub(super) fn check_packed_inner(
 
             stack.push(def_id);
             for field in &def.non_enum_variant().fields {
-                if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
-                    if !stack.contains(&def.did()) {
-                        if let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) {
-                            defs.push((def.did(), field.ident(tcx).span));
-                            return Some(defs);
-                        }
-                    }
+                if let ty::Adt(def, _) = field.ty(tcx, substs).kind()
+                    && !stack.contains(&def.did())
+                    && let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
+                {
+                    defs.push((def.did(), field.ident(tcx).span));
+                    return Some(defs);
                 }
             }
             stack.pop();
@@ -1370,8 +1366,8 @@ fn check_enum<'tcx>(
                 "discriminant value `{}` already exists",
                 discr.val,
             )
-            .span_label(i_span, format!("first use of {}", display_discr_i))
-            .span_label(span, format!("enum already has {}", display_discr))
+            .span_label(i_span, format!("first use of {display_discr_i}"))
+            .span_label(span, format!("enum already has {display_discr}"))
             .emit();
         }
         disr_vals.push(discr);
@@ -1393,7 +1389,7 @@ fn display_discriminant_value<'tcx>(
             && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
             && evaluated != *lit_value
         {
-                    return format!("`{}` (overflowed from `{}`)", evaluated, lit_value);
+                    return format!("`{evaluated}` (overflowed from `{lit_value}`)");
         }
     }
     format!("`{}`", evaluated)
@@ -1422,28 +1418,28 @@ pub(super) fn check_type_params_are_used<'tcx>(
     }
 
     for leaf in ty.walk() {
-        if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
-            if let ty::Param(param) = leaf_ty.kind() {
-                debug!("found use of ty param {:?}", param);
-                params_used.insert(param.index);
-            }
+        if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
+            && let ty::Param(param) = leaf_ty.kind()
+        {
+            debug!("found use of ty param {:?}", param);
+            params_used.insert(param.index);
         }
     }
 
     for param in &generics.params {
-        if !params_used.contains(param.index) {
-            if let ty::GenericParamDefKind::Type { .. } = param.kind {
-                let span = tcx.def_span(param.def_id);
-                struct_span_err!(
-                    tcx.sess,
-                    span,
-                    E0091,
-                    "type parameter `{}` is unused",
-                    param.name,
-                )
-                .span_label(span, "unused type parameter")
-                .emit();
-            }
+        if !params_used.contains(param.index)
+            && let ty::GenericParamDefKind::Type { .. } = param.kind
+        {
+            let span = tcx.def_span(param.def_id);
+            struct_span_err!(
+                tcx.sess,
+                span,
+                E0091,
+                "type parameter `{}` is unused",
+                param.name,
+            )
+            .span_label(span, "unused type parameter")
+            .emit();
         }
     }
 }
@@ -1534,10 +1530,10 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E
                 for def_id in visitor.0 {
                     let ty_span = tcx.def_span(def_id);
                     if !seen.contains(&ty_span) {
-                        err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
+                        err.span_label(ty_span, &format!("returning this opaque type `{ty}`"));
                         seen.insert(ty_span);
                     }
-                    err.span_label(sp, &format!("returning here with type `{}`", ty));
+                    err.span_label(sp, &format!("returning here with type `{ty}`"));
                 }
             }
         }
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 34fc177de6d..b44baf83cbe 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -632,11 +632,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                         let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
                         if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) =
                             (self_ty.kind(), unsize_ty.kind())
+                            && data_a.principal_def_id() != data_b.principal_def_id()
                         {
-                            if data_a.principal_def_id() != data_b.principal_def_id() {
-                                debug!("coerce_unsized: found trait upcasting coercion");
-                                has_trait_upcasting_coercion = true;
-                            }
+                            debug!("coerce_unsized: found trait upcasting coercion");
+                            has_trait_upcasting_coercion = true;
                         }
                         if let ty::Tuple(..) = unsize_ty.kind() {
                             debug!("coerce_unsized: found unsized tuple coercion");
@@ -732,13 +731,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         F: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
         G: FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
     {
-        if let ty::FnPtr(fn_ty_b) = b.kind() {
-            if let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) =
+        if let ty::FnPtr(fn_ty_b) = b.kind()
+            && let (hir::Unsafety::Normal, hir::Unsafety::Unsafe) =
                 (fn_ty_a.unsafety(), fn_ty_b.unsafety())
-            {
-                let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
-                return self.unify_and(unsafe_a, b, to_unsafe);
-            }
+        {
+            let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
+            return self.unify_and(unsafe_a, b, to_unsafe);
         }
         self.unify_and(a, b, normal)
     }
@@ -783,12 +781,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 }
 
                 // Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
-                if let ty::FnDef(def_id, _) = *a.kind() {
-                    if b_sig.unsafety() == hir::Unsafety::Normal
-                        && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
-                    {
-                        return Err(TypeError::TargetFeatureCast(def_id));
-                    }
+                if let ty::FnDef(def_id, _) = *a.kind()
+                    && b_sig.unsafety() == hir::Unsafety::Normal
+                    && !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
+                {
+                    return Err(TypeError::TargetFeatureCast(def_id));
                 }
 
                 let InferOk { value: a_sig, obligations: o1 } =
@@ -1502,7 +1499,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                         found,
                         expected,
                         None,
-                        coercion_error,
+                        Some(coercion_error),
                     );
                 }
 
@@ -1540,11 +1537,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                 fcx.tcx.hir().get_if_cause(expr.hir_id),
                 expected.is_unit(),
                 pointing_at_return_type,
-            ) {
+            )
                 // If the block is from an external macro or try (`?`) desugaring, then
                 // do not suggest adding a semicolon, because there's nowhere to put it.
                 // See issues #81943 and #87051.
-                if matches!(
+                && matches!(
                     cond_expr.span.desugaring_kind(),
                     None | Some(DesugaringKind::WhileLoop)
                 ) && !in_external_macro(fcx.tcx.sess, cond_expr.span)
@@ -1552,11 +1549,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                         cond_expr.kind,
                         hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
                     )
-                {
-                    err.span_label(cond_expr.span, "expected this to be `()`");
-                    if expr.can_have_side_effects() {
-                        fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);
-                    }
+            {
+                err.span_label(cond_expr.span, "expected this to be `()`");
+                if expr.can_have_side_effects() {
+                    fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);
                 }
             }
             fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
@@ -1636,28 +1632,27 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         let has_impl = snippet_iter.next().map_or(false, |s| s == "impl");
         // Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
         let mut is_object_safe = false;
-        if let hir::FnRetTy::Return(ty) = fn_output {
+        if let hir::FnRetTy::Return(ty) = fn_output
             // Get the return type.
-            if let hir::TyKind::OpaqueDef(..) = ty.kind {
-                let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty);
-                // Get the `impl Trait`'s `DefId`.
-                if let ty::Opaque(def_id, _) = ty.kind() {
-                    // Get the `impl Trait`'s `Item` so that we can get its trait bounds and
-                    // get the `Trait`'s `DefId`.
-                    if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) =
-                        fcx.tcx.hir().expect_item(def_id.expect_local()).kind
-                    {
-                        // Are of this `impl Trait`'s traits object safe?
-                        is_object_safe = bounds.iter().all(|bound| {
-                            bound
-                                .trait_ref()
-                                .and_then(|t| t.trait_def_id())
-                                .map_or(false, |def_id| {
-                                    fcx.tcx.object_safety_violations(def_id).is_empty()
-                                })
+            && let hir::TyKind::OpaqueDef(..) = ty.kind
+        {
+            let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty);
+            // Get the `impl Trait`'s `DefId`.
+            if let ty::Opaque(def_id, _) = ty.kind()
+                // Get the `impl Trait`'s `Item` so that we can get its trait bounds and
+                // get the `Trait`'s `DefId`.
+                && let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) =
+                    fcx.tcx.hir().expect_item(def_id.expect_local()).kind
+            {
+                // Are of this `impl Trait`'s traits object safe?
+                is_object_safe = bounds.iter().all(|bound| {
+                    bound
+                        .trait_ref()
+                        .and_then(|t| t.trait_def_id())
+                        .map_or(false, |def_id| {
+                            fcx.tcx.object_safety_violations(def_id).is_empty()
                         })
-                    }
-                }
+                })
             }
         };
         if has_impl {
@@ -1703,7 +1698,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
             && let ty = <dyn AstConv<'_>>::ast_ty_to_ty(fcx, ty)
             && let ty::Dynamic(..) = ty.kind()
         {
-                    return true;
+            return true;
         }
         false
     }
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 0bd5e018f4a..4ab6f2cdafb 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -315,7 +315,7 @@ fn compare_predicate_entailment<'tcx>(
                         ExplicitSelf::ByReference(_, hir::Mutability::Mut) => {
                             "&mut self".to_owned()
                         }
-                        _ => format!("self: {}", ty),
+                        _ => format!("self: {ty}"),
                     };
 
                     // When the `impl` receiver is an arbitrary self type, like `self: Box<Self>`, the
@@ -384,6 +384,7 @@ fn compare_predicate_entailment<'tcx>(
                 })),
                 &terr,
                 false,
+                false,
             );
 
             return Err(diag.emit());
@@ -526,7 +527,7 @@ fn compare_self_type<'tcx>(
                 ExplicitSelf::ByValue => "self".to_owned(),
                 ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
                 ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
-                _ => format!("self: {}", self_arg_ty),
+                _ => format!("self: {self_arg_ty}"),
             }
         })
     };
@@ -544,9 +545,9 @@ fn compare_self_type<'tcx>(
                 trait_m.name,
                 self_descr
             );
-            err.span_label(impl_m_span, format!("`{}` used in impl", self_descr));
+            err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
             if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
-                err.span_label(span, format!("trait method declared without `{}`", self_descr));
+                err.span_label(span, format!("trait method declared without `{self_descr}`"));
             } else {
                 err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
             }
@@ -564,9 +565,9 @@ fn compare_self_type<'tcx>(
                 trait_m.name,
                 self_descr
             );
-            err.span_label(impl_m_span, format!("expected `{}` in impl", self_descr));
+            err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
             if let Some(span) = tcx.hir().span_if_local(trait_m.def_id) {
-                err.span_label(span, format!("`{}` used in trait", self_descr));
+                err.span_label(span, format!("`{self_descr}` used in trait"));
             } else {
                 err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx));
             }
@@ -668,7 +669,7 @@ fn compare_number_of_generics<'tcx>(
                     err.span_label(*span, "");
                 }
             } else {
-                suffix = Some(format!(", expected {}", trait_count));
+                suffix = Some(format!(", expected {trait_count}"));
             }
 
             if let Some(span) = span {
@@ -873,12 +874,10 @@ fn compare_synthetic_generics<'tcx>(
                                 intravisit::walk_ty(self, ty);
                                 if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) =
                                     ty.kind
+                                    && let Res::Def(DefKind::TyParam, def_id) = path.res
+                                    && def_id == self.1
                                 {
-                                    if let Res::Def(DefKind::TyParam, def_id) = path.res {
-                                        if def_id == self.1 {
-                                            self.0 = Some(ty.span);
-                                        }
-                                    }
+                                    self.0 = Some(ty.span);
                                 }
                             }
                         }
@@ -908,7 +907,7 @@ fn compare_synthetic_generics<'tcx>(
                                 // delete generic parameters
                                 (impl_m.generics.span, String::new()),
                                 // replace param usage with `impl Trait`
-                                (span, format!("impl {}", bounds)),
+                                (span, format!("impl {bounds}")),
                             ],
                             Applicability::MaybeIncorrect,
                         );
@@ -972,7 +971,7 @@ fn compare_const_param_types<'tcx>(
                 &format!(
                     "the const parameter{} has type `{}`, but the declaration \
                               in trait `{}` has type `{}`",
-                    &impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{}`", ident)),
+                    &impl_ident.map_or_else(|| "".to_string(), |ident| format!(" `{ident}`")),
                     impl_ty,
                     tcx.def_path_str(trait_m.def_id),
                     trait_ty
@@ -1074,6 +1073,7 @@ crate fn compare_const_impl<'tcx>(
                 })),
                 &terr,
                 false,
+                false,
             );
             diag.emit();
         }
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 83e535b3c32..f377cf3678e 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -28,7 +28,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
-        error: TypeError<'tcx>,
+        error: Option<TypeError<'tcx>>,
     ) {
         self.annotate_expected_due_to_let_ty(err, expr, error);
         self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr);
@@ -150,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr_ty = self.resolve_vars_with_obligations(checked_ty);
         let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e.clone());
 
-        self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, e);
+        self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e));
 
         (expected, Some(err))
     }
@@ -159,7 +159,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
-        error: TypeError<'_>,
+        error: Option<TypeError<'_>>,
     ) {
         let parent = self.tcx.hir().get_parent_node(expr.hir_id);
         match (self.tcx.hir().find(parent), error) {
@@ -173,7 +173,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(hir::Node::Expr(hir::Expr {
                     kind: hir::ExprKind::Assign(lhs, rhs, _), ..
                 })),
-                TypeError::Sorts(ExpectedFound { expected, .. }),
+                Some(TypeError::Sorts(ExpectedFound { expected, .. })),
             ) if rhs.hir_id == expr.hir_id && !expected.is_closure() => {
                 // We ignore closures explicitly because we already point at them elsewhere.
                 // Point at the assigned-to binding.
@@ -241,13 +241,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We are pointing at the binding's type or initializer value, but it's pattern
                     // is in a different line, so we point at both.
                     err.span_label(secondary_span, "expected due to the type of this binding");
-                    err.span_label(primary_span, &format!("expected due to this{}", post_message));
+                    err.span_label(primary_span, &format!("expected due to this{post_message}"));
                 } else if post_message == "" {
                     // We are pointing at either the assignment lhs or the binding def pattern.
                     err.span_label(primary_span, "expected due to the type of this binding");
                 } else {
                     // We are pointing at the binding's type or initializer value.
-                    err.span_label(primary_span, &format!("expected due to this{}", post_message));
+                    err.span_label(primary_span, &format!("expected due to this{post_message}"));
                 }
 
                 if !lhs.is_syntactic_place_expr() {
@@ -321,7 +321,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     "try adding an expression at the end of the block",
                                     return_suggestions
                                         .into_iter()
-                                        .map(|r| format!("{}\n{}{}", semicolon, indent, r)),
+                                        .map(|r| format!("{semicolon}\n{indent}{r}")),
                                     Applicability::MaybeIncorrect,
                                 );
                             }
@@ -344,10 +344,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let variant_path =
                             with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
                         // FIXME #56861: DRYer prelude filtering
-                        if let Some(path) = variant_path.strip_prefix("std::prelude::") {
-                            if let Some((_, path)) = path.split_once("::") {
-                                return Some(path.to_string());
-                            }
+                        if let Some(path) = variant_path.strip_prefix("std::prelude::")
+                            && let Some((_, path)) = path.split_once("::")
+                        {
+                            return Some(path.to_string());
                         }
                         Some(variant_path)
                     } else {
@@ -357,7 +357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .collect();
 
             let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
-                Some(ident) => format!("{}: ", ident),
+                Some(ident) => format!("{ident}: "),
                 None => String::new(),
             };
 
@@ -366,9 +366,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 [variant] => {
                     // Just a single matching variant.
                     err.multipart_suggestion_verbose(
-                        &format!("try wrapping the expression in `{}`", variant),
+                        &format!("try wrapping the expression in `{variant}`"),
                         vec![
-                            (expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)),
+                            (expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
                             (expr.span.shrink_to_hi(), ")".to_string()),
                         ],
                         Applicability::MaybeIncorrect,
@@ -383,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ),
                         compatible_variants.into_iter().map(|variant| {
                             vec![
-                                (expr.span.shrink_to_lo(), format!("{}{}(", prefix, variant)),
+                                (expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
                                 (expr.span.shrink_to_hi(), ")".to_string()),
                             ]
                         }),
@@ -680,7 +680,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             _ if is_range_literal(expr) => true,
                             _ => false,
                         };
-                        let sugg_expr = if needs_parens { format!("({})", src) } else { src };
+                        let sugg_expr = if needs_parens { format!("({src})") } else { src };
 
                         if let Some(sugg) = self.can_use_as_ref(expr) {
                             return Some((
@@ -693,7 +693,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
 
                         let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
-                            Some(ident) => format!("{}: ", ident),
+                            Some(ident) => format!("{ident}: "),
                             None => String::new(),
                         };
 
@@ -727,14 +727,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             hir::Mutability::Mut => (
                                 sp,
                                 "consider mutably borrowing here".to_string(),
-                                format!("{}&mut {}", prefix, sugg_expr),
+                                format!("{prefix}&mut {sugg_expr}"),
                                 Applicability::MachineApplicable,
                                 false,
                             ),
                             hir::Mutability::Not => (
                                 sp,
                                 "consider borrowing here".to_string(),
-                                format!("{}&{}", prefix, sugg_expr),
+                                format!("{prefix}&{sugg_expr}"),
                                 Applicability::MachineApplicable,
                                 false,
                             ),
@@ -758,29 +758,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if let Some(call_span) =
                         iter::successors(Some(expr.span), |s| s.parent_callsite())
                             .find(|&s| sp.contains(s))
+                        && sm.span_to_snippet(call_span).is_ok()
                     {
-                        if sm.span_to_snippet(call_span).is_ok() {
-                            return Some((
-                                sp.with_hi(call_span.lo()),
-                                "consider removing the borrow".to_string(),
-                                String::new(),
-                                Applicability::MachineApplicable,
-                                true,
-                            ));
-                        }
-                    }
-                    return None;
-                }
-                if sp.contains(expr.span) {
-                    if sm.span_to_snippet(expr.span).is_ok() {
                         return Some((
-                            sp.with_hi(expr.span.lo()),
+                            sp.with_hi(call_span.lo()),
                             "consider removing the borrow".to_string(),
                             String::new(),
                             Applicability::MachineApplicable,
                             true,
                         ));
                     }
+                    return None;
+                }
+                if sp.contains(expr.span)
+                    && sm.span_to_snippet(expr.span).is_ok()
+                {
+                    return Some((
+                        sp.with_hi(expr.span.lo()),
+                        "consider removing the borrow".to_string(),
+                        String::new(),
+                        Applicability::MachineApplicable,
+                        true,
+                    ));
                 }
             }
             (
@@ -788,66 +787,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 &ty::RawPtr(TypeAndMut { ty: ty_b, mutbl: mutbl_b }),
                 &ty::Ref(_, ty_a, mutbl_a),
             ) => {
-                if let Some(steps) = self.deref_steps(ty_a, ty_b) {
+                if let Some(steps) = self.deref_steps(ty_a, ty_b)
                     // Only suggest valid if dereferencing needed.
-                    if steps > 0 {
-                        // The pointer type implements `Copy` trait so the suggestion is always valid.
-                        if let Ok(src) = sm.span_to_snippet(sp) {
-                            let derefs = "*".repeat(steps);
-                            if let Some((span, src, applicability)) = match mutbl_b {
+                    && steps > 0
+                    // The pointer type implements `Copy` trait so the suggestion is always valid.
+                    && let Ok(src) = sm.span_to_snippet(sp)
+                {
+                    let derefs = "*".repeat(steps);
+                    if let Some((span, src, applicability)) = match mutbl_b {
+                        hir::Mutability::Mut => {
+                            let new_prefix = "&mut ".to_owned() + &derefs;
+                            match mutbl_a {
                                 hir::Mutability::Mut => {
-                                    let new_prefix = "&mut ".to_owned() + &derefs;
-                                    match mutbl_a {
-                                        hir::Mutability::Mut => {
-                                            replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
-                                                let pos = sp.lo() + BytePos(5);
-                                                let sp = sp.with_lo(pos).with_hi(pos);
-                                                (sp, derefs, Applicability::MachineApplicable)
-                                            })
-                                        }
-                                        hir::Mutability::Not => {
-                                            replace_prefix(&src, "&", &new_prefix).map(|_| {
-                                                let pos = sp.lo() + BytePos(1);
-                                                let sp = sp.with_lo(pos).with_hi(pos);
-                                                (
-                                                    sp,
-                                                    format!("mut {}", derefs),
-                                                    Applicability::Unspecified,
-                                                )
-                                            })
-                                        }
-                                    }
+                                    replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
+                                        let pos = sp.lo() + BytePos(5);
+                                        let sp = sp.with_lo(pos).with_hi(pos);
+                                        (sp, derefs, Applicability::MachineApplicable)
+                                    })
                                 }
                                 hir::Mutability::Not => {
-                                    let new_prefix = "&".to_owned() + &derefs;
-                                    match mutbl_a {
-                                        hir::Mutability::Mut => {
-                                            replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
-                                                let lo = sp.lo() + BytePos(1);
-                                                let hi = sp.lo() + BytePos(5);
-                                                let sp = sp.with_lo(lo).with_hi(hi);
-                                                (sp, derefs, Applicability::MachineApplicable)
-                                            })
-                                        }
-                                        hir::Mutability::Not => {
-                                            replace_prefix(&src, "&", &new_prefix).map(|_| {
-                                                let pos = sp.lo() + BytePos(1);
-                                                let sp = sp.with_lo(pos).with_hi(pos);
-                                                (sp, derefs, Applicability::MachineApplicable)
-                                            })
-                                        }
-                                    }
+                                    replace_prefix(&src, "&", &new_prefix).map(|_| {
+                                        let pos = sp.lo() + BytePos(1);
+                                        let sp = sp.with_lo(pos).with_hi(pos);
+                                        (
+                                            sp,
+                                            format!("mut {derefs}"),
+                                            Applicability::Unspecified,
+                                        )
+                                    })
                                 }
-                            } {
-                                return Some((
-                                    span,
-                                    "consider dereferencing".to_string(),
-                                    src,
-                                    applicability,
-                                    true,
-                                ));
                             }
                         }
+                        hir::Mutability::Not => {
+                            let new_prefix = "&".to_owned() + &derefs;
+                            match mutbl_a {
+                                hir::Mutability::Mut => {
+                                    replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
+                                        let lo = sp.lo() + BytePos(1);
+                                        let hi = sp.lo() + BytePos(5);
+                                        let sp = sp.with_lo(lo).with_hi(hi);
+                                        (sp, derefs, Applicability::MachineApplicable)
+                                    })
+                                }
+                                hir::Mutability::Not => {
+                                    replace_prefix(&src, "&", &new_prefix).map(|_| {
+                                        let pos = sp.lo() + BytePos(1);
+                                        let sp = sp.with_lo(pos).with_hi(pos);
+                                        (sp, derefs, Applicability::MachineApplicable)
+                                    })
+                                }
+                            }
+                        }
+                    } {
+                        return Some((
+                            span,
+                            "consider dereferencing".to_string(),
+                            src,
+                            applicability,
+                            true,
+                        ));
                     }
                 }
             }
@@ -908,7 +906,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // Suggest removing `&` if we have removed any, otherwise suggest just
                         // dereferencing the remaining number of steps.
                         let message = if remove.is_empty() {
-                            format!("consider {}", deref_kind)
+                            format!("consider {deref_kind}")
                         } else {
                             format!(
                                 "consider removing the `{}` and {} instead",
@@ -918,7 +916,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         };
 
                         let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
-                            Some(ident) => format!("{}: ", ident),
+                            Some(ident) => format!("{ident}: "),
                             None => String::new(),
                         };
 
@@ -994,35 +992,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         };
 
-        if let hir::ExprKind::Call(path, args) = &expr.kind {
-            if let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) =
+        if let hir::ExprKind::Call(path, args) = &expr.kind
+            && let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) =
                 (&path.kind, args.len())
-            {
-                // `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697).
-                if let (hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)), sym::from) =
-                    (&base_ty.kind, path_segment.ident.name)
-                {
-                    if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() {
-                        match ident.name {
-                            sym::i128
-                            | sym::i64
-                            | sym::i32
-                            | sym::i16
-                            | sym::i8
-                            | sym::u128
-                            | sym::u64
-                            | sym::u32
-                            | sym::u16
-                            | sym::u8
-                            | sym::isize
-                            | sym::usize
-                                if base_ty_path.segments.len() == 1 =>
-                            {
-                                return false;
-                            }
-                            _ => {}
-                        }
+            // `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697).
+            && let (hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)), sym::from) =
+                (&base_ty.kind, path_segment.ident.name)
+        {
+            if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() {
+                match ident.name {
+                    sym::i128
+                    | sym::i64
+                    | sym::i32
+                    | sym::i16
+                    | sym::i8
+                    | sym::u128
+                    | sym::u64
+                    | sym::u32
+                    | sym::u16
+                    | sym::u8
+                    | sym::isize
+                    | sym::usize
+                        if base_ty_path.segments.len() == 1 =>
+                    {
+                        return false;
                     }
+                    _ => {}
                 }
             }
         }
@@ -1042,8 +1037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             expected_ty,
         );
         let lit_msg = format!(
-            "change the type of the numeric literal from `{}` to `{}`",
-            checked_ty, expected_ty,
+            "change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
         );
 
         let close_paren = if expr.precedence().order() < PREC_POSTFIX {
@@ -1054,10 +1048,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let mut cast_suggestion = sugg.clone();
-        cast_suggestion
-            .push((expr.span.shrink_to_hi(), format!("{} as {}", close_paren, expected_ty)));
+        cast_suggestion.push((expr.span.shrink_to_hi(), format!("{close_paren} as {expected_ty}")));
         let mut into_suggestion = sugg.clone();
-        into_suggestion.push((expr.span.shrink_to_hi(), format!("{}.into()", close_paren)));
+        into_suggestion.push((expr.span.shrink_to_hi(), format!("{close_paren}.into()")));
         let mut suffix_suggestion = sugg.clone();
         suffix_suggestion.push((
             if matches!(
@@ -1074,7 +1067,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             },
             if expr.precedence().order() < PREC_POSTFIX {
                 // Readd `)`
-                format!("{})", expected_ty)
+                format!("{expected_ty})")
             } else {
                 expected_ty.to_string()
             },
@@ -1108,20 +1101,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     (lhs_expr_and_src, exp_to_found_is_fallible)
                 {
                     let msg = format!(
-                        "you can convert `{}` from `{}` to `{}`, matching the type of `{}`",
-                        lhs_src, expected_ty, checked_ty, src
+                        "you can convert `{lhs_src}` from `{expected_ty}` to `{checked_ty}`, matching the type of `{src}`",
                     );
                     let suggestion = vec![
-                        (lhs_expr.span.shrink_to_lo(), format!("{}::from(", checked_ty)),
+                        (lhs_expr.span.shrink_to_lo(), format!("{checked_ty}::from(")),
                         (lhs_expr.span.shrink_to_hi(), ")".to_string()),
                     ];
                     (msg, suggestion)
                 } else {
-                    let msg = format!("{} and panic if the converted value doesn't fit", msg);
+                    let msg = format!("{msg} and panic if the converted value doesn't fit");
                     let mut suggestion = sugg.clone();
                     suggestion.push((
                         expr.span.shrink_to_hi(),
-                        format!("{}.try_into().unwrap()", close_paren),
+                        format!("{close_paren}.try_into().unwrap()"),
                     ));
                     (msg, suggestion)
                 };
@@ -1151,7 +1143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // We now know that converting either the lhs or rhs is fallible. Before we
                     // suggest a fallible conversion, check if the value can never fit in the
                     // expected type.
-                    let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty);
+                    let msg = format!("`{src}` cannot fit into type `{expected_ty}`");
                     err.note(&msg);
                     return;
                 } else if in_const_context {
@@ -1229,7 +1221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 } else if can_cast {
                     // Missing try_into implementation for `f64` to `f32`
                     err.multipart_suggestion_verbose(
-                        &format!("{}, producing the closest possible value", cast_msg),
+                        &format!("{cast_msg}, producing the closest possible value"),
                         cast_suggestion,
                         Applicability::MaybeIncorrect, // lossy conversion
                     );
@@ -1246,7 +1238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 } else if can_cast {
                     // Missing try_into implementation for `{float}` to `{integer}`
                     err.multipart_suggestion_verbose(
-                        &format!("{}, rounding the float towards zero", msg),
+                        &format!("{msg}, rounding the float towards zero"),
                         cast_suggestion,
                         Applicability::MaybeIncorrect, // lossy conversion
                     );
@@ -1258,8 +1250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if exp.bit_width() > found.bit_width().unwrap_or(256) {
                     err.multipart_suggestion_verbose(
                         &format!(
-                            "{}, producing the floating point representation of the integer",
-                            msg,
+                            "{msg}, producing the floating point representation of the integer",
                         ),
                         into_suggestion,
                         Applicability::MachineApplicable,
@@ -1274,9 +1265,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // Missing try_into implementation for `{integer}` to `{float}`
                     err.multipart_suggestion_verbose(
                         &format!(
-                            "{}, producing the floating point representation of the integer, \
+                            "{cast_msg}, producing the floating point representation of the integer, \
                                  rounded if necessary",
-                            cast_msg,
                         ),
                         cast_suggestion,
                         Applicability::MaybeIncorrect, // lossy conversion
@@ -1321,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 &ty::Char,
             ) => {
                 err.multipart_suggestion_verbose(
-                    &format!("{}, since a `char` always occupies 4 bytes", cast_msg,),
+                    &format!("{cast_msg}, since a `char` always occupies 4 bytes"),
                     cast_suggestion,
                     Applicability::MachineApplicable,
                 );
@@ -1333,22 +1323,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     // Report the type inferred by the return statement.
     fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) {
-        if let Some(sp) = self.ret_coercion_span.get() {
+        if let Some(sp) = self.ret_coercion_span.get()
             // If the closure has an explicit return type annotation, or if
             // the closure's return type has been inferred from outside
             // requirements (such as an Fn* trait bound), then a type error
             // may occur at the first return expression we see in the closure
             // (if it conflicts with the declared return type). Skip adding a
             // note in this case, since it would be incorrect.
-            if !self.return_type_pre_known {
-                err.span_note(
-                    sp,
-                    &format!(
-                        "return type inferred to be `{}` here",
-                        self.resolve_vars_if_possible(expected)
-                    ),
-                );
-            }
+            && !self.return_type_pre_known
+        {
+            err.span_note(
+                sp,
+                &format!(
+                    "return type inferred to be `{}` here",
+                    self.resolve_vars_if_possible(expected)
+                ),
+            );
         }
     }
 }
diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs
index 4ab94f39357..3bc92166543 100644
--- a/compiler/rustc_typeck/src/check/dropck.rs
+++ b/compiler/rustc_typeck/src/check/dropck.rs
@@ -57,7 +57,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
             let span = tcx.def_span(drop_impl_did);
             let reported = tcx.sess.delay_span_bug(
                 span,
-                &format!("should have been rejected by coherence check: {}", dtor_self_type),
+                &format!("should have been rejected by coherence check: {dtor_self_type}"),
             );
             Err(reported)
         }
@@ -104,8 +104,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
                     item_span,
                     &format!(
                         "use the same sequence of generic type, lifetime and const parameters \
-                        as the {} definition",
-                        self_descr,
+                        as the {self_descr} definition",
                     ),
                 )
                 .emit();
@@ -262,9 +261,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                 tcx.sess,
                 predicate_sp,
                 E0367,
-                "`Drop` impl requires `{}` but the {} it is implemented for does not",
-                predicate,
-                self_descr,
+                "`Drop` impl requires `{predicate}` but the {self_descr} it is implemented for does not",
             )
             .span_note(item_span, "the implementor must specify the same requirement")
             .emit();
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 669521bc472..e88082dbb97 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -181,13 +181,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // make this code only run with -Zverbose because it is probably slow
             if let Ok(lint_str) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
                 if !lint_str.contains('\n') {
-                    debug!("expr text: {}", lint_str);
+                    debug!("expr text: {lint_str}");
                 } else {
                     let mut lines = lint_str.lines();
                     if let Some(line0) = lines.next() {
                         let remaining_lines = lines.count();
-                        debug!("expr text: {}", line0);
-                        debug!("expr text: ...(and {} more lines)", remaining_lines);
+                        debug!("expr text: {line0}");
+                        debug!("expr text: ...(and {remaining_lines} more lines)");
                     }
                 }
             }
@@ -259,7 +259,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     #[instrument(skip(self, expr), level = "debug")]
-    fn check_expr_kind(
+    pub(super) fn check_expr_kind(
         &self,
         expr: &'tcx hir::Expr<'tcx>,
         expected: Expectation<'tcx>,
@@ -375,8 +375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             expr.span,
                             oprnd_t,
                             E0614,
-                            "type `{}` cannot be dereferenced",
-                            oprnd_t,
+                            "type `{oprnd_t}` cannot be dereferenced",
                         );
                         let sp = tcx.sess.source_map().start_point(expr.span);
                         if let Some(sp) =
@@ -652,7 +651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 err.span_suggestion(
                                     expr.span,
                                     "give it a value of the expected type",
-                                    format!("break{} {}", label, val),
+                                    format!("break{label} {val}"),
                                     Applicability::HasPlaceholders,
                                 );
                             }
@@ -780,7 +779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
                             db.span_label(
                                 span,
-                                format!("expected `{}` because of this return type", snippet),
+                                format!("expected `{snippet}` because of this return type"),
                             );
                         }
                     },
@@ -1367,11 +1366,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let tcx = self.tcx;
 
-        let adt_ty_hint = self
-            .expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
-            .get(0)
-            .cloned()
-            .unwrap_or(adt_ty);
+        let expected_inputs =
+            self.expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty]);
+        let adt_ty_hint = if let Some(expected_inputs) = expected_inputs {
+            expected_inputs.get(0).cloned().unwrap_or(adt_ty)
+        } else {
+            adt_ty
+        };
         // re-link the regions that EIfEO can erase.
         self.demand_eqtype(span, adt_ty_hint, adt_ty);
 
@@ -1611,15 +1612,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut truncated_fields_error = String::new();
         let remaining_fields_names = match &displayable_field_names[..] {
             [field1] => format!("`{}`", field1),
-            [field1, field2] => format!("`{}` and `{}`", field1, field2),
-            [field1, field2, field3] => format!("`{}`, `{}` and `{}`", field1, field2, field3),
+            [field1, field2] => format!("`{field1}` and `{field2}`"),
+            [field1, field2, field3] => format!("`{field1}`, `{field2}` and `{field3}`"),
             _ => {
                 truncated_fields_error =
                     format!(" and {} other field{}", len - 3, pluralize!(len - 3));
                 displayable_field_names
                     .iter()
                     .take(3)
-                    .map(|n| format!("`{}`", n))
+                    .map(|n| format!("`{n}`"))
                     .collect::<Vec<_>>()
                     .join(", ")
             }
@@ -1635,10 +1636,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             truncated_fields_error,
             adt_ty
         );
-        err.span_label(
-            span,
-            format!("missing {}{}", remaining_fields_names, truncated_fields_error),
-        );
+        err.span_label(span, format!("missing {remaining_fields_names}{truncated_fields_error}"));
 
         // If the last field is a range literal, but it isn't supposed to be, then they probably
         // meant to use functional update syntax.
@@ -1693,8 +1691,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.tcx.sess.span_err(
             span,
             &format!(
-                "cannot construct `{}` with struct literal syntax due to inaccessible fields",
-                adt_ty,
+                "cannot construct `{adt_ty}` with struct literal syntax due to inaccessible fields",
             ),
         );
     }
@@ -1807,7 +1804,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             } else {
                                 err.span_label(
                                     field.ident.span,
-                                    format!("`{}` does not have this field", ty),
+                                    format!("`{ty}` does not have this field"),
                                 );
                             }
                             let available_field_names =
@@ -1973,8 +1970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 field.span,
                 expr_t,
                 E0610,
-                "`{}` is a primitive type and therefore doesn't have fields",
-                expr_t
+                "`{expr_t}` is a primitive type and therefore doesn't have fields",
             )
             .emit();
         }
@@ -2018,7 +2014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
         if add_label {
-            err.span_label(field_ident.span, &format!("field not found in `{}`", ty));
+            err.span_label(field_ident.span, &format!("field not found in `{ty}`"));
         }
     }
 
@@ -2077,10 +2073,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.tcx().sess,
             field.span,
             E0616,
-            "field `{}` of {} `{}` is private",
-            field,
-            kind_name,
-            struct_path
+            "field `{field}` of {kind_name} `{struct_path}` is private",
         );
         err.span_label(field.span, "private field");
         // Also check if an accessible method exists, which is often what is meant.
@@ -2088,7 +2081,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             self.suggest_method_call(
                 &mut err,
-                &format!("a method `{}` also exists, call it with parentheses", field),
+                &format!("a method `{field}` also exists, call it with parentheses"),
                 field,
                 expr_t,
                 expr,
@@ -2104,9 +2097,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             field.span,
             expr_t,
             E0615,
-            "attempted to take value of method `{}` on type `{}`",
-            field,
-            expr_t
+            "attempted to take value of method `{field}` on type `{expr_t}`",
         );
         err.span_label(field.span, "method, not a field");
         let expr_is_call =
@@ -2150,27 +2141,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             let mut found = false;
 
-            if let ty::RawPtr(ty_and_mut) = expr_t.kind() {
-                if let ty::Adt(adt_def, _) = ty_and_mut.ty.kind() {
-                    if adt_def.variants().len() == 1
-                        && adt_def
-                            .variants()
-                            .iter()
-                            .next()
-                            .unwrap()
-                            .fields
-                            .iter()
-                            .any(|f| f.ident(self.tcx) == field)
-                    {
-                        if let Some(dot_loc) = expr_snippet.rfind('.') {
-                            found = true;
-                            err.span_suggestion(
-                                expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
-                                "to access the field, dereference first",
-                                format!("(*{})", &expr_snippet[0..dot_loc]),
-                                Applicability::MaybeIncorrect,
-                            );
-                        }
+            if let ty::RawPtr(ty_and_mut) = expr_t.kind()
+                && let ty::Adt(adt_def, _) = ty_and_mut.ty.kind()
+            {
+                if adt_def.variants().len() == 1
+                    && adt_def
+                        .variants()
+                        .iter()
+                        .next()
+                        .unwrap()
+                        .fields
+                        .iter()
+                        .any(|f| f.ident(self.tcx) == field)
+                {
+                    if let Some(dot_loc) = expr_snippet.rfind('.') {
+                        found = true;
+                        err.span_suggestion(
+                            expr.span.with_hi(expr.span.lo() + BytePos::from_usize(dot_loc)),
+                            "to access the field, dereference first",
+                            format!("(*{})", &expr_snippet[0..dot_loc]),
+                            Applicability::MaybeIncorrect,
+                        );
                     }
                 }
             }
@@ -2197,7 +2188,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let param_span = self.tcx.hir().span(param_hir_id);
         let param_name = self.tcx.hir().ty_param_name(param_def_id.expect_local());
 
-        err.span_label(param_span, &format!("type parameter '{}' declared here", param_name));
+        err.span_label(param_span, &format!("type parameter '{param_name}' declared here"));
     }
 
     fn suggest_fields_on_recordish(
@@ -2239,17 +2230,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         if let (Some(len), Ok(user_index)) =
             (len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
+            && let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
         {
-            if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
-                let help = "instead of using tuple indexing, use array indexing";
-                let suggestion = format!("{}[{}]", base, field);
-                let applicability = if len < user_index {
-                    Applicability::MachineApplicable
-                } else {
-                    Applicability::MaybeIncorrect
-                };
-                err.span_suggestion(expr.span, help, suggestion, applicability);
-            }
+            let help = "instead of using tuple indexing, use array indexing";
+            let suggestion = format!("{base}[{field}]");
+            let applicability = if len < user_index {
+                Applicability::MachineApplicable
+            } else {
+                Applicability::MaybeIncorrect
+            };
+            err.span_suggestion(expr.span, help, suggestion, applicability);
         }
     }
 
@@ -2261,8 +2251,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         field: Ident,
     ) {
         if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
-            let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
-            let suggestion = format!("(*{}).{}", base, field);
+            let msg = format!("`{base}` is a raw pointer; try dereferencing it");
+            let suggestion = format!("(*{base}).{field}");
             err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect);
         }
     }
@@ -2281,9 +2271,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             field.span,
             expr_t,
             E0609,
-            "no field `{}` on type `{}`",
-            field,
-            expr_t
+            "no field `{field}` on type `{expr_t}`",
         );
 
         // try to add a suggestion in case the field is a nested field of a field of the Adt
@@ -2307,7 +2295,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     err.span_suggestion_verbose(
                         field.span.shrink_to_lo(),
                         "one of the expressions' fields has a field of the same name",
-                        format!("{}.", field_path_str),
+                        format!("{field_path_str}."),
                         Applicability::MaybeIncorrect,
                     );
                 }
@@ -2419,8 +2407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         expr.span,
                         base_t,
                         E0608,
-                        "cannot index into a value of type `{}`",
-                        base_t
+                        "cannot index into a value of type `{base_t}`",
                     );
                     // Try to give some advice about indexing tuples.
                     if let ty::Tuple(..) = base_t.kind() {
@@ -2434,7 +2421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                     err.span_suggestion(
                                         expr.span,
                                         "to access tuple elements, use",
-                                        format!("{}.{}", snip, i),
+                                        format!("{snip}.{i}"),
                                         Applicability::MachineApplicable,
                                     );
                                     needs_note = false;
@@ -2535,12 +2522,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         self.check_expr_asm_operand(out_expr, false);
                     }
                 }
-                hir::InlineAsmOperand::Const { anon_const } => {
+                hir::InlineAsmOperand::Const { anon_const }
+                | hir::InlineAsmOperand::SymFn { anon_const } => {
                     self.to_const(anon_const);
                 }
-                hir::InlineAsmOperand::Sym { expr } => {
-                    self.check_expr(expr);
-                }
+                hir::InlineAsmOperand::SymStatic { .. } => {}
             }
         }
         if asm.options.contains(ast::InlineAsmOptions::NORETURN) {
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index d403d6e3f33..152be4bd538 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -755,9 +755,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ret: Expectation<'tcx>,
         formal_ret: Ty<'tcx>,
         formal_args: &[Ty<'tcx>],
-    ) -> Vec<Ty<'tcx>> {
+    ) -> Option<Vec<Ty<'tcx>>> {
         let formal_ret = self.resolve_vars_with_obligations(formal_ret);
-        let Some(ret_ty) = expected_ret.only_has_type(self) else { return Vec::new() };
+        let Some(ret_ty) = expected_ret.only_has_type(self) else { return None };
 
         // HACK(oli-obk): This is a hack to keep RPIT and TAIT in sync wrt their behaviour.
         // Without it, the inference
@@ -779,7 +779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() {
                     if let ty::Opaque(def_id, _) = *ty.kind() {
                         if self.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() {
-                            return Vec::new();
+                            return None;
                         }
                     }
                 }
@@ -820,7 +820,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 // Record all the argument types, with the substitutions
                 // produced from the above subtyping unification.
-                Ok(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect())
+                Ok(Some(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect()))
             })
             .unwrap_or_default();
         debug!(?formal_args, ?formal_ret, ?expect_args, ?expected_ret);
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
new file mode 100644
index 00000000000..48a66e8026b
--- /dev/null
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/arg_matrix.rs
@@ -0,0 +1,343 @@
+use std::cmp;
+
+use rustc_middle::ty::error::TypeError;
+
+// An issue that might be found in the compatibility matrix
+enum Issue {
+    /// The given argument is the invalid type for the input
+    Invalid(usize),
+    /// There is a missing input
+    Missing(usize),
+    /// There's a superfluous argument
+    Extra(usize),
+    /// Two arguments should be swapped
+    Swap(usize, usize),
+    /// Several arguments should be reordered
+    Permutation(Vec<Option<usize>>),
+}
+
+#[derive(Clone, Debug)]
+pub(crate) enum Compatibility<'tcx> {
+    Compatible,
+    Incompatible(Option<TypeError<'tcx>>),
+}
+
+/// Similar to `Issue`, but contains some extra information
+pub(crate) enum Error<'tcx> {
+    /// The given argument is the invalid type for the input
+    Invalid(usize, Compatibility<'tcx>),
+    /// There is a missing input
+    Missing(usize),
+    /// There's a superfluous argument
+    Extra(usize),
+    /// Two arguments should be swapped
+    Swap(usize, usize, usize, usize),
+    /// Several arguments should be reordered
+    Permutation(Vec<(usize, usize)>), // dest_arg, dest_input
+}
+
+pub(crate) struct ArgMatrix<'tcx> {
+    input_indexes: Vec<usize>,
+    arg_indexes: Vec<usize>,
+    compatibility_matrix: Vec<Vec<Compatibility<'tcx>>>,
+}
+
+impl<'tcx> ArgMatrix<'tcx> {
+    pub(crate) fn new<F: FnMut(usize, usize) -> Compatibility<'tcx>>(
+        minimum_input_count: usize,
+        provided_arg_count: usize,
+        mut is_compatible: F,
+    ) -> Self {
+        let compatibility_matrix = (0..provided_arg_count)
+            .map(|i| (0..minimum_input_count).map(|j| is_compatible(i, j)).collect())
+            .collect();
+        ArgMatrix {
+            input_indexes: (0..minimum_input_count).collect(),
+            arg_indexes: (0..provided_arg_count).collect(),
+            compatibility_matrix,
+        }
+    }
+
+    /// Remove a given input from consideration
+    fn eliminate_input(&mut self, idx: usize) {
+        self.input_indexes.remove(idx);
+        for row in &mut self.compatibility_matrix {
+            row.remove(idx);
+        }
+    }
+
+    /// Remove a given argument from consideration
+    fn eliminate_arg(&mut self, idx: usize) {
+        self.arg_indexes.remove(idx);
+        self.compatibility_matrix.remove(idx);
+    }
+
+    /// "satisfy" an input with a given arg, removing both from consideration
+    fn satisfy_input(&mut self, input_idx: usize, arg_idx: usize) {
+        self.eliminate_input(input_idx);
+        self.eliminate_arg(arg_idx);
+    }
+
+    fn eliminate_satisfied(&mut self) -> Vec<(usize, usize)> {
+        let mut i = cmp::min(self.input_indexes.len(), self.arg_indexes.len());
+        let mut eliminated = vec![];
+        while i > 0 {
+            let idx = i - 1;
+            if matches!(self.compatibility_matrix[idx][idx], Compatibility::Compatible) {
+                eliminated.push((self.arg_indexes[idx], self.input_indexes[idx]));
+                self.satisfy_input(idx, idx);
+            }
+            i -= 1;
+        }
+        return eliminated;
+    }
+
+    // Check for the above mismatch cases
+    fn find_issue(&self) -> Option<Issue> {
+        let mat = &self.compatibility_matrix;
+        let ai = &self.arg_indexes;
+        let ii = &self.input_indexes;
+
+        for i in 0..cmp::max(ai.len(), ii.len()) {
+            // If we eliminate the last row, any left-over inputs are considered missing
+            if i >= mat.len() {
+                return Some(Issue::Missing(i));
+            }
+            // If we eliminate the last column, any left-over arguments are extra
+            if mat[i].len() == 0 {
+                return Some(Issue::Extra(i));
+            }
+
+            // Make sure we don't pass the bounds of our matrix
+            let is_arg = i < ai.len();
+            let is_input = i < ii.len();
+            if is_arg && is_input && matches!(mat[i][i], Compatibility::Compatible) {
+                // This is a satisfied input, so move along
+                continue;
+            }
+
+            let mut useless = true;
+            let mut unsatisfiable = true;
+            if is_arg {
+                for j in 0..ii.len() {
+                    // If we find at least one input this argument could satisfy
+                    // this argument isn't completely useless
+                    if matches!(mat[i][j], Compatibility::Compatible) {
+                        useless = false;
+                        break;
+                    }
+                }
+            }
+            if is_input {
+                for j in 0..ai.len() {
+                    // If we find at least one argument that could satisfy this input
+                    // this argument isn't unsatisfiable
+                    if matches!(mat[j][i], Compatibility::Compatible) {
+                        unsatisfiable = false;
+                        break;
+                    }
+                }
+            }
+
+            match (is_arg, is_input, useless, unsatisfiable) {
+                // If an input is unsatisfied, and the argument in its position is useless
+                // then the most likely explanation is that we just got the types wrong
+                (true, true, true, true) => return Some(Issue::Invalid(i)),
+                // Otherwise, if an input is useless, then indicate that this is an extra argument
+                (true, _, true, _) => return Some(Issue::Extra(i)),
+                // Otherwise, if an argument is unsatisfiable, indicate that it's missing
+                (_, true, _, true) => return Some(Issue::Missing(i)),
+                (true, true, _, _) => {
+                    // The argument isn't useless, and the input isn't unsatisfied,
+                    // so look for a parameter we might swap it with
+                    // We look for swaps explicitly, instead of just falling back on permutations
+                    // so that cases like (A,B,C,D) given (B,A,D,C) show up as two swaps,
+                    // instead of a large permutation of 4 elements.
+                    for j in 0..cmp::min(ai.len(), ii.len()) {
+                        if i == j || matches!(mat[j][j], Compatibility::Compatible) {
+                            continue;
+                        }
+                        if matches!(mat[i][j], Compatibility::Compatible)
+                            && matches!(mat[j][i], Compatibility::Compatible)
+                        {
+                            return Some(Issue::Swap(i, j));
+                        }
+                    }
+                }
+                _ => {
+                    continue;
+                }
+            };
+        }
+
+        // We didn't find any of the individual issues above, but
+        // there might be a larger permutation of parameters, so we now check for that
+        // by checking for cycles
+        // We use a double option at position i in this vec to represent:
+        // - None: We haven't computed anything about this argument yet
+        // - Some(None): This argument definitely doesn't participate in a cycle
+        // - Some(Some(x)): the i-th argument could permute to the x-th position
+        let mut permutation: Vec<Option<Option<usize>>> = vec![None; mat.len()];
+        let mut permutation_found = false;
+        for i in 0..mat.len() {
+            if permutation[i].is_some() {
+                // We've already decided whether this argument is or is not in a loop
+                continue;
+            }
+
+            let mut stack = vec![];
+            let mut j = i;
+            let mut last = i;
+            let mut is_cycle = true;
+            loop {
+                stack.push(j);
+                // Look for params this one could slot into
+                let compat: Vec<_> =
+                    mat[j]
+                        .iter()
+                        .enumerate()
+                        .filter_map(|(i, c)| {
+                            if matches!(c, Compatibility::Compatible) { Some(i) } else { None }
+                        })
+                        .collect();
+                if compat.len() != 1 {
+                    // this could go into multiple slots, don't bother exploring both
+                    is_cycle = false;
+                    break;
+                }
+                j = compat[0];
+                if stack.contains(&j) {
+                    last = j;
+                    break;
+                }
+            }
+            if stack.len() <= 2 {
+                // If we encounter a cycle of 1 or 2 elements, we'll let the
+                // "satisfy" and "swap" code above handle those
+                is_cycle = false;
+            }
+            // We've built up some chain, some of which might be a cycle
+            // ex: [1,2,3,4]; last = 2; j = 2;
+            // So, we want to mark 4, 3, and 2 as part of a permutation
+            permutation_found = is_cycle;
+            while let Some(x) = stack.pop() {
+                if is_cycle {
+                    permutation[x] = Some(Some(j));
+                    j = x;
+                    if j == last {
+                        // From here on out, we're a tail leading into a cycle,
+                        // not the cycle itself
+                        is_cycle = false;
+                    }
+                } else {
+                    // Some(None) ensures we save time by skipping this argument again
+                    permutation[x] = Some(None);
+                }
+            }
+        }
+
+        if permutation_found {
+            // Map unwrap to remove the first layer of Some
+            let final_permutation: Vec<Option<usize>> =
+                permutation.into_iter().map(|x| x.unwrap()).collect();
+            return Some(Issue::Permutation(final_permutation));
+        }
+        return None;
+    }
+
+    // Obviously, detecting exact user intention is impossible, so the goal here is to
+    // come up with as likely of a story as we can to be helpful.
+    //
+    // We'll iteratively removed "satisfied" input/argument pairs,
+    // then check for the cases above, until we've eliminated the entire grid
+    //
+    // We'll want to know which arguments and inputs these rows and columns correspond to
+    // even after we delete them.
+    pub(crate) fn find_errors(mut self) -> (Vec<Error<'tcx>>, Vec<Option<usize>>) {
+        let provided_arg_count = self.arg_indexes.len();
+
+        let mut errors: Vec<Error<'tcx>> = vec![];
+        // For each expected argument, the matched *actual* input
+        let mut matched_inputs: Vec<Option<usize>> = vec![None; self.input_indexes.len()];
+
+        // Before we start looking for issues, eliminate any arguments that are already satisfied,
+        // so that an argument which is already spoken for by the input it's in doesn't
+        // spill over into another similarly typed input
+        // ex:
+        //   fn some_func(_a: i32, _b: i32) {}
+        //   some_func(1, "");
+        // Without this elimination, the first argument causes the second argument
+        // to show up as both a missing input and extra argument, rather than
+        // just an invalid type.
+        for (arg, inp) in self.eliminate_satisfied() {
+            matched_inputs[inp] = Some(arg);
+        }
+
+        while self.input_indexes.len() > 0 || self.arg_indexes.len() > 0 {
+            // Check for the first relevant issue
+            match self.find_issue() {
+                Some(Issue::Invalid(idx)) => {
+                    let compatibility = self.compatibility_matrix[idx][idx].clone();
+                    let input_idx = self.input_indexes[idx];
+                    self.satisfy_input(idx, idx);
+                    errors.push(Error::Invalid(input_idx, compatibility));
+                }
+                Some(Issue::Extra(idx)) => {
+                    let arg_idx = self.arg_indexes[idx];
+                    self.eliminate_arg(idx);
+                    errors.push(Error::Extra(arg_idx));
+                }
+                Some(Issue::Missing(idx)) => {
+                    let input_idx = self.input_indexes[idx];
+                    self.eliminate_input(idx);
+                    errors.push(Error::Missing(input_idx));
+                }
+                Some(Issue::Swap(idx, other)) => {
+                    let input_idx = self.input_indexes[idx];
+                    let other_input_idx = self.input_indexes[other];
+                    let arg_idx = self.arg_indexes[idx];
+                    let other_arg_idx = self.arg_indexes[other];
+                    let (min, max) = (cmp::min(idx, other), cmp::max(idx, other));
+                    self.satisfy_input(min, max);
+                    // Subtract 1 because we already removed the "min" row
+                    self.satisfy_input(max - 1, min);
+                    errors.push(Error::Swap(input_idx, other_input_idx, arg_idx, other_arg_idx));
+                    matched_inputs[input_idx] = Some(other_arg_idx);
+                    matched_inputs[other_input_idx] = Some(arg_idx);
+                }
+                Some(Issue::Permutation(args)) => {
+                    // FIXME: If satisfy_input ever did anything non-trivial (emit obligations to help type checking, for example)
+                    // we'd want to call this function with the correct arg/input pairs, but for now, we just throw them in a bucket.
+                    // This works because they force a cycle, so each row is guaranteed to also be a column
+                    let mut idxs: Vec<usize> = args.iter().filter_map(|&a| a).collect();
+
+                    let mut real_idxs = vec![None; provided_arg_count];
+                    for (src, dst) in
+                        args.iter().enumerate().filter_map(|(src, dst)| dst.map(|dst| (src, dst)))
+                    {
+                        let src_arg = self.arg_indexes[src];
+                        let dst_arg = self.arg_indexes[dst];
+                        let dest_input = self.input_indexes[dst];
+                        real_idxs[src_arg] = Some((dst_arg, dest_input));
+                        matched_inputs[dest_input] = Some(src_arg);
+                    }
+                    idxs.sort();
+                    idxs.reverse();
+                    for i in idxs {
+                        self.satisfy_input(i, i);
+                    }
+                    errors.push(Error::Permutation(real_idxs.into_iter().flatten().collect()));
+                }
+                None => {
+                    // We didn't find any issues, so we need to push the algorithm forward
+                    // First, eliminate any arguments that currently satisfy their inputs
+                    for (arg, inp) in self.eliminate_satisfied() {
+                        matched_inputs[inp] = Some(arg);
+                    }
+                }
+            };
+        }
+
+        return (errors, matched_inputs);
+    }
+}
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
index f6a5243274c..80f6190732a 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
@@ -1,5 +1,6 @@
 use crate::astconv::AstConv;
 use crate::check::coercion::CoerceMany;
+use crate::check::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error};
 use crate::check::gather_locals::Declaration;
 use crate::check::method::MethodCallee;
 use crate::check::Expectation::*;
@@ -8,6 +9,7 @@ use crate::check::{
     potentially_plural_count, struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt,
     LocalTy, Needs, TupleArgumentsFlag,
 };
+use crate::structured_errors::StructuredDiagnostic;
 
 use rustc_ast as ast;
 use rustc_data_structures::sync::Lrc;
@@ -16,7 +18,11 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{ExprKind, Node, QPath};
+use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt};
+use rustc_infer::infer::InferOk;
+use rustc_infer::infer::TypeTrace;
 use rustc_middle::ty::adjustment::AllowTwoPhase;
+use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::Session;
@@ -24,15 +30,15 @@ use rustc_span::symbol::Ident;
 use rustc_span::{self, Span};
 use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
 
-use crate::structured_errors::StructuredDiagnostic;
 use std::iter;
 use std::slice;
 
-struct FnArgsAsTuple<'hir> {
-    first: &'hir hir::Expr<'hir>,
-    last: &'hir hir::Expr<'hir>,
+enum TupleMatchFound {
+    None,
+    Single,
+    /// Beginning and end Span
+    Multiple(Span, Span),
 }
-
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(in super::super) fn check_casts(&self) {
         let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
@@ -67,7 +73,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 sp,
                 expr,
                 &err_inputs,
-                vec![],
+                None,
                 args_no_rcvr,
                 false,
                 tuple_arguments,
@@ -108,7 +114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Types (as defined in the *signature* of the target function)
         formal_input_tys: &[Ty<'tcx>],
         // More specific expected types, after unifying with caller output types
-        expected_input_tys: Vec<Ty<'tcx>>,
+        expected_input_tys: Option<Vec<Ty<'tcx>>>,
         // The expressions for each provided argument
         provided_args: &'tcx [hir::Expr<'tcx>],
         // Whether the function is variadic, for example when imported from C
@@ -119,10 +125,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         fn_def_id: Option<DefId>,
     ) {
         let tcx = self.tcx;
-        // Grab the argument types, supplying fresh type variables
-        // if the wrong number of arguments were supplied
-        let supplied_arg_count =
-            if tuple_arguments == DontTupleArguments { provided_args.len() } else { 1 };
+
+        // Conceptually, we've got some number of expected inputs, and some number of provided aguments
+        // and we can form a grid of whether each argument could satisfy a given input:
+        //      in1 | in2 | in3 | ...
+        // arg1  ?  |     |     |
+        // arg2     |  ?  |     |
+        // arg3     |     |  ?  |
+        // ...
+        // Initially, we just check the diagonal, because in the case of correct code
+        // these are the only checks that matter
+        // However, in the unhappy path, we'll fill in this whole grid to attempt to provide
+        // better error messages about invalid method calls.
 
         // All the input types from the fn signature must outlive the call
         // so as to validate implied bounds.
@@ -130,11 +144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
         }
 
-        let expected_arg_count = formal_input_tys.len();
-
-        // expected_count, arg_count, error_code, sugg_unit, sugg_tuple_wrap_args
-        let mut arg_count_error: Option<(usize, usize, &str, bool, Option<FnArgsAsTuple<'_>>)> =
-            None;
+        let mut err_code = "E0061";
 
         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
         let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
@@ -144,15 +154,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ty::Tuple(arg_types) => {
                     // Argument length differs
                     if arg_types.len() != provided_args.len() {
-                        arg_count_error =
-                            Some((arg_types.len(), provided_args.len(), "E0057", false, None));
+                        err_code = "E0057";
                     }
-                    let expected_input_tys = match expected_input_tys.get(0) {
-                        Some(&ty) => match ty.kind() {
-                            ty::Tuple(tys) => tys.iter().collect(),
-                            _ => vec![],
+                    let expected_input_tys = match expected_input_tys {
+                        Some(expected_input_tys) => match expected_input_tys.get(0) {
+                            Some(ty) => match ty.kind() {
+                                ty::Tuple(tys) => Some(tys.iter().collect()),
+                                _ => None,
+                            },
+                            None => None,
                         },
-                        None => vec![],
+                        None => None,
                     };
                     (arg_types.iter().collect(), expected_input_tys)
                 }
@@ -167,67 +179,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                          for the function trait is neither a tuple nor unit"
                     )
                     .emit();
-                    (self.err_args(provided_args.len()), vec![])
+                    (self.err_args(provided_args.len()), None)
                 }
             }
-        } else if expected_arg_count == supplied_arg_count {
-            (formal_input_tys.to_vec(), expected_input_tys)
-        } else if c_variadic {
-            if supplied_arg_count >= expected_arg_count {
-                (formal_input_tys.to_vec(), expected_input_tys)
-            } else {
-                arg_count_error =
-                    Some((expected_arg_count, supplied_arg_count, "E0060", false, None));
-                (self.err_args(supplied_arg_count), vec![])
-            }
         } else {
-            // is the missing argument of type `()`?
-            let sugg_unit = if expected_input_tys.len() == 1 && supplied_arg_count == 0 {
-                self.resolve_vars_if_possible(expected_input_tys[0]).is_unit()
-            } else if formal_input_tys.len() == 1 && supplied_arg_count == 0 {
-                self.resolve_vars_if_possible(formal_input_tys[0]).is_unit()
-            } else {
-                false
-            };
-
-            // are we passing elements of a tuple without the tuple parentheses?
-            let expected_input_tys = if expected_input_tys.is_empty() {
-                // In most cases we can use expected_input_tys, but some callers won't have the type
-                // information, in which case we fall back to the types from the input expressions.
-                formal_input_tys
-            } else {
-                &*expected_input_tys
-            };
-
-            let sugg_tuple_wrap_args = self.suggested_tuple_wrap(expected_input_tys, provided_args);
-
-            arg_count_error = Some((
-                expected_arg_count,
-                supplied_arg_count,
-                "E0061",
-                sugg_unit,
-                sugg_tuple_wrap_args,
-            ));
-            (self.err_args(supplied_arg_count), vec![])
+            (formal_input_tys.to_vec(), expected_input_tys)
         };
 
-        debug!(
-            "check_argument_types: formal_input_tys={:?}",
-            formal_input_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
-        );
-
-        // If there is no expectation, expect formal_input_tys.
-        let expected_input_tys = if !expected_input_tys.is_empty() {
+        // If there are no external expectations at the call site, just use the types from the function defn
+        let expected_input_tys = if let Some(expected_input_tys) = expected_input_tys {
+            assert_eq!(expected_input_tys.len(), formal_input_tys.len());
             expected_input_tys
         } else {
             formal_input_tys.clone()
         };
 
-        assert_eq!(expected_input_tys.len(), formal_input_tys.len());
-
-        let provided_arg_count: usize = provided_args.len();
+        let minimum_input_count = expected_input_tys.len();
+        let provided_arg_count = provided_args.len();
 
-        // Keep track of the fully coerced argument types
+        // We'll also want to keep track of the fully coerced argument types, for an awkward hack near the end
         let mut final_arg_types: Vec<Option<(Ty<'_>, Ty<'_>)>> = vec![None; provided_arg_count];
 
         // We introduce a helper function to demand that a given argument satisfy a given input
@@ -240,8 +210,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
 
-            // The special-cased logic below has three functions:
-            // 1. Provide as good of an expected type as possible.
+            // We're on the happy path here, so we'll do a more involved check and write back types
+            // To check compatibility, we'll do 3 things:
+            // 1. Unify the provided argument with the expected type
             let expectation = Expectation::rvalue_hint(self, expected_input_ty);
 
             let checked_ty = self.check_expr_with_expectation(provided_arg, expectation);
@@ -255,8 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             final_arg_types[idx] = Some((checked_ty, coerced_ty));
 
             // Cause selection errors caused by resolving a single argument to point at the
-            // argument and not the call. This is otherwise redundant with the `demand_coerce`
-            // call immediately after, but it lets us customize the span pointed to in the
+            // argument and not the call. This lets us customize the span pointed to in the
             // fulfillment error to be more accurate.
             let coerced_ty =
                 self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| {
@@ -270,18 +240,95 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 });
 
+            // Make sure we store the resolved type
             final_arg_types[idx] = Some((checked_ty, coerced_ty));
 
-            // We're processing function arguments so we definitely want to use
-            // two-phase borrows.
-            self.demand_coerce(&provided_arg, checked_ty, coerced_ty, None, AllowTwoPhase::Yes);
+            let coerce_error = self
+                .try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
+                .err();
+
+            if coerce_error.is_some() {
+                return Compatibility::Incompatible(coerce_error);
+            }
+
+            // 3. Check if the formal type is a supertype of the checked one
+            //    and register any such obligations for future type checks
+            let supertype_error = self
+                .at(&self.misc(provided_arg.span), self.param_env)
+                .sup(formal_input_ty, coerced_ty);
+            let subtyping_error = match supertype_error {
+                Ok(InferOk { obligations, value: () }) => {
+                    self.register_predicates(obligations);
+                    None
+                }
+                Err(err) => Some(err),
+            };
 
-            // 3. Relate the expected type and the formal one,
-            //    if the expected type was used for the coercion.
-            self.demand_suptype(provided_arg.span, formal_input_ty, coerced_ty);
+            // If neither check failed, the types are compatible
+            match subtyping_error {
+                None => Compatibility::Compatible,
+                Some(_) => Compatibility::Incompatible(subtyping_error),
+            }
         };
 
-        let minimum_input_count = formal_input_tys.len();
+        // A "softer" version of the helper above, which checks types without persisting them,
+        // and treats error types differently
+        // This will allow us to "probe" for other argument orders that would likely have been correct
+        let check_compatible = |arg_idx, input_idx| {
+            let formal_input_ty: Ty<'tcx> = formal_input_tys[input_idx];
+            let expected_input_ty: Ty<'tcx> = expected_input_tys[input_idx];
+
+            // If either is an error type, we defy the usual convention and consider them to *not* be
+            // coercible.  This prevents our error message heuristic from trying to pass errors into
+            // every argument.
+            if formal_input_ty.references_error() || expected_input_ty.references_error() {
+                return Compatibility::Incompatible(None);
+            }
+
+            let provided_arg: &hir::Expr<'tcx> = &provided_args[arg_idx];
+            let expectation = Expectation::rvalue_hint(self, expected_input_ty);
+            // FIXME: check that this is safe; I don't believe this commits any of the obligations, but I can't be sure.
+            //
+            //   I had another method of "soft" type checking before,
+            //   but it was failing to find the type of some expressions (like "")
+            //   so I prodded this method and made it pub(super) so I could call it, and it seems to work well.
+            let checked_ty = self.check_expr_kind(provided_arg, expectation);
+
+            let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
+            let can_coerce = self.can_coerce(checked_ty, coerced_ty);
+
+            if !can_coerce {
+                return Compatibility::Incompatible(None);
+            }
+
+            let subtyping_result = self
+                .at(&self.misc(provided_arg.span), self.param_env)
+                .sup(formal_input_ty, coerced_ty);
+
+            // Same as above: if either the coerce type or the checked type is an error type,
+            // consider them *not* compatible.
+            let coercible =
+                !coerced_ty.references_error() && !checked_ty.references_error() && can_coerce;
+
+            match (coercible, &subtyping_result) {
+                (true, Ok(_)) => Compatibility::Compatible,
+                _ => Compatibility::Incompatible(subtyping_result.err()),
+            }
+        };
+
+        // To start, we only care "along the diagonal", where we expect every
+        // provided arg to be in the right spot
+        let mut compatibility = vec![Compatibility::Incompatible(None); provided_args.len()];
+
+        // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path
+        // if the wrong number of arguments were supplied, we CAN'T be satisfied,
+        // and if we're c_variadic, the supplied arguments must be >= the minimum count from the function
+        // otherwise, they need to be identical, because rust doesn't currently support variadic functions
+        let mut call_appears_satisfied = if c_variadic {
+            provided_arg_count >= minimum_input_count
+        } else {
+            provided_arg_count == minimum_input_count
+        };
 
         // Check the arguments.
         // We do this in a pretty awful way: first we type-check any arguments
@@ -305,6 +352,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 })
             }
 
+            // Check each argument, to satisfy the input it was provided for
+            // Visually, we're traveling down the diagonal of the compatibility matrix
             for (idx, arg) in provided_args.iter().enumerate() {
                 // Warn only for the first loop (the "no closures" one).
                 // Closure arguments themselves can't be diverging, but
@@ -327,15 +376,82 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     continue;
                 }
 
-                demand_compatible(idx, &mut final_arg_types);
+                let compatible = demand_compatible(idx, &mut final_arg_types);
+                let is_compatible = matches!(compatible, Compatibility::Compatible);
+                compatibility[idx] = compatible;
+
+                if !is_compatible {
+                    call_appears_satisfied = false;
+                }
             }
         }
 
-        // If there was an error in parameter count, emit that here
-        if let Some((expected_count, arg_count, err_code, sugg_unit, sugg_tuple_wrap_args)) =
-            arg_count_error
-        {
-            let (span, start_span, args, ctor_of) = match &call_expr.kind {
+        // Logic here is a bit hairy
+        'errors: {
+            // If something above didn't typecheck, we've fallen off the happy path
+            // and we should make some effort to provide better error messages
+            if call_appears_satisfied {
+                break 'errors;
+            }
+
+            // The algorithm here is inspired by levenshtein distance and longest common subsequence.
+            // We'll try to detect 4 different types of mistakes:
+            // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
+            // - An input is missing, which isn't satisfied by *any* of the other arguments
+            // - Some number of arguments have been provided in the wrong order
+            // - A type is straight up invalid
+
+            // First, let's find the errors
+            let mut compatibility: Vec<_> = compatibility.into_iter().map(Some).collect();
+            let (mut errors, matched_inputs) =
+                ArgMatrix::new(minimum_input_count, provided_arg_count, |i, j| {
+                    if i == j { compatibility[i].take().unwrap() } else { check_compatible(i, j) }
+                })
+                .find_errors();
+
+            // Okay, so here's where it gets complicated in regards to what errors
+            // we emit and how.
+            // There are 3 different "types" of errors we might encounter.
+            //   1) Missing/extra/swapped arguments
+            //   2) Valid but incorrect arguments
+            //   3) Invalid arguments
+            //      - Currently I think this only comes up with `CyclicTy`
+            //
+            // We first need to go through, remove those from (3) and emit those
+            // as their own error, particularly since they're error code and
+            // message is special. From what I can tell, we *must* emit these
+            // here (vs somewhere prior to this function) since the arguments
+            // become invalid *because* of how they get used in the function.
+            // It is what it is.
+
+            let found_errors = !errors.is_empty();
+
+            errors.drain_filter(|error| {
+                let Error::Invalid(input_idx, Compatibility::Incompatible(error)) = error else { return false };
+                let expected_ty = expected_input_tys[*input_idx];
+                let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
+                let cause = &self.misc(provided_args[*input_idx].span);
+                let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                if let Some(e) = error {
+                    if !matches!(trace.cause.as_failure_code(e), FailureCode::Error0308(_)) {
+                        self.report_and_explain_type_error(trace, e).emit();
+                        return true;
+                    }
+                }
+                false
+            });
+
+            // We're done if we found errors, but we already emitted them.
+            // I don't think we *should* be able to enter this bit of code
+            // (`!call_appears_satisfied`) without *also* finding errors, but we
+            // don't want to accidentally not emit an error if there is some
+            // logic bug in the `ArgMatrix` code.
+            if found_errors && errors.is_empty() {
+                break 'errors;
+            }
+
+            // Next, let's construct the error
+            let (error_span, full_call_span, ctor_of) = match &call_expr.kind {
                 hir::ExprKind::Call(
                     hir::Expr {
                         span,
@@ -346,67 +462,484 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             )),
                         ..
                     },
-                    args,
-                ) => (*span, *span, &args[..], Some(of)),
-                hir::ExprKind::Call(hir::Expr { span, .. }, args) => {
-                    (*span, *span, &args[..], None)
+                    _,
+                ) => (call_span, *span, Some(of)),
+                hir::ExprKind::Call(hir::Expr { span, .. }, _) => (call_span, *span, None),
+                hir::ExprKind::MethodCall(path_segment, _, span) => {
+                    let ident_span = path_segment.ident.span;
+                    let ident_span = if let Some(args) = path_segment.args {
+                        ident_span.with_hi(args.span_ext.hi())
+                    } else {
+                        ident_span
+                    };
+                    (
+                        *span, ident_span, None, // methods are never ctors
+                    )
                 }
-                hir::ExprKind::MethodCall(path_segment, args, _) => (
-                    path_segment.ident.span,
-                    // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
-                    path_segment
-                        .args
-                        .and_then(|args| args.args.iter().last())
-                        // Account for `foo.bar::<T>()`.
-                        .map(|arg| {
-                            // Skip the closing `>`.
-                            tcx.sess
-                                .source_map()
-                                .next_point(tcx.sess.source_map().next_point(arg.span()))
-                        })
-                        .unwrap_or(path_segment.ident.span),
-                    &args[1..], // Skip the receiver.
-                    None,       // methods are never ctors
-                ),
                 k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
             };
-            let arg_spans = if provided_args.is_empty() {
-                // foo()
-                // ^^^-- supplied 0 arguments
-                // |
-                // expected 2 arguments
-                vec![tcx.sess.source_map().next_point(start_span).with_hi(call_span.hi())]
-            } else {
-                // foo(1, 2, 3)
-                // ^^^ -  -  - supplied 3 arguments
-                // |
-                // expected 2 arguments
-                args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
-            };
+            let args_span = error_span.trim_start(full_call_span).unwrap_or(error_span);
             let call_name = match ctor_of {
                 Some(CtorOf::Struct) => "struct",
                 Some(CtorOf::Variant) => "enum variant",
                 None => "function",
             };
-            let mut err = tcx.sess.struct_span_err_with_code(
-                span,
-                &format!(
-                    "this {} takes {}{} but {} {} supplied",
+            if c_variadic && provided_arg_count < minimum_input_count {
+                err_code = "E0060";
+            }
+
+            // Next special case: The case where we expect a single tuple and
+            // wrapping all the args in parentheses (or adding a comma to
+            // already existing parentheses) will result in a tuple that
+            // satisfies the call.
+            // This isn't super ideal code, because we copy code from elsewhere
+            // and somewhat duplicate this. We also delegate to the general type
+            // mismatch suggestions for the single arg case.
+            let sugg_tuple_wrap_args =
+                self.suggested_tuple_wrap(&expected_input_tys, provided_args);
+            match sugg_tuple_wrap_args {
+                TupleMatchFound::None => {}
+                TupleMatchFound::Single => {
+                    let expected_ty = expected_input_tys[0];
+                    let provided_ty = final_arg_types[0].map(|ty| ty.0).unwrap();
+                    let cause = &self.misc(provided_args[0].span);
+                    let compatibility = demand_compatible(0, &mut final_arg_types);
+                    let type_error = match compatibility {
+                        Compatibility::Incompatible(Some(error)) => error,
+                        _ => TypeError::Mismatch,
+                    };
+                    let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                    let mut err = self.report_and_explain_type_error(trace, &type_error);
+                    self.emit_coerce_suggestions(
+                        &mut err,
+                        &provided_args[0],
+                        final_arg_types[0].map(|ty| ty.0).unwrap(),
+                        final_arg_types[0].map(|ty| ty.1).unwrap(),
+                        None,
+                        None,
+                    );
+                    err.span_label(
+                        full_call_span,
+                        format!("arguments to this {} are incorrect", call_name),
+                    );
+                    // Call out where the function is defined
+                    if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
+                        let mut spans: MultiSpan = def_span.into();
+
+                        let params = tcx
+                            .hir()
+                            .get_if_local(def_id)
+                            .and_then(|node| node.body_id())
+                            .into_iter()
+                            .map(|id| tcx.hir().body(id).params)
+                            .flatten();
+
+                        for param in params {
+                            spans.push_span_label(param.span, String::new());
+                        }
+
+                        let def_kind = tcx.def_kind(def_id);
+                        err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+                    }
+                    err.emit();
+                    break 'errors;
+                }
+                TupleMatchFound::Multiple(start, end) => {
+                    let mut err = tcx.sess.struct_span_err_with_code(
+                        full_call_span,
+                        &format!(
+                            "this {} takes {}{} but {} {} supplied",
+                            call_name,
+                            if c_variadic { "at least " } else { "" },
+                            potentially_plural_count(minimum_input_count, "argument"),
+                            potentially_plural_count(provided_arg_count, "argument"),
+                            if provided_arg_count == 1 { "was" } else { "were" }
+                        ),
+                        DiagnosticId::Error(err_code.to_owned()),
+                    );
+                    // Call out where the function is defined
+                    if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
+                        let mut spans: MultiSpan = def_span.into();
+
+                        let params = tcx
+                            .hir()
+                            .get_if_local(def_id)
+                            .and_then(|node| node.body_id())
+                            .into_iter()
+                            .map(|id| tcx.hir().body(id).params)
+                            .flatten();
+
+                        for param in params {
+                            spans.push_span_label(param.span, String::new());
+                        }
+
+                        let def_kind = tcx.def_kind(def_id);
+                        err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+                    }
+                    err.multipart_suggestion(
+                        "use parentheses to construct a tuple",
+                        vec![(start, '('.to_string()), (end, ')'.to_string())],
+                        Applicability::MachineApplicable,
+                    );
+                    err.emit();
+                    break 'errors;
+                }
+            }
+
+            // Okay, now that we've emitted the special errors separately, we
+            // are only left missing/extra/swapped and mismatched arguments, both
+            // can be collated pretty easily if needed.
+
+            // Next special case: if there is only one "Incompatible" error, just emit that
+            if errors.len() == 1 {
+                if let Some(Error::Invalid(input_idx, Compatibility::Incompatible(Some(error)))) =
+                    errors.iter().next()
+                {
+                    let expected_ty = expected_input_tys[*input_idx];
+                    let provided_ty = final_arg_types[*input_idx].map(|ty| ty.0).unwrap();
+                    let cause = &self.misc(provided_args[*input_idx].span);
+                    let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                    let mut err = self.report_and_explain_type_error(trace, error);
+                    self.emit_coerce_suggestions(
+                        &mut err,
+                        &provided_args[*input_idx],
+                        final_arg_types[*input_idx].map(|ty| ty.0).unwrap(),
+                        final_arg_types[*input_idx].map(|ty| ty.1).unwrap(),
+                        None,
+                        None,
+                    );
+                    err.span_label(
+                        full_call_span,
+                        format!("arguments to this {} are incorrect", call_name),
+                    );
+                    // Call out where the function is defined
+                    if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
+                        let mut spans: MultiSpan = def_span.into();
+
+                        let params = tcx
+                            .hir()
+                            .get_if_local(def_id)
+                            .and_then(|node| node.body_id())
+                            .into_iter()
+                            .map(|id| tcx.hir().body(id).params)
+                            .flatten();
+
+                        for param in params {
+                            spans.push_span_label(param.span, String::new());
+                        }
+
+                        let def_kind = tcx.def_kind(def_id);
+                        err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
+                    }
+                    err.emit();
+                    break 'errors;
+                }
+            }
+
+            let mut err = if minimum_input_count == provided_arg_count {
+                struct_span_err!(
+                    tcx.sess,
+                    full_call_span,
+                    E0308,
+                    "arguments to this {} are incorrect",
                     call_name,
-                    if c_variadic { "at least " } else { "" },
-                    potentially_plural_count(expected_count, "argument"),
-                    potentially_plural_count(arg_count, "argument"),
-                    if arg_count == 1 { "was" } else { "were" }
-                ),
-                DiagnosticId::Error(err_code.to_owned()),
-            );
-            let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
-            for (i, span) in arg_spans.into_iter().enumerate() {
-                err.span_label(
-                    span,
-                    if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
-                );
+                )
+            } else {
+                tcx.sess.struct_span_err_with_code(
+                    full_call_span,
+                    &format!(
+                        "this {} takes {}{} but {} {} supplied",
+                        call_name,
+                        if c_variadic { "at least " } else { "" },
+                        potentially_plural_count(minimum_input_count, "argument"),
+                        potentially_plural_count(provided_arg_count, "argument"),
+                        if provided_arg_count == 1 { "was" } else { "were" }
+                    ),
+                    DiagnosticId::Error(err_code.to_owned()),
+                )
+            };
+
+            // As we encounter issues, keep track of what we want to provide for the suggestion
+            let mut labels = vec![];
+            // If there is a single error, we give a specific suggestion; otherwise, we change to
+            // "did you mean" with the suggested function call
+            enum SuggestionText {
+                None,
+                Provide(bool),
+                Remove(bool),
+                Swap,
+                Reorder,
+                DidYouMean,
             }
+            let mut suggestion_text = SuggestionText::None;
+
+            let mut errors = errors.into_iter().peekable();
+            while let Some(error) = errors.next() {
+                match error {
+                    Error::Invalid(input_idx, compatibility) => {
+                        let expected_ty = expected_input_tys[input_idx];
+                        if let Compatibility::Incompatible(error) = &compatibility {
+                            let provided_ty = final_arg_types[input_idx].map(|ty| ty.0).unwrap();
+                            let cause = &self.misc(provided_args[input_idx].span);
+                            let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
+                            if let Some(e) = error {
+                                self.note_type_err(
+                                    &mut err,
+                                    &trace.cause,
+                                    None,
+                                    Some(trace.values),
+                                    e,
+                                    false,
+                                    true,
+                                );
+                            }
+                        }
+
+                        self.emit_coerce_suggestions(
+                            &mut err,
+                            &provided_args[input_idx],
+                            final_arg_types[input_idx].map(|ty| ty.0).unwrap(),
+                            final_arg_types[input_idx].map(|ty| ty.1).unwrap(),
+                            None,
+                            None,
+                        );
+                    }
+                    Error::Extra(arg_idx) => {
+                        let arg_type = if let Some((_, ty)) = final_arg_types[arg_idx] {
+                            if ty.references_error() || ty.has_infer_types() {
+                                "".into()
+                            } else {
+                                format!(" of type `{}`", ty)
+                            }
+                        } else {
+                            "".into()
+                        };
+                        labels.push((
+                            provided_args[arg_idx].span,
+                            format!("argument{} unexpected", arg_type),
+                        ));
+                        suggestion_text = match suggestion_text {
+                            SuggestionText::None => SuggestionText::Remove(false),
+                            SuggestionText::Remove(_) => SuggestionText::Remove(true),
+                            _ => SuggestionText::DidYouMean,
+                        };
+                    }
+                    Error::Missing(input_idx) => {
+                        // If there are multiple missing arguments adjacent to each other,
+                        // then we can provide a single error.
+
+                        let mut missing_idxs = vec![input_idx];
+                        while let Some(e) = errors.next_if(|e| matches!(e, Error::Missing(input_idx) if *input_idx == (missing_idxs.last().unwrap() + 1))) {
+                            match e {
+                                Error::Missing(input_idx) => missing_idxs.push(input_idx),
+                                _ => unreachable!(),
+                            }
+                        }
+
+                        // NOTE: Because we might be re-arranging arguments, might have extra
+                        // arguments, etc. it's hard to *really* know where we should provide
+                        // this error label, so as a heuristic, we point to the provided arg, or
+                        // to the call if the missing inputs pass the provided args.
+                        match &missing_idxs[..] {
+                            &[input_idx] => {
+                                let expected_ty = expected_input_tys[input_idx];
+                                let input_ty = self.resolve_vars_if_possible(expected_ty);
+                                let span = if input_idx < provided_arg_count {
+                                    let arg_span = provided_args[input_idx].span;
+                                    Span::new(arg_span.lo(), arg_span.hi(), arg_span.ctxt(), None)
+                                } else {
+                                    args_span
+                                };
+                                let arg_type =
+                                    if input_ty.references_error() || input_ty.has_infer_types() {
+                                        "".into()
+                                    } else {
+                                        format!(" of type `{}`", input_ty)
+                                    };
+                                labels.push((span, format!("an argument{} is missing", arg_type)));
+                                suggestion_text = match suggestion_text {
+                                    SuggestionText::None => SuggestionText::Provide(false),
+                                    SuggestionText::Provide(_) => SuggestionText::Provide(true),
+                                    _ => SuggestionText::DidYouMean,
+                                };
+                            }
+                            &[first_idx, second_idx] => {
+                                let first_input_ty =
+                                    self.resolve_vars_if_possible(expected_input_tys[first_idx]);
+                                let second_input_ty =
+                                    self.resolve_vars_if_possible(expected_input_tys[second_idx]);
+
+                                let span = if second_idx < provided_arg_count {
+                                    let first_arg_span = provided_args[first_idx].span;
+                                    let second_arg_span = provided_args[second_idx].span;
+                                    Span::new(
+                                        first_arg_span.lo(),
+                                        second_arg_span.hi(),
+                                        first_arg_span.ctxt(),
+                                        None,
+                                    )
+                                } else {
+                                    args_span
+                                };
+                                let any_unnameable = false
+                                    || first_input_ty.references_error()
+                                    || first_input_ty.has_infer_types()
+                                    || second_input_ty.references_error()
+                                    || second_input_ty.has_infer_types();
+                                let arg_type = if any_unnameable {
+                                    "".into()
+                                } else {
+                                    format!(
+                                        " of type `{}` and `{}`",
+                                        first_input_ty, second_input_ty
+                                    )
+                                };
+                                labels
+                                    .push((span, format!("two arguments{} are missing", arg_type)));
+                                suggestion_text = match suggestion_text {
+                                    SuggestionText::None | SuggestionText::Provide(_) => {
+                                        SuggestionText::Provide(true)
+                                    }
+                                    _ => SuggestionText::DidYouMean,
+                                };
+                            }
+                            &[first_idx, second_idx, third_idx] => {
+                                let first_input_ty =
+                                    self.resolve_vars_if_possible(expected_input_tys[first_idx]);
+                                let second_input_ty =
+                                    self.resolve_vars_if_possible(expected_input_tys[second_idx]);
+                                let third_input_ty =
+                                    self.resolve_vars_if_possible(expected_input_tys[second_idx]);
+                                let span = if third_idx < provided_arg_count {
+                                    let first_arg_span = provided_args[first_idx].span;
+                                    let third_arg_span = provided_args[third_idx].span;
+                                    Span::new(
+                                        first_arg_span.lo(),
+                                        third_arg_span.hi(),
+                                        first_arg_span.ctxt(),
+                                        None,
+                                    )
+                                } else {
+                                    args_span
+                                };
+                                let any_unnameable = false
+                                    || first_input_ty.references_error()
+                                    || first_input_ty.has_infer_types()
+                                    || second_input_ty.references_error()
+                                    || second_input_ty.has_infer_types()
+                                    || third_input_ty.references_error()
+                                    || third_input_ty.has_infer_types();
+                                let arg_type = if any_unnameable {
+                                    "".into()
+                                } else {
+                                    format!(
+                                        " of type `{}`, `{}`, and `{}`",
+                                        first_input_ty, second_input_ty, third_input_ty
+                                    )
+                                };
+                                labels.push((
+                                    span,
+                                    format!("three arguments{} are missing", arg_type),
+                                ));
+                                suggestion_text = match suggestion_text {
+                                    SuggestionText::None | SuggestionText::Provide(_) => {
+                                        SuggestionText::Provide(true)
+                                    }
+                                    _ => SuggestionText::DidYouMean,
+                                };
+                            }
+                            missing_idxs => {
+                                let first_idx = *missing_idxs.first().unwrap();
+                                let second_idx = *missing_idxs.last().unwrap();
+                                // NOTE: Because we might be re-arranging arguments, might have extra arguments, etc.
+                                // It's hard to *really* know where we should provide this error label, so this is a
+                                // decent heuristic
+                                let span = if first_idx < provided_arg_count {
+                                    let first_arg_span = provided_args[first_idx].span;
+                                    let second_arg_span = provided_args[second_idx].span;
+                                    Span::new(
+                                        first_arg_span.lo(),
+                                        second_arg_span.hi(),
+                                        first_arg_span.ctxt(),
+                                        None,
+                                    )
+                                } else {
+                                    // Otherwise just label the whole function
+                                    args_span
+                                };
+                                labels.push((span, format!("multiple arguments are missing")));
+                                suggestion_text = match suggestion_text {
+                                    SuggestionText::None | SuggestionText::Provide(_) => {
+                                        SuggestionText::Provide(true)
+                                    }
+                                    _ => SuggestionText::DidYouMean,
+                                };
+                            }
+                        }
+                    }
+                    Error::Swap(input_idx, other_input_idx, arg_idx, other_arg_idx) => {
+                        let first_span = provided_args[arg_idx].span;
+                        let second_span = provided_args[other_arg_idx].span;
+
+                        let first_expected_ty =
+                            self.resolve_vars_if_possible(expected_input_tys[input_idx]);
+                        let first_provided_ty = if let Some((ty, _)) = final_arg_types[arg_idx] {
+                            format!(",found `{}`", ty)
+                        } else {
+                            "".into()
+                        };
+                        labels.push((
+                            first_span,
+                            format!("expected `{}`{}", first_expected_ty, first_provided_ty),
+                        ));
+                        let other_expected_ty =
+                            self.resolve_vars_if_possible(expected_input_tys[other_input_idx]);
+                        let other_provided_ty =
+                            if let Some((ty, _)) = final_arg_types[other_arg_idx] {
+                                format!(",found `{}`", ty)
+                            } else {
+                                "".into()
+                            };
+                        labels.push((
+                            second_span,
+                            format!("expected `{}`{}", other_expected_ty, other_provided_ty),
+                        ));
+                        suggestion_text = match suggestion_text {
+                            SuggestionText::None => SuggestionText::Swap,
+                            _ => SuggestionText::DidYouMean,
+                        };
+                    }
+                    Error::Permutation(args) => {
+                        for (dst_arg, dest_input) in args {
+                            let expected_ty =
+                                self.resolve_vars_if_possible(expected_input_tys[dest_input]);
+                            let provided_ty = if let Some((ty, _)) = final_arg_types[dst_arg] {
+                                format!(",found `{}`", ty)
+                            } else {
+                                "".into()
+                            };
+                            labels.push((
+                                provided_args[dst_arg].span,
+                                format!("expected `{}`{}", expected_ty, provided_ty),
+                            ));
+                        }
+
+                        suggestion_text = match suggestion_text {
+                            SuggestionText::None => SuggestionText::Reorder,
+                            _ => SuggestionText::DidYouMean,
+                        };
+                    }
+                }
+            }
+
+            // If we have less than 5 things to say, it would be useful to call out exactly what's wrong
+            if labels.len() <= 5 {
+                for (span, label) in labels {
+                    err.span_label(span, label);
+                }
+            }
+
+            // Call out where the function is defined
             if let Some(def_id) = fn_def_id && let Some(def_span) = tcx.def_ident_span(def_id) {
                 let mut spans: MultiSpan = def_span.into();
 
@@ -415,8 +948,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .get_if_local(def_id)
                     .and_then(|node| node.body_id())
                     .into_iter()
-                    .map(|id| tcx.hir().body(id).params)
-                    .flatten();
+                    .flat_map(|id| tcx.hir().body(id).params)
+                    ;
 
                 for param in params {
                     spans.push_span_label(param.span, String::new());
@@ -425,33 +958,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let def_kind = tcx.def_kind(def_id);
                 err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
             }
-            if sugg_unit {
-                let sugg_span = tcx.sess.source_map().end_point(call_expr.span);
-                // remove closing `)` from the span
-                let sugg_span = sugg_span.shrink_to_lo();
-                err.span_suggestion(
-                    sugg_span,
-                    "expected the unit value `()`; create it with empty parentheses",
-                    String::from("()"),
-                    Applicability::MachineApplicable,
-                );
-            } else if let Some(FnArgsAsTuple { first, last }) = sugg_tuple_wrap_args {
-                err.multipart_suggestion(
-                    "use parentheses to construct a tuple",
-                    vec![
-                        (first.span.shrink_to_lo(), '('.to_string()),
-                        (last.span.shrink_to_hi(), ')'.to_string()),
-                    ],
-                    Applicability::MachineApplicable,
+
+            // And add a suggestion block for all of the parameters
+            let suggestion_text = match suggestion_text {
+                SuggestionText::None => None,
+                SuggestionText::Provide(plural) => {
+                    Some(format!("provide the argument{}", if plural { "s" } else { "" }))
+                }
+                SuggestionText::Remove(plural) => {
+                    Some(format!("remove the extra argument{}", if plural { "s" } else { "" }))
+                }
+                SuggestionText::Swap => Some(format!("swap these arguments")),
+                SuggestionText::Reorder => Some(format!("reorder these arguments")),
+                SuggestionText::DidYouMean => Some(format!("did you mean")),
+            };
+            if let Some(suggestion_text) = suggestion_text {
+                let source_map = self.sess().source_map();
+                let mut suggestion = format!(
+                    "{}(",
+                    source_map.span_to_snippet(full_call_span).unwrap_or_else(|_| String::new())
                 );
-            } else {
-                err.span_label(
-                    span,
-                    format!(
-                        "expected {}{}",
-                        if c_variadic { "at least " } else { "" },
-                        potentially_plural_count(expected_count, "argument")
-                    ),
+                for (idx, arg) in matched_inputs.iter().enumerate() {
+                    let suggestion_text = if let Some(arg) = arg {
+                        let arg_span = provided_args[*arg].span;
+                        let arg_text = source_map.span_to_snippet(arg_span).unwrap();
+                        arg_text
+                    } else {
+                        // Propose a placeholder of the correct type
+                        let expected_ty = expected_input_tys[idx];
+                        let input_ty = self.resolve_vars_if_possible(expected_ty);
+                        if input_ty.is_unit() {
+                            "()".to_string()
+                        } else {
+                            format!("{{{}}}", input_ty)
+                        }
+                    };
+                    suggestion += &suggestion_text;
+                    if idx < minimum_input_count - 1 {
+                        suggestion += ", ";
+                    }
+                }
+                suggestion += ")";
+                err.span_suggestion_verbose(
+                    error_span,
+                    &suggestion_text,
+                    suggestion,
+                    Applicability::HasPlaceholders,
                 );
             }
             err.emit();
@@ -460,10 +1012,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         for arg in provided_args.iter().skip(minimum_input_count) {
             let arg_ty = self.check_expr(&arg);
 
+            // If the function is c-style variadic, we skipped a bunch of arguments
+            // so we need to check those, and write out the types
+            // Ideally this would be folded into the above, for uniform style
+            // but c-variadic is already a corner case
             if c_variadic {
-                // We also need to make sure we at least write the ty of the other
-                // arguments which we skipped above, either because they were additional
-                // c_variadic args, or because we had an argument count mismatch.
                 fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
                     use crate::structured_errors::MissingCastForVariadicArg;
 
@@ -498,27 +1051,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         expected_input_tys: &[Ty<'tcx>],
         provided_args: &'tcx [hir::Expr<'tcx>],
-    ) -> Option<FnArgsAsTuple<'_>> {
-        let [expected_arg_type] = expected_input_tys[..] else { return None };
-
+    ) -> TupleMatchFound {
+        // Only handle the case where we expect only one tuple arg
+        let [expected_arg_type] = expected_input_tys[..] else { return TupleMatchFound::None };
         let &ty::Tuple(expected_types) = self.resolve_vars_if_possible(expected_arg_type).kind()
-            else { return None };
+            else { return TupleMatchFound::None };
+
+        // First check that there are the same number of types.
+        if expected_types.len() != provided_args.len() {
+            return TupleMatchFound::None;
+        }
 
         let supplied_types: Vec<_> = provided_args.iter().map(|arg| self.check_expr(arg)).collect();
 
         let all_match = iter::zip(expected_types, supplied_types)
             .all(|(expected, supplied)| self.can_eq(self.param_env, expected, supplied).is_ok());
 
-        if all_match {
-            match provided_args {
-                [] => None,
-                [_] => unreachable!(
-                    "shouldn't reach here - need count mismatch between 1-tuple and 1-argument"
-                ),
-                [first, .., last] => Some(FnArgsAsTuple { first, last }),
+        if !all_match {
+            return TupleMatchFound::None;
+        }
+        match provided_args {
+            [] => TupleMatchFound::None,
+            [_] => TupleMatchFound::Single,
+            [first, .., last] => {
+                TupleMatchFound::Multiple(first.span.shrink_to_lo(), last.span.shrink_to_hi())
             }
-        } else {
-            None
         }
     }
 
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 77cba1c22c4..ce9ff61bd9e 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -1,9 +1,9 @@
 mod _impl;
+mod arg_matrix;
 mod checks;
 mod suggestions;
 
 pub use _impl::*;
-pub use checks::*;
 pub use suggestions::*;
 
 use crate::astconv::AstConv;
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 93a0900c7e8..62518408b8b 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -646,7 +646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // now get all predicates in the same types as the where bounds, so we can chain them
         let predicates_from_where =
-            where_predicates.iter().flatten().map(|bounds| bounds.iter()).flatten();
+            where_predicates.iter().flatten().flat_map(|bounds| bounds.iter());
 
         // extract all bounds from the source code using their spans
         let all_matching_bounds_strs = expected_generic_param
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index e584c9ad201..15edc11a497 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -319,7 +319,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
         self.expr_count += 1;
 
         if let PatKind::Binding(..) = pat.kind {
-            let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
+            let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
             let ty = self.fcx.typeck_results.borrow().pat_ty(pat);
             self.record(ty, pat.hir_id, Some(scope), None, pat.span, false);
         }
@@ -567,7 +567,7 @@ pub fn check_must_not_suspend_ty<'tcx>(
                 _ => None,
             };
             for (i, ty) in fields.iter().enumerate() {
-                let descr_post = &format!(" in tuple element {}", i);
+                let descr_post = &format!(" in tuple element {i}");
                 let span = comps.and_then(|c| c.get(i)).map(|e| e.span).unwrap_or(data.source_span);
                 if check_must_not_suspend_ty(
                     fcx,
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index cd6b1115ed8..0dd8ee88ca2 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -437,6 +437,7 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         | sym::simd_fpow
         | sym::simd_saturating_add
         | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)),
+        sym::simd_arith_offset => (2, vec![param(0), param(1)], param(0)),
         sym::simd_neg
         | sym::simd_fsqrt
         | sym::simd_fsin
@@ -484,14 +485,14 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
                 }
                 Err(_) => {
                     let msg =
-                        format!("unrecognized platform-specific intrinsic function: `{}`", name);
+                        format!("unrecognized platform-specific intrinsic function: `{name}`");
                     tcx.sess.struct_span_err(it.span, &msg).emit();
                     return;
                 }
             }
         }
         _ => {
-            let msg = format!("unrecognized platform-specific intrinsic function: `{}`", name);
+            let msg = format!("unrecognized platform-specific intrinsic function: `{name}`");
             tcx.sess.struct_span_err(it.span, &msg).emit();
             return;
         }
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 83474bd7e72..e04cc42b6d7 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -644,7 +644,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 self.assemble_inherent_impl_candidates_for_type(p.def_id());
             }
             ty::Adt(def, _) => {
-                self.assemble_inherent_impl_candidates_for_type(def.did());
+                let def_id = def.did();
+                self.assemble_inherent_impl_candidates_for_type(def_id);
+                if Some(def_id) == self.tcx.lang_items().c_str() {
+                    self.assemble_inherent_candidates_for_incoherent_ty(raw_self_ty);
+                }
             }
             ty::Foreign(did) => {
                 self.assemble_inherent_impl_candidates_for_type(did);
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index e6560ca4d9b..2921176ca4b 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -8,7 +8,7 @@ use rustc_errors::{
     MultiSpan,
 };
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -1473,12 +1473,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    fn suggest_use_candidates(
-        &self,
-        err: &mut Diagnostic,
-        mut msg: String,
-        candidates: Vec<DefId>,
-    ) {
+    fn suggest_use_candidates(&self, err: &mut Diagnostic, msg: String, candidates: Vec<DefId>) {
         let parent_map = self.tcx.visible_parent_map(());
 
         // Separate out candidates that must be imported with a glob, because they are named `_`
@@ -1502,80 +1497,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         });
 
         let module_did = self.tcx.parent_module(self.body_id);
-        let (span, found_use) = find_use_placement(self.tcx, module_did);
-        if let Some(span) = span {
-            let path_strings = candidates.iter().map(|trait_did| {
-                // Produce an additional newline to separate the new use statement
-                // from the directly following item.
-                let additional_newline = if found_use { "" } else { "\n" };
-                format!(
-                    "use {};\n{}",
-                    with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
-                    additional_newline
-                )
-            });
+        let (module, _, _) = self.tcx.hir().get_module(module_did);
+        let span = module.spans.inject_use_span;
 
-            let glob_path_strings = globs.iter().map(|trait_did| {
-                let parent_did = parent_map.get(trait_did).unwrap();
+        let path_strings = candidates.iter().map(|trait_did| {
+            format!("use {};\n", with_crate_prefix!(self.tcx.def_path_str(*trait_did)),)
+        });
 
-                // Produce an additional newline to separate the new use statement
-                // from the directly following item.
-                let additional_newline = if found_use { "" } else { "\n" };
-                format!(
-                    "use {}::*; // trait {}\n{}",
-                    with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
-                    self.tcx.item_name(*trait_did),
-                    additional_newline
-                )
-            });
+        let glob_path_strings = globs.iter().map(|trait_did| {
+            let parent_did = parent_map.get(trait_did).unwrap();
+            format!(
+                "use {}::*; // trait {}\n",
+                with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
+                self.tcx.item_name(*trait_did),
+            )
+        });
 
-            err.span_suggestions(
-                span,
-                &msg,
-                path_strings.chain(glob_path_strings),
-                Applicability::MaybeIncorrect,
-            );
-        } else {
-            let limit = if candidates.len() + globs.len() == 5 { 5 } else { 4 };
-            for (i, trait_did) in candidates.iter().take(limit).enumerate() {
-                if candidates.len() + globs.len() > 1 {
-                    msg.push_str(&format!(
-                        "\ncandidate #{}: `use {};`",
-                        i + 1,
-                        with_crate_prefix!(self.tcx.def_path_str(*trait_did))
-                    ));
-                } else {
-                    msg.push_str(&format!(
-                        "\n`use {};`",
-                        with_crate_prefix!(self.tcx.def_path_str(*trait_did))
-                    ));
-                }
-            }
-            for (i, trait_did) in
-                globs.iter().take(limit.saturating_sub(candidates.len())).enumerate()
-            {
-                let parent_did = parent_map.get(trait_did).unwrap();
-
-                if candidates.len() + globs.len() > 1 {
-                    msg.push_str(&format!(
-                        "\ncandidate #{}: `use {}::*; // trait {}`",
-                        candidates.len() + i + 1,
-                        with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
-                        self.tcx.item_name(*trait_did),
-                    ));
-                } else {
-                    msg.push_str(&format!(
-                        "\n`use {}::*; // trait {}`",
-                        with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
-                        self.tcx.item_name(*trait_did),
-                    ));
-                }
-            }
-            if candidates.len() > limit {
-                msg.push_str(&format!("\nand {} others", candidates.len() + globs.len() - limit));
-            }
-            err.note(&msg);
-        }
+        err.span_suggestions(
+            span,
+            &msg,
+            path_strings.chain(glob_path_strings),
+            Applicability::MaybeIncorrect,
+        );
     }
 
     fn suggest_valid_traits(
@@ -2106,53 +2049,6 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
     tcx.all_traits().map(|def_id| TraitInfo { def_id }).collect()
 }
 
-fn find_use_placement<'tcx>(tcx: TyCtxt<'tcx>, target_module: LocalDefId) -> (Option<Span>, bool) {
-    // FIXME(#94854): this code uses an out-of-date method for inferring a span
-    // to suggest. It would be better to thread the ModSpans from the AST into
-    // the HIR, and then use that to drive the suggestion here.
-
-    let mut span = None;
-    let mut found_use = false;
-    let (module, _, _) = tcx.hir().get_module(target_module);
-
-    // Find a `use` statement.
-    for &item_id in module.item_ids {
-        let item = tcx.hir().item(item_id);
-        match item.kind {
-            hir::ItemKind::Use(..) => {
-                // Don't suggest placing a `use` before the prelude
-                // import or other generated ones.
-                if !item.span.from_expansion() {
-                    span = Some(item.span.shrink_to_lo());
-                    found_use = true;
-                    break;
-                }
-            }
-            // Don't place `use` before `extern crate`...
-            hir::ItemKind::ExternCrate(_) => {}
-            // ...but do place them before the first other item.
-            _ => {
-                if span.map_or(true, |span| item.span < span) {
-                    if !item.span.from_expansion() {
-                        span = Some(item.span.shrink_to_lo());
-                        // Don't insert between attributes and an item.
-                        let attrs = tcx.hir().attrs(item.hir_id());
-                        // Find the first attribute on the item.
-                        // FIXME: This is broken for active attributes.
-                        for attr in attrs {
-                            if !attr.span.is_dummy() && span.map_or(true, |span| attr.span < span) {
-                                span = Some(attr.span.shrink_to_lo());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    (span, found_use)
-}
-
 fn print_disambiguation_help<'tcx>(
     item_name: Ident,
     args: Option<&'tcx [hir::Expr<'tcx>]>,
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 19d52f430fc..0d5e7b28a4e 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -427,16 +427,29 @@ fn typeck_with_fallback<'tcx>(
                             span,
                         }),
                         Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
-                        | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. })
-                            if asm.operands.iter().any(|(op, _op_sp)| match op {
-                                hir::InlineAsmOperand::Const { anon_const } => {
-                                    anon_const.hir_id == id
-                                }
-                                _ => false,
-                            }) =>
-                        {
-                            // Inline assembly constants must be integers.
-                            fcx.next_int_var()
+                        | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
+                            let operand_ty = asm
+                                .operands
+                                .iter()
+                                .filter_map(|(op, _op_sp)| match op {
+                                    hir::InlineAsmOperand::Const { anon_const }
+                                        if anon_const.hir_id == id =>
+                                    {
+                                        // Inline assembly constants must be integers.
+                                        Some(fcx.next_int_var())
+                                    }
+                                    hir::InlineAsmOperand::SymFn { anon_const }
+                                        if anon_const.hir_id == id =>
+                                    {
+                                        Some(fcx.next_ty_var(TypeVariableOrigin {
+                                            kind: TypeVariableOriginKind::MiscVariable,
+                                            span,
+                                        }))
+                                    }
+                                    _ => None,
+                                })
+                                .next();
+                            operand_ty.unwrap_or_else(fallback)
                         }
                         _ => fallback(),
                     },
@@ -553,13 +566,13 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: S
     // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
     // the consumer's responsibility to ensure all bytes that have been read
     // have defined values.
-    if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id()) {
-        if alloc.inner().relocations().len() != 0 {
-            let msg = "statics with a custom `#[link_section]` must be a \
-                           simple list of bytes on the wasm target with no \
-                           extra levels of indirection such as references";
-            tcx.sess.span_err(span, msg);
-        }
+    if let Ok(alloc) = tcx.eval_static_initializer(id.to_def_id())
+        && alloc.inner().relocations().len() != 0
+    {
+        let msg = "statics with a custom `#[link_section]` must be a \
+                        simple list of bytes on the wasm target with no \
+                        extra levels of indirection such as references";
+        tcx.sess.span_err(span, msg);
     }
 }
 
@@ -587,7 +600,7 @@ fn report_forbidden_specialization(
             ));
         }
         Err(cname) => {
-            err.note(&format!("parent implementation is in crate `{}`", cname));
+            err.note(&format!("parent implementation is in crate `{cname}`"));
         }
     }
 
@@ -610,10 +623,9 @@ fn missing_items_err(
         tcx.sess,
         impl_span,
         E0046,
-        "not all trait items implemented, missing: `{}`",
-        missing_items_msg
+        "not all trait items implemented, missing: `{missing_items_msg}`",
     );
-    err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
+    err.span_label(impl_span, format!("missing `{missing_items_msg}` in implementation"));
 
     // `Span` before impl block closing brace.
     let hi = full_impl_span.hi() - BytePos(1);
@@ -628,7 +640,7 @@ fn missing_items_err(
     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 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.name));
@@ -653,10 +665,9 @@ fn missing_items_must_implement_one_of_err(
         tcx.sess,
         impl_span,
         E0046,
-        "not all trait items implemented, missing one of: `{}`",
-        missing_items_msg
+        "not all trait items implemented, missing one of: `{missing_items_msg}`",
     );
-    err.span_label(impl_span, format!("missing one of `{}` in implementation", missing_items_msg));
+    err.span_label(impl_span, format!("missing one of `{missing_items_msg}` in implementation"));
 
     if let Some(annotation_span) = annotation_span {
         err.span_note(annotation_span, "required because of this annotation");
@@ -749,9 +760,10 @@ fn fn_sig_suggestion<'tcx>(
             Some(match ty.kind() {
                 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
                 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
-                    let reg = match &format!("{}", reg)[..] {
-                        "'_" | "" => String::new(),
-                        reg => format!("{} ", reg),
+                    let reg = format!("{reg} ");
+                    let reg = match &reg[..] {
+                        "'_ " | " " => "",
+                        reg => reg,
                     };
                     if assoc.fn_has_self_parameter {
                         match ref_ty.kind() {
@@ -759,17 +771,17 @@ fn fn_sig_suggestion<'tcx>(
                                 format!("&{}{}self", reg, mutability.prefix_str())
                             }
 
-                            _ => format!("self: {}", ty),
+                            _ => format!("self: {ty}"),
                         }
                     } else {
-                        format!("_: {}", ty)
+                        format!("_: {ty}")
                     }
                 }
                 _ => {
                     if assoc.fn_has_self_parameter && i == 0 {
-                        format!("self: {}", ty)
+                        format!("self: {ty}")
                     } else {
-                        format!("_: {}", ty)
+                        format!("_: {ty}")
                     }
                 }
             })
@@ -779,7 +791,7 @@ fn fn_sig_suggestion<'tcx>(
         .collect::<Vec<String>>()
         .join(", ");
     let output = sig.output();
-    let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() };
+    let output = if !output.is_unit() { format!(" -> {output}") } else { String::new() };
 
     let unsafety = sig.unsafety.prefix_str();
     let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
@@ -789,10 +801,7 @@ fn fn_sig_suggestion<'tcx>(
     // 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 {}{}({}){}{} {{ todo!() }}",
-        unsafety, ident, generics, args, output, where_clauses
-    )
+    format!("{unsafety}fn {ident}{generics}({args}){output}{where_clauses} {{ todo!() }}")
 }
 
 /// Return placeholder code for the given associated item.
@@ -830,7 +839,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d
         .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
         .collect();
     let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),);
-    let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
+    let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {msg}");
     err.span_label(sp, &msg);
     if let [start @ .., end] = &*variant_spans {
         for variant_span in start {
@@ -850,7 +859,7 @@ fn bad_non_zero_sized_fields<'tcx>(
     field_spans: impl Iterator<Item = Span>,
     sp: Span,
 ) {
-    let msg = format!("needs at most one non-zero-sized field, but has {}", field_count);
+    let msg = format!("needs at most one non-zero-sized field, but has {field_count}");
     let mut err = struct_span_err!(
         tcx.sess,
         sp,
@@ -877,7 +886,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
         tcx.sess
             .source_map()
             .span_to_snippet(span)
-            .map_or_else(|_| String::new(), |s| format!(" `{}`", s)),
+            .map_or_else(|_| String::new(), |s| format!(" `{s}`",)),
     )
     .emit();
 }
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 0baca9048b4..f3dcf5fff74 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -405,16 +405,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut pat_ty = ty;
         if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind {
             let expected = self.structurally_resolved_type(span, expected);
-            if let ty::Ref(_, inner_ty, _) = expected.kind() {
-                if matches!(inner_ty.kind(), ty::Slice(_)) {
-                    let tcx = self.tcx;
-                    trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
-                    self.typeck_results
-                        .borrow_mut()
-                        .treat_byte_string_as_slice
-                        .insert(lt.hir_id.local_id);
-                    pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
-                }
+            if let ty::Ref(_, inner_ty, _) = expected.kind()
+                && matches!(inner_ty.kind(), ty::Slice(_))
+            {
+                let tcx = self.tcx;
+                trace!(?lt.hir_id.local_id, "polymorphic byte string lit");
+                self.typeck_results
+                    .borrow_mut()
+                    .treat_byte_string_as_slice
+                    .insert(lt.hir_id.local_id);
+                pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_slice(tcx.types.u8));
             }
         }
 
@@ -481,14 +481,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Unify each side with `expected`.
         // Subtyping doesn't matter here, as the value is some kind of scalar.
         let demand_eqtype = |x: &mut _, y| {
-            if let Some((ref mut fail, x_ty, x_span)) = *x {
-                if let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) {
-                    if let Some((_, y_ty, y_span)) = y {
-                        self.endpoint_has_type(&mut err, y_span, y_ty);
-                    }
-                    err.emit();
-                    *fail = true;
-                };
+            if let Some((ref mut fail, x_ty, x_span)) = *x
+                && let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti)
+            {
+                if let Some((_, y_ty, y_span)) = y {
+                    self.endpoint_has_type(&mut err, y_span, y_ty);
+                }
+                err.emit();
+                *fail = true;
             }
         };
         demand_eqtype(&mut lhs, rhs);
@@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
             let hir = self.tcx.hir();
             let var_ty = self.resolve_vars_with_obligations(var_ty);
-            let msg = format!("first introduced with type `{}` here", var_ty);
+            let msg = format!("first introduced with type `{var_ty}` here");
             err.span_label(hir.span(var_id), msg);
             let in_match = hir.parent_iter(var_id).any(|(_, n)| {
                 matches!(
@@ -665,8 +665,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 {
                     err.span_suggestion(
                         *span,
-                        &format!("did you mean `{}`", snippet),
-                        format!(" &{}", expected),
+                        &format!("did you mean `{snippet}`"),
+                        format!(" &{expected}"),
                         Applicability::MachineApplicable,
                     );
                 }
@@ -701,7 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "type `{}` cannot be dereferenced",
                         type_str
                     );
-                    err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
+                    err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
                         err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
                     }
@@ -918,7 +918,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 path_str
             );
 
-            let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
+            let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}");
             match res {
                 Res::Def(DefKind::Fn | DefKind::AssocFn, _) => {
                     err.span_label(pat.span, "`fn` calls are not allowed in patterns");
@@ -1396,8 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.tcx.sess,
                     pat.span,
                     E0769,
-                    "tuple variant `{}` written as struct variant",
-                    path
+                    "tuple variant `{path}` written as struct variant",
                 );
                 err.span_suggestion_verbose(
                     qpath.span().shrink_to_hi().to(pat.span.shrink_to_hi()),
@@ -1422,8 +1421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             sess,
             pat.span,
             E0638,
-            "`..` required with {} marked as non-exhaustive",
-            descr
+            "`..` required with {descr} marked as non-exhaustive",
         );
         err.span_suggestion_verbose(
             sp_comma,
@@ -1442,8 +1440,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             "field `{}` bound multiple times in the pattern",
             ident
         )
-        .span_label(span, format!("multiple uses of `{}` in pattern", ident))
-        .span_label(other_field, format!("first use of `{}`", ident))
+        .span_label(span, format!("multiple uses of `{ident}` in pattern"))
+        .span_label(other_field, format!("first use of `{ident}`"))
         .emit();
     }
 
diff --git a/compiler/rustc_typeck/src/check/place_op.rs b/compiler/rustc_typeck/src/check/place_op.rs
index 5dab0bb7a13..2e0f37eba23 100644
--- a/compiler/rustc_typeck/src/check/place_op.rs
+++ b/compiler/rustc_typeck/src/check/place_op.rs
@@ -74,9 +74,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ty = self.resolve_vars_if_possible(ty);
         let mut err = self.tcx.sess.struct_span_err(
             span,
-            &format!("negative integers cannot be used to index on a `{}`", ty),
+            &format!("negative integers cannot be used to index on a `{ty}`"),
         );
-        err.span_label(span, &format!("cannot use a negative integer for indexing on `{}`", ty));
+        err.span_label(span, &format!("cannot use a negative integer for indexing on `{ty}`"));
         if let (hir::ExprKind::Path(..), Ok(snippet)) =
             (&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
         {
@@ -84,10 +84,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             err.span_suggestion_verbose(
                 span.shrink_to_lo(),
                 &format!(
-                    "to access an element starting from the end of the `{}`, compute the index",
-                    ty,
+                    "to access an element starting from the end of the `{ty}`, compute the index",
                 ),
-                format!("{}.len() ", snippet),
+                format!("{snippet}.len() "),
                 Applicability::MachineApplicable,
             );
         }
@@ -314,32 +313,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.typeck_results.borrow_mut().adjustments_mut().remove(expr.hir_id);
             if let Some(mut adjustments) = previous_adjustments {
                 for adjustment in &mut adjustments {
-                    if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
-                        if let Some(ok) = self.try_mutable_overloaded_place_op(
+                    if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind
+                        && let Some(ok) = self.try_mutable_overloaded_place_op(
                             expr.span,
                             source,
                             &[],
                             PlaceOp::Deref,
-                        ) {
-                            let method = self.register_infer_ok_obligations(ok);
-                            if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
-                                *deref = OverloadedDeref { region, mutbl, span: deref.span };
-                            }
-                            // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
-                            // This helps avoid accidental drops.
-                            if inside_union
-                                && source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop())
-                            {
-                                let mut err = self.tcx.sess.struct_span_err(
-                                    expr.span,
-                                    "not automatically applying `DerefMut` on `ManuallyDrop` union field",
-                                );
-                                err.help(
-                                    "writing to this reference calls the destructor for the old value",
-                                );
-                                err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor");
-                                err.emit();
-                            }
+                        )
+                    {
+                        let method = self.register_infer_ok_obligations(ok);
+                        if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
+                            *deref = OverloadedDeref { region, mutbl, span: deref.span };
+                        }
+                        // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
+                        // This helps avoid accidental drops.
+                        if inside_union
+                            && source.ty_adt_def().map_or(false, |adt| adt.is_manually_drop())
+                        {
+                            let mut err = self.tcx.sess.struct_span_err(
+                                expr.span,
+                                "not automatically applying `DerefMut` on `ManuallyDrop` union field",
+                            );
+                            err.help(
+                                "writing to this reference calls the destructor for the old value",
+                            );
+                            err.help("add an explicit `*` if that is desired, or call `ptr::write` to not run the destructor");
+                            err.emit();
                         }
                     }
                     source = adjustment.target;
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index e18cb31acbd..e37e83e7487 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -317,13 +317,8 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         self.body_id = body_id.hir_id;
         self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
 
-        let fn_sig = {
-            match self.typeck_results.borrow().liberated_fn_sigs().get(id) {
-                Some(f) => *f,
-                None => {
-                    bug!("No fn-sig entry for id={:?}", id);
-                }
-            }
+        let Some(fn_sig) = self.typeck_results.borrow().liberated_fn_sigs().get(id) else {
+            bug!("No fn-sig entry for id={:?}", id);
         };
 
         // Collect the types from which we create inferred bounds.
@@ -642,12 +637,9 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         ignore_err!(self.with_mc(|mc| {
             mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id, .. }| {
                 // `ref x` pattern
-                if let PatKind::Binding(..) = kind {
-                    if let Some(ty::BindByReference(mutbl)) =
-                        mc.typeck_results.extract_binding_mode(self.tcx.sess, *hir_id, *span)
-                    {
-                        self.link_region_from_node_type(*span, *hir_id, mutbl, sub_cmt);
-                    }
+                if let PatKind::Binding(..) = kind
+                    && let Some(ty::BindByReference(mutbl)) = mc.typeck_results.extract_binding_mode(self.tcx.sess, *hir_id, *span) {
+                    self.link_region_from_node_type(*span, *hir_id, mutbl, sub_cmt);
                 }
             })
         }));
diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs
index 1118e967707..9dbb8132932 100644
--- a/compiler/rustc_typeck/src/check/upvar.rs
+++ b/compiler/rustc_typeck/src/check/upvar.rs
@@ -862,7 +862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             diagnostics_builder.span_suggestion(
                                 closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(),
                                 &diagnostic_msg,
-                                format!("\n{}{};", indent, migration_string),
+                                format!("\n{indent}{migration_string};"),
                                 Applicability::MachineApplicable,
                             );
                         } else if line1.starts_with('{') {
@@ -873,7 +873,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             diagnostics_builder.span_suggestion(
                                 closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(),
                                 &diagnostic_msg,
-                                format!(" {};", migration_string),
+                                format!(" {migration_string};"),
                                 Applicability::MachineApplicable,
                             );
                         } else {
@@ -882,7 +882,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             diagnostics_builder.multipart_suggestion(
                                 &diagnostic_msg,
                                 vec![
-                                    (closure_body_span.shrink_to_lo(), format!("{{ {}; ", migration_string)),
+                                    (closure_body_span.shrink_to_lo(), format!("{{ {migration_string}; ")),
                                     (closure_body_span.shrink_to_hi(), " }".to_string()),
                                 ],
                                 Applicability::MachineApplicable
@@ -1527,7 +1527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx.sess.struct_span_err(closure_span, "First Pass analysis includes:");
             for (place, capture_info) in capture_information {
                 let capture_str = construct_capture_info_string(self.tcx, place, capture_info);
-                let output_str = format!("Capturing {}", capture_str);
+                let output_str = format!("Capturing {capture_str}");
 
                 let span =
                     capture_info.path_expr_id.map_or(closure_span, |e| self.tcx.hir().span(e));
@@ -1552,7 +1552,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                         let capture_str =
                             construct_capture_info_string(self.tcx, place, capture_info);
-                        let output_str = format!("Min Capture {}", capture_str);
+                        let output_str = format!("Min Capture {capture_str}");
 
                         if capture.info.path_expr_id != capture.info.capture_kind_expr_id {
                             let path_span = capture_info
@@ -1969,7 +1969,7 @@ fn construct_place_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String
         projections_str.push_str(proj.as_str());
     }
 
-    format!("{}[{}]", variable_name, projections_str)
+    format!("{variable_name}[{projections_str}]")
 }
 
 fn construct_capture_kind_reason_string<'tcx>(
@@ -1984,13 +1984,13 @@ fn construct_capture_kind_reason_string<'tcx>(
         ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind),
     };
 
-    format!("{} captured as {} here", place_str, capture_kind_str)
+    format!("{place_str} captured as {capture_kind_str} here")
 }
 
 fn construct_path_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String {
     let place_str = construct_place_string(tcx, place);
 
-    format!("{} used here", place_str)
+    format!("{place_str} used here")
 }
 
 fn construct_capture_info_string<'tcx>(
@@ -2004,7 +2004,7 @@ fn construct_capture_info_string<'tcx>(
         ty::UpvarCapture::ByValue => "ByValue".into(),
         ty::UpvarCapture::ByRef(kind) => format!("{:?}", kind),
     };
-    format!("{} -> {}", place_str, capture_kind_str)
+    format!("{place_str} -> {capture_kind_str}")
 }
 
 fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol {
@@ -2035,16 +2035,16 @@ fn migration_suggestion_for_2229(
         .collect::<Vec<_>>();
 
     let migration_ref_concat =
-        need_migrations_variables.iter().map(|v| format!("&{}", v)).collect::<Vec<_>>().join(", ");
+        need_migrations_variables.iter().map(|v| format!("&{v}")).collect::<Vec<_>>().join(", ");
 
     let migration_string = if 1 == need_migrations.len() {
-        format!("let _ = {}", migration_ref_concat)
+        format!("let _ = {migration_ref_concat}")
     } else {
-        format!("let _ = ({})", migration_ref_concat)
+        format!("let _ = ({migration_ref_concat})")
     };
 
     let migrated_variables_concat =
-        need_migrations_variables.iter().map(|v| format!("`{}`", v)).collect::<Vec<_>>().join(", ");
+        need_migrations_variables.iter().map(|v| format!("`{v}`")).collect::<Vec<_>>().join(", ");
 
     (migration_string, migrated_variables_concat)
 }
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index f9664a9b991..4e3e32670e9 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -230,8 +230,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                         .struct_span_err(
                             self_ty.span,
                             &format!(
-                                "first argument of `call` in `{}` lang item must be a reference",
-                                fn_lang_item_name
+                                "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference",
                             ),
                         )
                         .emit();
@@ -241,8 +240,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     .struct_span_err(
                         *span,
                         &format!(
-                            "`call` function in `{}` lang item takes exactly two arguments",
-                            fn_lang_item_name
+                            "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments",
                         ),
                     )
                     .emit();
@@ -252,8 +250,7 @@ pub fn check_trait_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                 .struct_span_err(
                     trait_item.span,
                     &format!(
-                        "`call` trait item in `{}` lang item must be a function",
-                        fn_lang_item_name
+                        "`call` trait item in `{fn_lang_item_name}` lang item must be a function",
                     ),
                 )
                 .emit();
@@ -432,7 +429,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
             );
             err.span_suggestion(
                 gat_item_hir.generics.where_clause.tail_span_for_suggestion(),
-                &format!("add the required where clause{}", plural),
+                &format!("add the required where clause{plural}"),
                 suggestion,
                 Applicability::MachineApplicable,
             );
@@ -523,7 +520,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
             // In our example, requires that `Self: 'a`
             if ty_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *ty, *region_a) {
                 debug!(?ty_idx, ?region_a_idx);
-                debug!("required clause: {} must outlive {}", ty, region_a);
+                debug!("required clause: {ty} must outlive {region_a}");
                 // Translate into the generic parameters of the GAT. In
                 // our example, the type was `Self`, which will also be
                 // `Self` in the GAT.
@@ -560,7 +557,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>(
             }
             if region_known_to_outlive(tcx, item_hir, param_env, &wf_tys, *region_a, *region_b) {
                 debug!(?region_a_idx, ?region_b_idx);
-                debug!("required clause: {} must outlive {}", region_a, region_b);
+                debug!("required clause: {region_a} must outlive {region_b}");
                 // Translate into the generic parameters of the GAT.
                 let region_a_param = gat_generics.param_at(*region_a_idx, tcx);
                 let region_a_param =
@@ -869,7 +866,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
                         )
                         .span_label(
                             hir_ty.span,
-                            format!("`{}` doesn't derive both `PartialEq` and `Eq`", ty),
+                            format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
                         )
                         .emit();
                     }
@@ -884,7 +881,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
                     ty::RawPtr(_) => Some("raw pointers"),
                     _ => {
                         is_ptr = false;
-                        err_ty_str = format!("`{}`", ty);
+                        err_ty_str = format!("`{ty}`");
                         Some(err_ty_str.as_str())
                     }
                 };
@@ -894,16 +891,14 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
                         tcx.sess.span_err(
                             hir_ty.span,
                             &format!(
-                                "using {} as const generic parameters is forbidden",
-                                unsupported_type
+                                "using {unsupported_type} as const generic parameters is forbidden",
                             ),
                         );
                     } else {
                         let mut err = tcx.sess.struct_span_err(
                             hir_ty.span,
                             &format!(
-                                "{} is forbidden as the type of a const generic parameter",
-                                unsupported_type
+                                "{unsupported_type} is forbidden as the type of a const generic parameter",
                             ),
                         );
                         err.note("the only supported types are integers, `bool` and `char`");
@@ -1567,9 +1562,8 @@ fn check_method_receiver<'fcx, 'tcx>(
                     sym::arbitrary_self_types,
                     span,
                     &format!(
-                        "`{}` cannot be used as the type of `self` without \
+                        "`{receiver_ty}` cannot be used as the type of `self` without \
                          the `arbitrary_self_types` feature",
-                        receiver_ty,
                     ),
                 )
                 .help(HELP_FOR_SELF_TYPE)
@@ -1587,8 +1581,7 @@ fn e0307<'tcx>(fcx: &FnCtxt<'_, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
         fcx.tcx.sess.diagnostic(),
         span,
         E0307,
-        "invalid `self` parameter type: {}",
-        receiver_ty,
+        "invalid `self` parameter type: {receiver_ty}"
     )
     .note("type of `self` must be `Self` or a type that dereferences to it")
     .help(HELP_FOR_SELF_TYPE)
@@ -1793,7 +1786,7 @@ fn report_bivariance(
             tcx.def_path_str(def_id),
         )
     } else {
-        format!("consider removing `{}` or referring to it in a field", param_name)
+        format!("consider removing `{param_name}` or referring to it in a field")
     };
     err.help(&msg);
 
@@ -1993,8 +1986,7 @@ fn error_392(
     span: Span,
     param_name: Symbol,
 ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
-    let mut err =
-        struct_span_err!(tcx.sess, span, E0392, "parameter `{}` is never used", param_name);
+    let mut err = struct_span_err!(tcx.sess, span, E0392, "parameter `{param_name}` is never used");
     err.span_label(span, "unused parameter");
     err
 }
diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
index e11bd9355eb..5ad0c4ac52d 100644
--- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
@@ -55,7 +55,12 @@ impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
         let self_ty = self.tcx.type_of(item.def_id);
         match *self_ty.kind() {
             ty::Adt(def, _) => {
-                self.check_def_id(item, def.did());
+                let def_id = def.did();
+                if !def_id.is_local() && Some(def_id) == self.tcx.lang_items().c_str() {
+                    self.check_primitive_impl(item.def_id, self_ty, items, ty.span)
+                } else {
+                    self.check_def_id(item, def_id);
+                }
             }
             ty::Foreign(did) => {
                 self.check_def_id(item, did);
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 785538ab0df..fa06ec09fce 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -450,7 +450,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
                 | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
                     if asm.operands.iter().any(|(op, _op_sp)| match op {
-                        hir::InlineAsmOperand::Const { anon_const } => anon_const.hir_id == hir_id,
+                        hir::InlineAsmOperand::Const { anon_const }
+                        | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
                         _ => false,
                     }) =>
                 {
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index 055e391d706..2bcf2d3b2ed 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -358,8 +358,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             hir::ExprKind::InlineAsm(asm) => {
                 for (op, _op_sp) in asm.operands {
                     match op {
-                        hir::InlineAsmOperand::In { expr, .. }
-                        | hir::InlineAsmOperand::Sym { expr, .. } => self.consume_expr(expr),
+                        hir::InlineAsmOperand::In { expr, .. } => self.consume_expr(expr),
                         hir::InlineAsmOperand::Out { expr: Some(expr), .. }
                         | hir::InlineAsmOperand::InOut { expr, .. } => {
                             self.mutate_expr(expr);
@@ -371,7 +370,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                             }
                         }
                         hir::InlineAsmOperand::Out { expr: None, .. }
-                        | hir::InlineAsmOperand::Const { .. } => {}
+                        | hir::InlineAsmOperand::Const { .. }
+                        | hir::InlineAsmOperand::SymFn { .. }
+                        | hir::InlineAsmOperand::SymStatic { .. } => {}
                     }
                 }
             }
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index d0c4726bb0a..9fb9652b849 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -61,9 +61,11 @@ This API is completely unstable and subject to change.
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
 #![feature(crate_visibility_modifier)]
+#![feature(drain_filter)]
 #![feature(hash_drain_filter)]
 #![feature(if_let_guard)]
 #![feature(is_sorted)]
+#![feature(label_break_value)]
 #![feature(let_chains)]
 #![feature(let_else)]
 #![feature(min_specialization)]
diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs
index cc986e93698..47ba1777ae9 100644
--- a/library/alloc/src/collections/btree/map/tests.rs
+++ b/library/alloc/src/collections/btree/map/tests.rs
@@ -1879,6 +1879,96 @@ fn test_first_last_entry() {
 }
 
 #[test]
+fn test_pop_first_last() {
+    let mut map = BTreeMap::new();
+    assert_eq!(map.pop_first(), None);
+    assert_eq!(map.pop_last(), None);
+
+    map.insert(1, 10);
+    map.insert(2, 20);
+    map.insert(3, 30);
+    map.insert(4, 40);
+
+    assert_eq!(map.len(), 4);
+
+    let (key, val) = map.pop_first().unwrap();
+    assert_eq!(key, 1);
+    assert_eq!(val, 10);
+    assert_eq!(map.len(), 3);
+
+    let (key, val) = map.pop_first().unwrap();
+    assert_eq!(key, 2);
+    assert_eq!(val, 20);
+    assert_eq!(map.len(), 2);
+    let (key, val) = map.pop_last().unwrap();
+    assert_eq!(key, 4);
+    assert_eq!(val, 40);
+    assert_eq!(map.len(), 1);
+
+    map.insert(5, 50);
+    map.insert(6, 60);
+    assert_eq!(map.len(), 3);
+
+    let (key, val) = map.pop_first().unwrap();
+    assert_eq!(key, 3);
+    assert_eq!(val, 30);
+    assert_eq!(map.len(), 2);
+
+    let (key, val) = map.pop_last().unwrap();
+    assert_eq!(key, 6);
+    assert_eq!(val, 60);
+    assert_eq!(map.len(), 1);
+
+    let (key, val) = map.pop_last().unwrap();
+    assert_eq!(key, 5);
+    assert_eq!(val, 50);
+    assert_eq!(map.len(), 0);
+
+    assert_eq!(map.pop_first(), None);
+    assert_eq!(map.pop_last(), None);
+
+    map.insert(7, 70);
+    map.insert(8, 80);
+
+    let (key, val) = map.pop_last().unwrap();
+    assert_eq!(key, 8);
+    assert_eq!(val, 80);
+    assert_eq!(map.len(), 1);
+
+    let (key, val) = map.pop_last().unwrap();
+    assert_eq!(key, 7);
+    assert_eq!(val, 70);
+    assert_eq!(map.len(), 0);
+
+    assert_eq!(map.pop_first(), None);
+    assert_eq!(map.pop_last(), None);
+}
+
+#[test]
+fn test_get_key_value() {
+    let mut map = BTreeMap::new();
+
+    assert!(map.is_empty());
+    assert_eq!(map.get_key_value(&1), None);
+    assert_eq!(map.get_key_value(&2), None);
+
+    map.insert(1, 10);
+    map.insert(2, 20);
+    map.insert(3, 30);
+
+    assert_eq!(map.len(), 3);
+    assert_eq!(map.get_key_value(&1), Some((&1, &10)));
+    assert_eq!(map.get_key_value(&3), Some((&3, &30)));
+    assert_eq!(map.get_key_value(&4), None);
+
+    map.remove(&3);
+
+    assert_eq!(map.len(), 2);
+    assert_eq!(map.get_key_value(&3), None);
+    assert_eq!(map.get_key_value(&2), Some((&2, &20)));
+}
+
+#[test]
 fn test_insert_into_full_height_0() {
     let size = node::CAPACITY;
     for pos in 0..=size {
@@ -1904,6 +1994,21 @@ fn test_insert_into_full_height_1() {
     }
 }
 
+#[test]
+fn test_try_insert() {
+    let mut map = BTreeMap::new();
+
+    assert!(map.is_empty());
+
+    assert_eq!(map.try_insert(1, 10).unwrap(), &10);
+    assert_eq!(map.try_insert(2, 20).unwrap(), &20);
+
+    let err = map.try_insert(2, 200).unwrap_err();
+    assert_eq!(err.entry.key(), &2);
+    assert_eq!(err.entry.get(), &20);
+    assert_eq!(err.value, 200);
+}
+
 macro_rules! create_append_test {
     ($name:ident, $len:expr) => {
         #[test]
diff --git a/library/alloc/src/collections/btree/set/tests.rs b/library/alloc/src/collections/btree/set/tests.rs
index 00a2a0aaa14..429b1644976 100644
--- a/library/alloc/src/collections/btree/set/tests.rs
+++ b/library/alloc/src/collections/btree/set/tests.rs
@@ -320,6 +320,42 @@ fn test_is_subset() {
 }
 
 #[test]
+fn test_is_superset() {
+    fn is_superset(a: &[i32], b: &[i32]) -> bool {
+        let set_a = BTreeSet::from_iter(a.iter());
+        let set_b = BTreeSet::from_iter(b.iter());
+        set_a.is_superset(&set_b)
+    }
+
+    assert_eq!(is_superset(&[], &[]), true);
+    assert_eq!(is_superset(&[], &[1, 2]), false);
+    assert_eq!(is_superset(&[0], &[1, 2]), false);
+    assert_eq!(is_superset(&[1], &[1, 2]), false);
+    assert_eq!(is_superset(&[4], &[1, 2]), false);
+    assert_eq!(is_superset(&[1, 4], &[1, 2]), false);
+    assert_eq!(is_superset(&[1, 2], &[1, 2]), true);
+    assert_eq!(is_superset(&[1, 2, 3], &[1, 3]), true);
+    assert_eq!(is_superset(&[1, 2, 3], &[]), true);
+    assert_eq!(is_superset(&[-1, 1, 2, 3], &[-1, 3]), true);
+
+    if cfg!(miri) {
+        // Miri is too slow
+        return;
+    }
+
+    let large = Vec::from_iter(0..100);
+    assert_eq!(is_superset(&[], &large), false);
+    assert_eq!(is_superset(&large, &[]), true);
+    assert_eq!(is_superset(&large, &[1]), true);
+    assert_eq!(is_superset(&large, &[50, 99]), true);
+    assert_eq!(is_superset(&large, &[100]), false);
+    assert_eq!(is_superset(&large, &[0, 99]), true);
+    assert_eq!(is_superset(&[-1], &large), false);
+    assert_eq!(is_superset(&[0], &large), false);
+    assert_eq!(is_superset(&[99, 100], &large), false);
+}
+
+#[test]
 fn test_retain() {
     let mut set = BTreeSet::from([1, 2, 3, 4, 5, 6]);
     set.retain(|&k| k % 2 == 0);
@@ -391,6 +427,26 @@ fn test_clear() {
     x.clear();
     assert!(x.is_empty());
 }
+#[test]
+fn test_remove() {
+    let mut x = BTreeSet::new();
+    assert!(x.is_empty());
+
+    x.insert(1);
+    x.insert(2);
+    x.insert(3);
+    x.insert(4);
+
+    assert_eq!(x.remove(&2), true);
+    assert_eq!(x.remove(&0), false);
+    assert_eq!(x.remove(&5), false);
+    assert_eq!(x.remove(&1), true);
+    assert_eq!(x.remove(&2), false);
+    assert_eq!(x.remove(&3), true);
+    assert_eq!(x.remove(&4), true);
+    assert_eq!(x.remove(&4), false);
+    assert!(x.is_empty());
+}
 
 #[test]
 fn test_zip() {
diff --git a/library/std/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index a68def1e83d..172a008e89a 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -1,25 +1,25 @@
-#![deny(unsafe_op_in_unsafe_fn)]
-
 #[cfg(test)]
 mod tests;
 
-use crate::ascii;
-use crate::borrow::{Borrow, Cow};
-use crate::cmp::Ordering;
-use crate::error::Error;
-use crate::fmt::{self, Write};
-use crate::io;
-use crate::mem;
-use crate::num::NonZeroU8;
-use crate::ops;
-use crate::os::raw::c_char;
-use crate::ptr;
+use crate::borrow::{Cow, ToOwned};
+use crate::boxed::Box;
 use crate::rc::Rc;
-use crate::slice;
-use crate::str::{self, Utf8Error};
+use crate::slice::hack::into_vec;
+use crate::string::String;
+use crate::vec::Vec;
+use core::borrow::Borrow;
+use core::ffi::{c_char, CStr};
+use core::fmt;
+use core::mem;
+use core::num::NonZeroU8;
+use core::ops;
+use core::ptr;
+use core::slice;
+use core::slice::memchr;
+use core::str::{self, Utf8Error};
+
+#[cfg(target_has_atomic = "ptr")]
 use crate::sync::Arc;
-use crate::sys;
-use crate::sys_common::memchr;
 
 /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the
 /// middle.
@@ -108,7 +108,7 @@ use crate::sys_common::memchr;
 /// and other memory errors.
 #[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
 #[cfg_attr(not(test), rustc_diagnostic_item = "cstring_type")]
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "alloc_c_string", issue = "94079")]
 pub struct CString {
     // Invariant 1: the slice ends with a zero byte and has a length of at least one.
     // Invariant 2: the slice contains only one zero byte.
@@ -116,90 +116,6 @@ pub struct CString {
     inner: Box<[u8]>,
 }
 
-/// Representation of a borrowed C string.
-///
-/// This type represents a borrowed reference to a nul-terminated
-/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code>
-/// slice, or unsafely from a raw `*const c_char`. It can then be
-/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or
-/// into an owned [`CString`].
-///
-/// `&CStr` is to [`CString`] as <code>&[str]</code> is to [`String`]: the former
-/// in each pair are borrowed references; the latter are owned
-/// strings.
-///
-/// Note that this structure is **not** `repr(C)` and is not recommended to be
-/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI
-/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide
-/// a safe interface to other consumers.
-///
-/// # Examples
-///
-/// Inspecting a foreign C string:
-///
-/// ```ignore (extern-declaration)
-/// use std::ffi::CStr;
-/// use std::os::raw::c_char;
-///
-/// extern "C" { fn my_string() -> *const c_char; }
-///
-/// unsafe {
-///     let slice = CStr::from_ptr(my_string());
-///     println!("string buffer size without nul terminator: {}", slice.to_bytes().len());
-/// }
-/// ```
-///
-/// Passing a Rust-originating C string:
-///
-/// ```ignore (extern-declaration)
-/// use std::ffi::{CString, CStr};
-/// use std::os::raw::c_char;
-///
-/// fn work(data: &CStr) {
-///     extern "C" { fn work_with(data: *const c_char); }
-///
-///     unsafe { work_with(data.as_ptr()) }
-/// }
-///
-/// let s = CString::new("data data data data").expect("CString::new failed");
-/// work(&s);
-/// ```
-///
-/// Converting a foreign C string into a Rust [`String`]:
-///
-/// ```ignore (extern-declaration)
-/// use std::ffi::CStr;
-/// use std::os::raw::c_char;
-///
-/// extern "C" { fn my_string() -> *const c_char; }
-///
-/// fn my_string_safe() -> String {
-///     unsafe {
-///         CStr::from_ptr(my_string()).to_string_lossy().into_owned()
-///     }
-/// }
-///
-/// println!("string: {}", my_string_safe());
-/// ```
-///
-/// [str]: prim@str "str"
-#[derive(Hash)]
-#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")]
-#[stable(feature = "rust1", since = "1.0.0")]
-// FIXME:
-// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
-// on `CStr` being layout-compatible with `[u8]`.
-// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`.
-// Anyway, `CStr` representation and layout are considered implementation detail, are
-// not documented and must not be relied upon.
-pub struct CStr {
-    // FIXME: this should not be represented with a DST slice but rather with
-    //        just a raw `c_char` along with some form of marker to make
-    //        this an unsized type. Essentially `sizeof(&CStr)` should be the
-    //        same as `sizeof(&c_char)` but `CStr` should be an unsized type.
-    inner: [c_char],
-}
-
 /// An error indicating that an interior nul byte was found.
 ///
 /// While Rust strings may contain nul bytes in the middle, C strings
@@ -216,28 +132,13 @@ pub struct CStr {
 /// let _: NulError = CString::new(b"f\0oo".to_vec()).unwrap_err();
 /// ```
 #[derive(Clone, PartialEq, Eq, Debug)]
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "alloc_c_string", issue = "94079")]
 pub struct NulError(usize, Vec<u8>);
 
-/// An error indicating that a nul byte was not in the expected position.
-///
-/// The slice used to create a [`CStr`] must have one and only one nul byte,
-/// positioned at the end.
-///
-/// This error is created by the [`CStr::from_bytes_with_nul`] method.
-/// See its documentation for more.
-///
-/// # Examples
-///
-/// ```
-/// use std::ffi::{CStr, FromBytesWithNulError};
-///
-/// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err();
-/// ```
 #[derive(Clone, PartialEq, Eq, Debug)]
-#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-pub struct FromBytesWithNulError {
-    kind: FromBytesWithNulErrorKind,
+enum FromBytesWithNulErrorKind {
+    InteriorNul(usize),
+    NotNulTerminated,
 }
 
 /// An error indicating that a nul byte was not in the expected position.
@@ -256,27 +157,12 @@ pub struct FromBytesWithNulError {
 /// let _: FromVecWithNulError = CString::from_vec_with_nul(b"f\0oo".to_vec()).unwrap_err();
 /// ```
 #[derive(Clone, PartialEq, Eq, Debug)]
-#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
+#[unstable(feature = "alloc_c_string", issue = "94079")]
 pub struct FromVecWithNulError {
     error_kind: FromBytesWithNulErrorKind,
     bytes: Vec<u8>,
 }
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-enum FromBytesWithNulErrorKind {
-    InteriorNul(usize),
-    NotNulTerminated,
-}
-
-impl FromBytesWithNulError {
-    fn interior_nul(pos: usize) -> FromBytesWithNulError {
-        FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
-    }
-    fn not_nul_terminated() -> FromBytesWithNulError {
-        FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
-    }
-}
-
 #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 impl FromVecWithNulError {
     /// Returns a slice of [`u8`]s bytes that were attempted to convert to a [`CString`].
@@ -328,27 +214,6 @@ impl FromVecWithNulError {
     }
 }
 
-/// An error indicating that no nul byte was present.
-///
-/// A slice used to create a [`CStr`] must contain a nul byte somewhere
-/// within the slice.
-///
-/// This error is created by the [`CStr::from_bytes_until_nul`] method.
-///
-#[derive(Clone, PartialEq, Eq, Debug)]
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
-pub struct FromBytesUntilNulError(());
-
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
-impl Error for FromBytesUntilNulError {}
-
-#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
-impl fmt::Display for FromBytesUntilNulError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "data provided does not contain a nul")
-    }
-}
-
 /// An error indicating invalid UTF-8 when converting a [`CString`] into a [`String`].
 ///
 /// `CString` is just a wrapper over a buffer of bytes with a nul terminator;
@@ -358,7 +223,7 @@ impl fmt::Display for FromBytesUntilNulError {
 /// This `struct` is created by [`CString::into_string()`]. See
 /// its documentation for more.
 #[derive(Clone, PartialEq, Eq, Debug)]
-#[stable(feature = "cstring_into", since = "1.7.0")]
+#[unstable(feature = "alloc_c_string", issue = "94079")]
 pub struct IntoStringError {
     inner: CString,
     error: Utf8Error,
@@ -536,7 +401,11 @@ impl CString {
         // information about the size of the allocation is correct on Rust's
         // side.
         unsafe {
-            let len = sys::strlen(ptr) + 1; // Including the NUL byte
+            extern "C" {
+                /// Provided by libc or compiler_builtins.
+                fn strlen(s: *const c_char) -> usize;
+            }
+            let len = strlen(ptr) + 1; // Including the NUL byte
             let slice = slice::from_raw_parts_mut(ptr, len as usize);
             CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
         }
@@ -626,7 +495,7 @@ impl CString {
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes(self) -> Vec<u8> {
-        let mut vec = self.into_inner().into_vec();
+        let mut vec = into_vec(self.into_inner());
         let _nul = vec.pop();
         debug_assert_eq!(_nul, Some(0u8));
         vec
@@ -647,7 +516,7 @@ impl CString {
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes_with_nul(self) -> Vec<u8> {
-        self.into_inner().into_vec()
+        into_vec(self.into_inner())
     }
 
     /// Returns the contents of this `CString` as a slice of bytes.
@@ -842,7 +711,7 @@ impl ops::Deref for CString {
 
     #[inline]
     fn deref(&self) -> &CStr {
-        unsafe { CStr::_from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
+        unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
     }
 }
 
@@ -864,25 +733,6 @@ impl From<CString> for Vec<u8> {
     }
 }
 
-#[stable(feature = "cstr_debug", since = "1.3.0")]
-impl fmt::Debug for CStr {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "\"")?;
-        for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) {
-            f.write_char(byte as char)?;
-        }
-        write!(f, "\"")
-    }
-}
-
-#[stable(feature = "cstr_default", since = "1.10.0")]
-impl Default for &CStr {
-    fn default() -> Self {
-        const SLICE: &[c_char] = &[0];
-        unsafe { CStr::from_ptr(SLICE.as_ptr()) }
-    }
-}
-
 #[stable(feature = "cstr_default", since = "1.10.0")]
 impl Default for CString {
     /// Creates an empty `CString`.
@@ -910,6 +760,7 @@ impl<'a> From<Cow<'a, CStr>> for CString {
     }
 }
 
+#[cfg(not(test))]
 #[stable(feature = "box_from_c_str", since = "1.17.0")]
 impl From<&CStr> for Box<CStr> {
     /// Converts a `&CStr` into a `Box<CStr>`,
@@ -938,7 +789,8 @@ impl From<Box<CStr>> for CString {
     /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.
     #[inline]
     fn from(s: Box<CStr>) -> CString {
-        s.into_c_string()
+        let raw = Box::into_raw(s) as *mut [u8];
+        CString { inner: unsafe { Box::from_raw(raw) } }
     }
 }
 
@@ -964,6 +816,7 @@ impl From<Vec<NonZeroU8>> for CString {
     }
 }
 
+#[cfg(not(test))]
 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
 impl Clone for Box<CStr> {
     #[inline]
@@ -1008,6 +861,7 @@ impl<'a> From<&'a CString> for Cow<'a, CStr> {
     }
 }
 
+#[cfg(target_has_atomic = "ptr")]
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<CString> for Arc<CStr> {
     /// Converts a [`CString`] into an <code>[Arc]<[CStr]></code> by moving the [`CString`]
@@ -1019,6 +873,7 @@ impl From<CString> for Arc<CStr> {
     }
 }
 
+#[cfg(target_has_atomic = "ptr")]
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<&CStr> for Arc<CStr> {
     /// Converts a `&CStr` into a `Arc<CStr>`,
@@ -1052,6 +907,7 @@ impl From<&CStr> for Rc<CStr> {
     }
 }
 
+#[cfg(not(test))]
 #[stable(feature = "default_box_extra", since = "1.17.0")]
 impl Default for Box<CStr> {
     fn default() -> Box<CStr> {
@@ -1100,56 +956,12 @@ impl NulError {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Error for NulError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        "nul byte found in data"
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for NulError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "nul byte found in provided data at position: {}", self.0)
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl From<NulError> for io::Error {
-    /// Converts a [`NulError`] into a [`io::Error`].
-    fn from(_: NulError) -> io::Error {
-        io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
-    }
-}
-
-#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
-impl Error for FromBytesWithNulError {
-    #[allow(deprecated)]
-    fn description(&self) -> &str {
-        match self.kind {
-            FromBytesWithNulErrorKind::InteriorNul(..) => {
-                "data provided contains an interior nul byte"
-            }
-            FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated",
-        }
-    }
-}
-
-#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
-impl fmt::Display for FromBytesWithNulError {
-    #[allow(deprecated, deprecated_in_future)]
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.description())?;
-        if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind {
-            write!(f, " at byte pos {pos}")?;
-        }
-        Ok(())
-    }
-}
-
-#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
-impl Error for FromVecWithNulError {}
-
 #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
 impl fmt::Display for FromVecWithNulError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1179,18 +991,18 @@ impl IntoStringError {
     pub fn utf8_error(&self) -> Utf8Error {
         self.error
     }
+
+    #[doc(hidden)]
+    #[unstable(feature = "cstr_internals", issue = "none")]
+    pub fn __source(&self) -> &Utf8Error {
+        &self.error
+    }
 }
 
-#[stable(feature = "cstring_into", since = "1.7.0")]
-impl Error for IntoStringError {
-    #[allow(deprecated)]
+impl IntoStringError {
     fn description(&self) -> &str {
         "C string contained non-utf8 bytes"
     }
-
-    fn source(&self) -> Option<&(dyn Error + 'static)> {
-        Some(&self.error)
-    }
 }
 
 #[stable(feature = "cstring_into", since = "1.7.0")]
@@ -1201,327 +1013,126 @@ impl fmt::Display for IntoStringError {
     }
 }
 
-impl CStr {
-    /// Wraps a raw C string with a safe C string wrapper.
-    ///
-    /// This function will wrap the provided `ptr` with a `CStr` wrapper, which
-    /// allows inspection and interoperation of non-owned C strings. The total
-    /// size of the raw C string must be smaller than `isize::MAX` **bytes**
-    /// in memory due to calling the `slice::from_raw_parts` function.
-    /// This method is unsafe for a number of reasons:
-    ///
-    /// * There is no guarantee to the validity of `ptr`.
-    /// * The returned lifetime is not guaranteed to be the actual lifetime of
-    ///   `ptr`.
-    /// * There is no guarantee that the memory pointed to by `ptr` contains a
-    ///   valid nul terminator byte at the end of the string.
-    /// * It is not guaranteed that the memory pointed by `ptr` won't change
-    ///   before the `CStr` has been destroyed.
-    ///
-    /// > **Note**: This operation is intended to be a 0-cost cast but it is
-    /// > currently implemented with an up-front calculation of the length of
-    /// > the string. This is not guaranteed to always be the case.
-    ///
-    /// # Examples
-    ///
-    /// ```ignore (extern-declaration)
-    /// # fn main() {
-    /// use std::ffi::CStr;
-    /// use std::os::raw::c_char;
-    ///
-    /// extern "C" {
-    ///     fn my_string() -> *const c_char;
-    /// }
-    ///
-    /// unsafe {
-    ///     let slice = CStr::from_ptr(my_string());
-    ///     println!("string returned: {}", slice.to_str().unwrap());
-    /// }
-    /// # }
-    /// ```
-    #[inline]
-    #[must_use]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
-        // SAFETY: The caller has provided a pointer that points to a valid C
-        // string with a NUL terminator of size less than `isize::MAX`, whose
-        // content remain valid and doesn't change for the lifetime of the
-        // returned `CStr`.
-        //
-        // Thus computing the length is fine (a NUL byte exists), the call to
-        // from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning
-        // the call to `from_bytes_with_nul_unchecked` is correct.
-        //
-        // The cast from c_char to u8 is ok because a c_char is always one byte.
-        unsafe {
-            let len = sys::strlen(ptr);
-            let ptr = ptr as *const u8;
-            Self::_from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
-        }
-    }
+#[stable(feature = "cstr_borrow", since = "1.3.0")]
+impl ToOwned for CStr {
+    type Owned = CString;
 
-    /// Creates a C string wrapper from a byte slice.
-    ///
-    /// This method will create a `CStr` from any byte slice that contains at
-    /// least one nul byte. The caller does not need to know or specify where
-    /// the nul byte is located.
-    ///
-    /// If the first byte is a nul character, this method will return an
-    /// empty `CStr`. If multiple nul characters are present, the `CStr` will
-    /// end at the first one.
-    ///
-    /// If the slice only has a single nul byte at the end, this method is
-    /// equivalent to [`CStr::from_bytes_with_nul`].
-    ///
-    /// # Examples
-    /// ```
-    /// #![feature(cstr_from_bytes_until_nul)]
-    ///
-    /// use std::ffi::CStr;
-    ///
-    /// let mut buffer = [0u8; 16];
-    /// unsafe {
-    ///     // Here we might call an unsafe C function that writes a string
-    ///     // into the buffer.
-    ///     let buf_ptr = buffer.as_mut_ptr();
-    ///     buf_ptr.write_bytes(b'A', 8);
-    /// }
-    /// // Attempt to extract a C nul-terminated string from the buffer.
-    /// let c_str = CStr::from_bytes_until_nul(&buffer[..]).unwrap();
-    /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA");
-    /// ```
-    ///
-    #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
-    pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
-        let nul_pos = memchr::memchr(0, bytes);
-        match nul_pos {
-            Some(nul_pos) => {
-                // SAFETY: We know there is a nul byte at nul_pos, so this slice
-                // (ending at the nul byte) is a well-formed C string.
-                let subslice = &bytes[..nul_pos + 1];
-                Ok(unsafe { CStr::from_bytes_with_nul_unchecked(subslice) })
-            }
-            None => Err(FromBytesUntilNulError(())),
-        }
+    fn to_owned(&self) -> CString {
+        CString { inner: self.to_bytes_with_nul().into() }
     }
 
-    /// Creates a C string wrapper from a byte slice.
-    ///
-    /// This function will cast the provided `bytes` to a `CStr`
-    /// wrapper after ensuring that the byte slice is nul-terminated
-    /// and does not contain any interior nul bytes.
-    ///
-    /// If the nul byte may not be at the end,
-    /// [`CStr::from_bytes_until_nul`] can be used instead.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::ffi::CStr;
-    ///
-    /// let cstr = CStr::from_bytes_with_nul(b"hello\0");
-    /// assert!(cstr.is_ok());
-    /// ```
-    ///
-    /// Creating a `CStr` without a trailing nul terminator is an error:
-    ///
-    /// ```
-    /// use std::ffi::CStr;
-    ///
-    /// let cstr = CStr::from_bytes_with_nul(b"hello");
-    /// assert!(cstr.is_err());
-    /// ```
-    ///
-    /// Creating a `CStr` with an interior nul byte is an error:
-    ///
-    /// ```
-    /// use std::ffi::CStr;
-    ///
-    /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
-    /// assert!(cstr.is_err());
-    /// ```
-    #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
-        let nul_pos = memchr::memchr(0, bytes);
-        match nul_pos {
-            Some(nul_pos) if nul_pos + 1 == bytes.len() => {
-                // SAFETY: We know there is only one nul byte, at the end
-                // of the byte slice.
-                Ok(unsafe { Self::_from_bytes_with_nul_unchecked(bytes) })
-            }
-            Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
-            None => Err(FromBytesWithNulError::not_nul_terminated()),
-        }
+    fn clone_into(&self, target: &mut CString) {
+        let mut b = into_vec(mem::take(&mut target.inner));
+        self.to_bytes_with_nul().clone_into(&mut b);
+        target.inner = b.into_boxed_slice();
     }
+}
 
-    /// Unsafely creates a C string wrapper from a byte slice.
-    ///
-    /// This function will cast the provided `bytes` to a `CStr` wrapper without
-    /// performing any sanity checks. The provided slice **must** be nul-terminated
-    /// and not contain any interior nul bytes.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::ffi::{CStr, CString};
-    ///
-    /// unsafe {
-    ///     let cstring = CString::new("hello").expect("CString::new failed");
-    ///     let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
-    ///     assert_eq!(cstr, &*cstring);
-    /// }
-    /// ```
-    #[inline]
-    #[must_use]
-    #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-    #[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")]
-    pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
-        // We're in a const fn, so this is the best we can do
-        debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0);
-        unsafe { Self::_from_bytes_with_nul_unchecked(bytes) }
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl From<&CStr> for CString {
+    fn from(s: &CStr) -> CString {
+        s.to_owned()
     }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl ops::Index<ops::RangeFull> for CString {
+    type Output = CStr;
 
     #[inline]
-    const unsafe fn _from_bytes_with_nul_unchecked(bytes: &[u8]) -> &Self {
-        // SAFETY: Casting to CStr is safe because its internal representation
-        // is a [u8] too (safe only inside std).
-        // Dereferencing the obtained pointer is safe because it comes from a
-        // reference. Making a reference is then safe because its lifetime
-        // is bound by the lifetime of the given `bytes`.
-        unsafe { &*(bytes as *const [u8] as *const Self) }
+    fn index(&self, _index: ops::RangeFull) -> &CStr {
+        self
     }
+}
 
-    /// Returns the inner pointer to this C string.
-    ///
-    /// The returned pointer will be valid for as long as `self` is, and points
-    /// to a contiguous region of memory terminated with a 0 byte to represent
-    /// the end of the string.
-    ///
-    /// **WARNING**
-    ///
-    /// The returned pointer is read-only; writing to it (including passing it
-    /// to C code that writes to it) causes undefined behavior.
-    ///
-    /// It is your responsibility to make sure that the underlying memory is not
-    /// freed too early. For example, the following code will cause undefined
-    /// behavior when `ptr` is used inside the `unsafe` block:
-    ///
-    /// ```no_run
-    /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)]
-    /// use std::ffi::CString;
-    ///
-    /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr();
-    /// unsafe {
-    ///     // `ptr` is dangling
-    ///     *ptr;
-    /// }
-    /// ```
-    ///
-    /// This happens because the pointer returned by `as_ptr` does not carry any
-    /// lifetime information and the [`CString`] is deallocated immediately after
-    /// the `CString::new("Hello").expect("CString::new failed").as_ptr()`
-    /// expression is evaluated.
-    /// To fix the problem, bind the `CString` to a local variable:
-    ///
-    /// ```no_run
-    /// # #![allow(unused_must_use)]
-    /// use std::ffi::CString;
-    ///
-    /// let hello = CString::new("Hello").expect("CString::new failed");
-    /// let ptr = hello.as_ptr();
-    /// unsafe {
-    ///     // `ptr` is valid because `hello` is in scope
-    ///     *ptr;
-    /// }
-    /// ```
-    ///
-    /// This way, the lifetime of the [`CString`] in `hello` encompasses
-    /// the lifetime of `ptr` and the `unsafe` block.
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl AsRef<CStr> for CString {
     #[inline]
-    #[must_use]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
-    pub const fn as_ptr(&self) -> *const c_char {
-        self.inner.as_ptr()
+    fn as_ref(&self) -> &CStr {
+        self
     }
+}
 
-    /// Converts this C string to a byte slice.
+#[cfg(bootstrap)]
+#[doc(hidden)]
+#[unstable(feature = "cstr_internals", issue = "none")]
+pub trait CStrExt {
+    /// Converts a `CStr` into a <code>[Cow]<[str]></code>.
     ///
-    /// The returned slice will **not** contain the trailing nul terminator that this C
-    /// string has.
+    /// If the contents of the `CStr` are valid UTF-8 data, this
+    /// function will return a <code>[Cow]::[Borrowed]\(&[str])</code>
+    /// with the corresponding <code>&[str]</code> slice. Otherwise, it will
+    /// replace any invalid UTF-8 sequences with
+    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
+    /// <code>[Cow]::[Owned]\(&[str])</code> with the result.
     ///
-    /// > **Note**: This method is currently implemented as a constant-time
-    /// > cast, but it is planned to alter its definition in the future to
-    /// > perform the length calculation whenever this method is called.
+    /// [str]: prim@str "str"
+    /// [Borrowed]: Cow::Borrowed
+    /// [Owned]: Cow::Owned
+    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER"
     ///
     /// # Examples
     ///
+    /// Calling `to_string_lossy` on a `CStr` containing valid UTF-8:
+    ///
     /// ```
+    /// use std::borrow::Cow;
     /// use std::ffi::CStr;
     ///
-    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(cstr.to_bytes(), b"foo");
+    /// let cstr = CStr::from_bytes_with_nul(b"Hello World\0")
+    ///                  .expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World"));
     /// ```
-    #[inline]
-    #[must_use = "this returns the result of the operation, \
-                  without modifying the original"]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_bytes(&self) -> &[u8] {
-        let bytes = self.to_bytes_with_nul();
-        // SAFETY: to_bytes_with_nul returns slice with length at least 1
-        unsafe { bytes.get_unchecked(..bytes.len() - 1) }
-    }
-
-    /// Converts this C string to a byte slice containing the trailing 0 byte.
     ///
-    /// This function is the equivalent of [`CStr::to_bytes`] except that it
-    /// will retain the trailing nul terminator instead of chopping it off.
-    ///
-    /// > **Note**: This method is currently implemented as a 0-cost cast, but
-    /// > it is planned to alter its definition in the future to perform the
-    /// > length calculation whenever this method is called.
-    ///
-    /// # Examples
+    /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
     ///
     /// ```
+    /// use std::borrow::Cow;
     /// use std::ffi::CStr;
     ///
-    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0");
+    /// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
+    ///                  .expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(
+    ///     cstr.to_string_lossy(),
+    ///     Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
+    /// );
     /// ```
-    #[inline]
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn to_bytes_with_nul(&self) -> &[u8] {
-        unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
-    }
+    #[stable(feature = "cstr_to_str", since = "1.4.0")]
+    fn to_string_lossy(&self) -> Cow<'_, str>;
 
-    /// Yields a <code>&[str]</code> slice if the `CStr` contains valid UTF-8.
-    ///
-    /// If the contents of the `CStr` are valid UTF-8 data, this
-    /// function will return the corresponding <code>&[str]</code> slice. Otherwise,
-    /// it will return an error with details of where UTF-8 validation failed.
-    ///
-    /// [str]: prim@str "str"
+    /// Converts a <code>[Box]<[CStr]></code> into a [`CString`] without copying or allocating.
     ///
     /// # Examples
     ///
     /// ```
-    /// use std::ffi::CStr;
+    /// use std::ffi::CString;
     ///
-    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(cstr.to_str(), Ok("foo"));
+    /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed");
+    /// let boxed = c_string.into_boxed_c_str();
+    /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("CString::new failed"));
     /// ```
-    #[stable(feature = "cstr_to_str", since = "1.4.0")]
-    pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
-        // N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
-        // instead of in `from_ptr()`, it may be worth considering if this should
-        // be rewritten to do the UTF-8 check inline with the length calculation
-        // instead of doing it afterwards.
-        str::from_utf8(self.to_bytes())
+    #[must_use = "`self` will be dropped if the result is not used"]
+    #[stable(feature = "into_boxed_c_str", since = "1.20.0")]
+    fn into_c_string(self: Box<Self>) -> CString;
+}
+
+#[cfg(bootstrap)]
+#[unstable(feature = "cstr_internals", issue = "none")]
+impl CStrExt for CStr {
+    fn to_string_lossy(&self) -> Cow<'_, str> {
+        String::from_utf8_lossy(self.to_bytes())
     }
 
+    fn into_c_string(self: Box<Self>) -> CString {
+        CString::from(self)
+    }
+}
+
+#[cfg(not(bootstrap))]
+#[cfg(not(test))]
+impl CStr {
     /// Converts a `CStr` into a <code>[Cow]<[str]></code>.
     ///
     /// If the contents of the `CStr` are valid UTF-8 data, this
@@ -1534,7 +1145,7 @@ impl CStr {
     /// [str]: prim@str "str"
     /// [Borrowed]: Cow::Borrowed
     /// [Owned]: Cow::Owned
-    /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER"
+    /// [U+FFFD]: core::char::REPLACEMENT_CHARACTER "std::char::REPLACEMENT_CHARACTER"
     ///
     /// # Examples
     ///
@@ -1562,6 +1173,7 @@ impl CStr {
     ///     Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
     /// );
     /// ```
+    #[rustc_allow_incoherent_impl]
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
@@ -1580,101 +1192,10 @@ impl CStr {
     /// let boxed = c_string.into_boxed_c_str();
     /// assert_eq!(boxed.into_c_string(), CString::new("foo").expect("CString::new failed"));
     /// ```
+    #[rustc_allow_incoherent_impl]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "into_boxed_c_str", since = "1.20.0")]
-    pub fn into_c_string(self: Box<CStr>) -> CString {
-        let raw = Box::into_raw(self) as *mut [u8];
-        CString { inner: unsafe { Box::from_raw(raw) } }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for CStr {
-    fn eq(&self, other: &CStr) -> bool {
-        self.to_bytes().eq(other.to_bytes())
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for CStr {}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialOrd for CStr {
-    fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
-        self.to_bytes().partial_cmp(&other.to_bytes())
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Ord for CStr {
-    fn cmp(&self, other: &CStr) -> Ordering {
-        self.to_bytes().cmp(&other.to_bytes())
-    }
-}
-
-#[stable(feature = "cstr_borrow", since = "1.3.0")]
-impl ToOwned for CStr {
-    type Owned = CString;
-
-    fn to_owned(&self) -> CString {
-        CString { inner: self.to_bytes_with_nul().into() }
-    }
-
-    fn clone_into(&self, target: &mut CString) {
-        let mut b = Vec::from(mem::take(&mut target.inner));
-        self.to_bytes_with_nul().clone_into(&mut b);
-        target.inner = b.into_boxed_slice();
-    }
-}
-
-#[stable(feature = "cstring_asref", since = "1.7.0")]
-impl From<&CStr> for CString {
-    /// Copies the contents of the `&CStr` into a newly allocated `CString`.
-    fn from(s: &CStr) -> CString {
-        s.to_owned()
-    }
-}
-
-#[stable(feature = "cstring_asref", since = "1.7.0")]
-impl ops::Index<ops::RangeFull> for CString {
-    type Output = CStr;
-
-    #[inline]
-    fn index(&self, _index: ops::RangeFull) -> &CStr {
-        self
-    }
-}
-
-#[stable(feature = "cstr_range_from", since = "1.47.0")]
-impl ops::Index<ops::RangeFrom<usize>> for CStr {
-    type Output = CStr;
-
-    fn index(&self, index: ops::RangeFrom<usize>) -> &CStr {
-        let bytes = self.to_bytes_with_nul();
-        // we need to manually check the starting index to account for the null
-        // byte, since otherwise we could get an empty string that doesn't end
-        // in a null.
-        if index.start < bytes.len() {
-            unsafe { CStr::_from_bytes_with_nul_unchecked(&bytes[index.start..]) }
-        } else {
-            panic!(
-                "index out of bounds: the len is {} but the index is {}",
-                bytes.len(),
-                index.start
-            );
-        }
-    }
-}
-
-#[stable(feature = "cstring_asref", since = "1.7.0")]
-impl AsRef<CStr> for CStr {
-    #[inline]
-    fn as_ref(&self) -> &CStr {
-        self
-    }
-}
-
-#[stable(feature = "cstring_asref", since = "1.7.0")]
-impl AsRef<CStr> for CString {
-    #[inline]
-    fn as_ref(&self) -> &CStr {
-        self
+    pub fn into_c_string(self: Box<Self>) -> CString {
+        CString::from(self)
     }
 }
diff --git a/library/std/src/ffi/c_str/tests.rs b/library/alloc/src/ffi/c_str/tests.rs
index c20da138a18..0b7476d5cc7 100644
--- a/library/std/src/ffi/c_str/tests.rs
+++ b/library/alloc/src/ffi/c_str/tests.rs
@@ -1,10 +1,12 @@
 use super::*;
-use crate::borrow::Cow::{Borrowed, Owned};
-use crate::collections::hash_map::DefaultHasher;
-use crate::hash::{Hash, Hasher};
-use crate::os::raw::c_char;
 use crate::rc::Rc;
 use crate::sync::Arc;
+use core::assert_matches::assert_matches;
+use core::ffi::FromBytesUntilNulError;
+use core::hash::{Hash, Hasher};
+
+#[allow(deprecated)]
+use core::hash::SipHasher13 as DefaultHasher;
 
 #[test]
 fn c_to_rust() {
@@ -48,22 +50,6 @@ fn borrowed() {
 }
 
 #[test]
-fn to_str() {
-    let data = b"123\xE2\x80\xA6\0";
-    let ptr = data.as_ptr() as *const c_char;
-    unsafe {
-        assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…"));
-        assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…"));
-    }
-    let data = b"123\xE2\0";
-    let ptr = data.as_ptr() as *const c_char;
-    unsafe {
-        assert!(CStr::from_ptr(ptr).to_str().is_err());
-        assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}")));
-    }
-}
-
-#[test]
 fn to_owned() {
     let data = b"123\0";
     let ptr = data.as_ptr() as *const c_char;
@@ -78,9 +64,11 @@ fn equal_hash() {
     let ptr = data.as_ptr() as *const c_char;
     let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) };
 
+    #[allow(deprecated)]
     let mut s = DefaultHasher::new();
     cstr.hash(&mut s);
     let cstr_hash = s.finish();
+    #[allow(deprecated)]
     let mut s = DefaultHasher::new();
     CString::new(&data[..data.len() - 1]).unwrap().hash(&mut s);
     let cstring_hash = s.finish();
@@ -122,11 +110,11 @@ fn cstr_from_bytes_until_nul() {
     // Test an empty slice. This should fail because it
     // does not contain a nul byte.
     let b = b"";
-    assert_eq!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError(())));
+    assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
 
     // Test a non-empty slice, that does not contain a nul byte.
     let b = b"hello";
-    assert_eq!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError(())));
+    assert_matches!(CStr::from_bytes_until_nul(&b[..]), Err(FromBytesUntilNulError { .. }));
 
     // Test an empty nul-terminated string
     let b = b"\0";
diff --git a/library/alloc/src/ffi/mod.rs b/library/alloc/src/ffi/mod.rs
new file mode 100644
index 00000000000..eed2851c153
--- /dev/null
+++ b/library/alloc/src/ffi/mod.rs
@@ -0,0 +1,91 @@
+//! Utilities related to FFI bindings.
+//!
+//! This module provides utilities to handle data across non-Rust
+//! interfaces, like other programming languages and the underlying
+//! operating system. It is mainly of use for FFI (Foreign Function
+//! Interface) bindings and code that needs to exchange C-like strings
+//! with other languages.
+//!
+//! # Overview
+//!
+//! Rust represents owned strings with the [`String`] type, and
+//! borrowed slices of strings with the [`str`] primitive. Both are
+//! always in UTF-8 encoding, and may contain nul bytes in the middle,
+//! i.e., if you look at the bytes that make up the string, there may
+//! be a `\0` among them. Both `String` and `str` store their length
+//! explicitly; there are no nul terminators at the end of strings
+//! like in C.
+//!
+//! C strings are different from Rust strings:
+//!
+//! * **Encodings** - Rust strings are UTF-8, but C strings may use
+//! other encodings. If you are using a string from C, you should
+//! check its encoding explicitly, rather than just assuming that it
+//! is UTF-8 like you can do in Rust.
+//!
+//! * **Character size** - C strings may use `char` or `wchar_t`-sized
+//! characters; please **note** that C's `char` is different from Rust's.
+//! The C standard leaves the actual sizes of those types open to
+//! interpretation, but defines different APIs for strings made up of
+//! each character type. Rust strings are always UTF-8, so different
+//! Unicode characters will be encoded in a variable number of bytes
+//! each. The Rust type [`char`] represents a '[Unicode scalar
+//! value]', which is similar to, but not the same as, a '[Unicode
+//! code point]'.
+//!
+//! * **Nul terminators and implicit string lengths** - Often, C
+//! strings are nul-terminated, i.e., they have a `\0` character at the
+//! end. The length of a string buffer is not stored, but has to be
+//! calculated; to compute the length of a string, C code must
+//! manually call a function like `strlen()` for `char`-based strings,
+//! or `wcslen()` for `wchar_t`-based ones. Those functions return
+//! the number of characters in the string excluding the nul
+//! terminator, so the buffer length is really `len+1` characters.
+//! Rust strings don't have a nul terminator; their length is always
+//! stored and does not need to be calculated. While in Rust
+//! accessing a string's length is an *O*(1) operation (because the
+//! length is stored); in C it is an *O*(*n*) operation because the
+//! length needs to be computed by scanning the string for the nul
+//! terminator.
+//!
+//! * **Internal nul characters** - When C strings have a nul
+//! terminator character, this usually means that they cannot have nul
+//! characters in the middle — a nul character would essentially
+//! truncate the string. Rust strings *can* have nul characters in
+//! the middle, because nul does not have to mark the end of the
+//! string in Rust.
+//!
+//! # Representations of non-Rust strings
+//!
+//! [`CString`] and [`CStr`] are useful when you need to transfer
+//! UTF-8 strings to and from languages with a C ABI, like Python.
+//!
+//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
+//! string: it is nul-terminated, and has no internal nul characters.
+//! Rust code can create a [`CString`] out of a normal string (provided
+//! that the string doesn't have nul characters in the middle), and
+//! then use a variety of methods to obtain a raw <code>\*mut [u8]</code> that can
+//! then be passed as an argument to functions which use the C
+//! conventions for strings.
+//!
+//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
+//! is what you would use to wrap a raw <code>\*const [u8]</code> that you got from
+//! a C function. A [`CStr`] is guaranteed to be a nul-terminated array
+//! of bytes. Once you have a [`CStr`], you can convert it to a Rust
+//! <code>&[str]</code> if it's valid UTF-8, or lossily convert it by adding
+//! replacement characters.
+//!
+//! [`String`]: crate::string::String
+//! [`CStr`]: core::ffi::CStr
+
+#![unstable(feature = "alloc_ffi", issue = "94079")]
+
+#[cfg(bootstrap)]
+#[unstable(feature = "cstr_internals", issue = "none")]
+pub use self::c_str::CStrExt;
+#[unstable(feature = "alloc_c_string", issue = "94079")]
+pub use self::c_str::FromVecWithNulError;
+#[unstable(feature = "alloc_c_string", issue = "94079")]
+pub use self::c_str::{CString, IntoStringError, NulError};
+
+mod c_str;
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index c54001dceea..4d2dc4ecee0 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -86,11 +86,13 @@
 #![allow(explicit_outlives_requirements)]
 //
 // Library features:
+#![cfg_attr(not(no_global_oom_handling), feature(alloc_c_string))]
 #![feature(alloc_layout_extra)]
 #![feature(allocator_api)]
 #![feature(array_chunks)]
 #![feature(array_methods)]
 #![feature(array_windows)]
+#![feature(assert_matches)]
 #![feature(async_iterator)]
 #![feature(coerce_unsized)]
 #![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
@@ -104,9 +106,12 @@
 #![feature(const_maybe_uninit_write)]
 #![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_refs_to_cell)]
+#![feature(core_c_str)]
 #![feature(core_intrinsics)]
+#![feature(core_ffi_c)]
 #![feature(const_eval_select)]
 #![feature(const_pin)]
+#![feature(cstr_from_bytes_until_nul)]
 #![feature(dispatch_from_dyn)]
 #![feature(exact_size_is_empty)]
 #![feature(extend_one)]
@@ -152,6 +157,7 @@
 #![feature(exclusive_range_pattern)]
 #![feature(fundamental)]
 #![cfg_attr(not(test), feature(generator_trait))]
+#![feature(hashmap_internals)]
 #![feature(lang_items)]
 #![feature(let_else)]
 #![feature(min_specialization)]
@@ -160,6 +166,7 @@
 #![feature(nll)] // Not necessary, but here to test the `nll` feature.
 #![feature(rustc_allow_const_fn_unstable)]
 #![feature(rustc_attrs)]
+#![feature(slice_internals)]
 #![feature(staged_api)]
 #![cfg_attr(test, feature(test))]
 #![feature(unboxed_closures)]
@@ -205,6 +212,8 @@ mod boxed {
 }
 pub mod borrow;
 pub mod collections;
+#[cfg(not(no_global_oom_handling))]
+pub mod ffi;
 pub mod fmt;
 pub mod rc;
 pub mod slice;
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index d0d37c08d13..a42f1c3b4bb 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -2511,14 +2511,23 @@ trait RcInnerPtr {
     fn inc_strong(&self) {
         let strong = self.strong();
 
+        // We insert an `assume` here to hint LLVM at an otherwise
+        // missed optimization.
+        // SAFETY: The reference count will never be zero when this is
+        // called.
+        unsafe {
+            core::intrinsics::assume(strong != 0);
+        }
+
+        let strong = strong.wrapping_add(1);
+        self.strong_ref().set(strong);
+
         // We want to abort on overflow instead of dropping the value.
-        // The reference count will never be zero when this is called;
-        // nevertheless, we insert an abort here to hint LLVM at
-        // an otherwise missed optimization.
-        if strong == 0 || strong == usize::MAX {
+        // Checking for overflow after the store instead of before
+        // allows for slightly better code generation.
+        if core::intrinsics::unlikely(strong == 0) {
             abort();
         }
-        self.strong_ref().set(strong + 1);
     }
 
     #[inline]
@@ -2535,14 +2544,23 @@ trait RcInnerPtr {
     fn inc_weak(&self) {
         let weak = self.weak();
 
+        // We insert an `assume` here to hint LLVM at an otherwise
+        // missed optimization.
+        // SAFETY: The reference count will never be zero when this is
+        // called.
+        unsafe {
+            core::intrinsics::assume(weak != 0);
+        }
+
+        let weak = weak.wrapping_add(1);
+        self.weak_ref().set(weak);
+
         // We want to abort on overflow instead of dropping the value.
-        // The reference count will never be zero when this is called;
-        // nevertheless, we insert an abort here to hint LLVM at
-        // an otherwise missed optimization.
-        if weak == 0 || weak == usize::MAX {
+        // Checking for overflow after the store instead of before
+        // allows for slightly better code generation.
+        if core::intrinsics::unlikely(weak == 0) {
             abort();
         }
-        self.weak_ref().set(weak + 1);
     }
 
     #[inline]
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 31edbe0c5af..02a47c57b8a 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -153,7 +153,7 @@ pub use hack::to_vec;
 // functions are actually methods that are in `impl [T]` but not in
 // `core::slice::SliceExt` - we need to supply these functions for the
 // `test_permutations` test
-mod hack {
+pub(crate) mod hack {
     use core::alloc::Allocator;
 
     use crate::boxed::Box;
diff --git a/library/alloc/tests/c_str.rs b/library/alloc/tests/c_str.rs
new file mode 100644
index 00000000000..8fbb10e1d5c
--- /dev/null
+++ b/library/alloc/tests/c_str.rs
@@ -0,0 +1,18 @@
+use std::borrow::Cow::{Borrowed, Owned};
+use std::ffi::{c_char, CStr};
+
+#[test]
+fn to_str() {
+    let data = b"123\xE2\x80\xA6\0";
+    let ptr = data.as_ptr() as *const c_char;
+    unsafe {
+        assert_eq!(CStr::from_ptr(ptr).to_str(), Ok("123…"));
+        assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Borrowed("123…"));
+    }
+    let data = b"123\xE2\0";
+    let ptr = data.as_ptr() as *const c_char;
+    unsafe {
+        assert!(CStr::from_ptr(ptr).to_str().is_err());
+        assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}")));
+    }
+}
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index 16d3b368595..8de159246c6 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -12,6 +12,8 @@
 #![feature(const_nonnull_slice_from_raw_parts)]
 #![feature(const_ptr_write)]
 #![feature(const_try)]
+#![feature(core_c_str)]
+#![feature(core_ffi_c)]
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(exact_size_is_empty)]
@@ -49,6 +51,7 @@ mod binary_heap;
 mod borrow;
 mod boxed;
 mod btree_set_hash;
+mod c_str;
 mod const_fns;
 mod cow_str;
 mod fmt;
diff --git a/library/core/src/default.rs b/library/core/src/default.rs
index fb862f7df94..1ce00828bf3 100644
--- a/library/core/src/default.rs
+++ b/library/core/src/default.rs
@@ -52,6 +52,23 @@
 /// This trait can be used with `#[derive]` if all of the type's fields implement
 /// `Default`. When `derive`d, it will use the default value for each field's type.
 ///
+/// ### `enum`s
+///
+/// When using `#[derive(Default)]` on an `enum`, you need to choose which unit variant will be
+/// default. You do this by placing the `#[default]` attribute on the variant.
+///
+/// ```
+/// #[derive(Default)]
+/// enum Kind {
+///     #[default]
+///     A,
+///     B,
+///     C,
+/// }
+/// ```
+///
+/// You cannot use the `#[default]` attribute on non-unit or non-exhaustive variants.
+///
 /// ## How can I implement `Default`?
 ///
 /// Provide an implementation for the `default()` method that returns the value of
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
new file mode 100644
index 00000000000..15d9d013997
--- /dev/null
+++ b/library/core/src/ffi/c_str.rs
@@ -0,0 +1,570 @@
+use crate::ascii;
+use crate::cmp::Ordering;
+use crate::ffi::c_char;
+use crate::fmt::{self, Write};
+use crate::ops;
+use crate::slice;
+use crate::slice::memchr;
+use crate::str;
+
+/// Representation of a borrowed C string.
+///
+/// This type represents a borrowed reference to a nul-terminated
+/// array of bytes. It can be constructed safely from a <code>&[[u8]]</code>
+/// slice, or unsafely from a raw `*const c_char`. It can then be
+/// converted to a Rust <code>&[str]</code> by performing UTF-8 validation, or
+/// into an owned `CString`.
+///
+/// `&CStr` is to `CString` as <code>&[str]</code> is to `String`: the former
+/// in each pair are borrowed references; the latter are owned
+/// strings.
+///
+/// Note that this structure is **not** `repr(C)` and is not recommended to be
+/// placed in the signatures of FFI functions. Instead, safe wrappers of FFI
+/// functions may leverage the unsafe [`CStr::from_ptr`] constructor to provide
+/// a safe interface to other consumers.
+///
+/// # Examples
+///
+/// Inspecting a foreign C string:
+///
+/// ```ignore (extern-declaration)
+/// use std::ffi::CStr;
+/// use std::os::raw::c_char;
+///
+/// extern "C" { fn my_string() -> *const c_char; }
+///
+/// unsafe {
+///     let slice = CStr::from_ptr(my_string());
+///     println!("string buffer size without nul terminator: {}", slice.to_bytes().len());
+/// }
+/// ```
+///
+/// Passing a Rust-originating C string:
+///
+/// ```ignore (extern-declaration)
+/// use std::ffi::{CString, CStr};
+/// use std::os::raw::c_char;
+///
+/// fn work(data: &CStr) {
+///     extern "C" { fn work_with(data: *const c_char); }
+///
+///     unsafe { work_with(data.as_ptr()) }
+/// }
+///
+/// let s = CString::new("data data data data").expect("CString::new failed");
+/// work(&s);
+/// ```
+///
+/// Converting a foreign C string into a Rust `String`:
+///
+/// ```ignore (extern-declaration)
+/// use std::ffi::CStr;
+/// use std::os::raw::c_char;
+///
+/// extern "C" { fn my_string() -> *const c_char; }
+///
+/// fn my_string_safe() -> String {
+///     unsafe {
+///         CStr::from_ptr(my_string()).to_string_lossy().into_owned()
+///     }
+/// }
+///
+/// println!("string: {}", my_string_safe());
+/// ```
+///
+/// [str]: prim@str "str"
+#[derive(Hash)]
+#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")]
+#[unstable(feature = "core_c_str", issue = "94079")]
+#[cfg_attr(not(bootstrap), lang = "CStr")]
+// FIXME:
+// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
+// on `CStr` being layout-compatible with `[u8]`.
+// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`.
+// Anyway, `CStr` representation and layout are considered implementation detail, are
+// not documented and must not be relied upon.
+pub struct CStr {
+    // FIXME: this should not be represented with a DST slice but rather with
+    //        just a raw `c_char` along with some form of marker to make
+    //        this an unsized type. Essentially `sizeof(&CStr)` should be the
+    //        same as `sizeof(&c_char)` but `CStr` should be an unsized type.
+    inner: [c_char],
+}
+
+/// An error indicating that a nul byte was not in the expected position.
+///
+/// The slice used to create a [`CStr`] must have one and only one nul byte,
+/// positioned at the end.
+///
+/// This error is created by the [`CStr::from_bytes_with_nul`] method.
+/// See its documentation for more.
+///
+/// # Examples
+///
+/// ```
+/// use std::ffi::{CStr, FromBytesWithNulError};
+///
+/// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err();
+/// ```
+#[derive(Clone, PartialEq, Eq, Debug)]
+#[unstable(feature = "core_c_str", issue = "94079")]
+pub struct FromBytesWithNulError {
+    kind: FromBytesWithNulErrorKind,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug)]
+enum FromBytesWithNulErrorKind {
+    InteriorNul(usize),
+    NotNulTerminated,
+}
+
+impl FromBytesWithNulError {
+    fn interior_nul(pos: usize) -> FromBytesWithNulError {
+        FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) }
+    }
+    fn not_nul_terminated() -> FromBytesWithNulError {
+        FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated }
+    }
+
+    #[doc(hidden)]
+    #[unstable(feature = "cstr_internals", issue = "none")]
+    pub fn __description(&self) -> &str {
+        match self.kind {
+            FromBytesWithNulErrorKind::InteriorNul(..) => {
+                "data provided contains an interior nul byte"
+            }
+            FromBytesWithNulErrorKind::NotNulTerminated => "data provided is not nul terminated",
+        }
+    }
+}
+
+/// An error indicating that no nul byte was present.
+///
+/// A slice used to create a [`CStr`] must contain a nul byte somewhere
+/// within the slice.
+///
+/// This error is created by the [`CStr::from_bytes_until_nul`] method.
+///
+#[derive(Clone, PartialEq, Eq, Debug)]
+#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+pub struct FromBytesUntilNulError(());
+
+#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+impl fmt::Display for FromBytesUntilNulError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "data provided does not contain a nul")
+    }
+}
+
+#[stable(feature = "cstr_debug", since = "1.3.0")]
+impl fmt::Debug for CStr {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "\"")?;
+        for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) {
+            f.write_char(byte as char)?;
+        }
+        write!(f, "\"")
+    }
+}
+
+#[stable(feature = "cstr_default", since = "1.10.0")]
+impl Default for &CStr {
+    fn default() -> Self {
+        const SLICE: &[c_char] = &[0];
+        // SAFETY: `SLICE` is indeed pointing to a valid nul-terminated string.
+        unsafe { CStr::from_ptr(SLICE.as_ptr()) }
+    }
+}
+
+#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
+impl fmt::Display for FromBytesWithNulError {
+    #[allow(deprecated, deprecated_in_future)]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(self.__description())?;
+        if let FromBytesWithNulErrorKind::InteriorNul(pos) = self.kind {
+            write!(f, " at byte pos {pos}")?;
+        }
+        Ok(())
+    }
+}
+
+impl CStr {
+    /// Wraps a raw C string with a safe C string wrapper.
+    ///
+    /// This function will wrap the provided `ptr` with a `CStr` wrapper, which
+    /// allows inspection and interoperation of non-owned C strings. The total
+    /// size of the raw C string must be smaller than `isize::MAX` **bytes**
+    /// in memory due to calling the `slice::from_raw_parts` function.
+    /// This method is unsafe for a number of reasons:
+    ///
+    /// * There is no guarantee to the validity of `ptr`.
+    /// * The returned lifetime is not guaranteed to be the actual lifetime of
+    ///   `ptr`.
+    /// * There is no guarantee that the memory pointed to by `ptr` contains a
+    ///   valid nul terminator byte at the end of the string.
+    /// * It is not guaranteed that the memory pointed by `ptr` won't change
+    ///   before the `CStr` has been destroyed.
+    ///
+    /// > **Note**: This operation is intended to be a 0-cost cast but it is
+    /// > currently implemented with an up-front calculation of the length of
+    /// > the string. This is not guaranteed to always be the case.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore (extern-declaration)
+    /// # fn main() {
+    /// use std::ffi::CStr;
+    /// use std::os::raw::c_char;
+    ///
+    /// extern "C" {
+    ///     fn my_string() -> *const c_char;
+    /// }
+    ///
+    /// unsafe {
+    ///     let slice = CStr::from_ptr(my_string());
+    ///     println!("string returned: {}", slice.to_str().unwrap());
+    /// }
+    /// # }
+    /// ```
+    #[inline]
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
+        // SAFETY: The caller has provided a pointer that points to a valid C
+        // string with a NUL terminator of size less than `isize::MAX`, whose
+        // content remain valid and doesn't change for the lifetime of the
+        // returned `CStr`.
+        //
+        // Thus computing the length is fine (a NUL byte exists), the call to
+        // from_raw_parts is safe because we know the length is at most `isize::MAX`, meaning
+        // the call to `from_bytes_with_nul_unchecked` is correct.
+        //
+        // The cast from c_char to u8 is ok because a c_char is always one byte.
+        unsafe {
+            extern "C" {
+                /// Provided by libc or compiler_builtins.
+                fn strlen(s: *const c_char) -> usize;
+            }
+            let len = strlen(ptr);
+            let ptr = ptr as *const u8;
+            CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
+        }
+    }
+
+    /// Creates a C string wrapper from a byte slice.
+    ///
+    /// This method will create a `CStr` from any byte slice that contains at
+    /// least one nul byte. The caller does not need to know or specify where
+    /// the nul byte is located.
+    ///
+    /// If the first byte is a nul character, this method will return an
+    /// empty `CStr`. If multiple nul characters are present, the `CStr` will
+    /// end at the first one.
+    ///
+    /// If the slice only has a single nul byte at the end, this method is
+    /// equivalent to [`CStr::from_bytes_with_nul`].
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(cstr_from_bytes_until_nul)]
+    ///
+    /// use std::ffi::CStr;
+    ///
+    /// let mut buffer = [0u8; 16];
+    /// unsafe {
+    ///     // Here we might call an unsafe C function that writes a string
+    ///     // into the buffer.
+    ///     let buf_ptr = buffer.as_mut_ptr();
+    ///     buf_ptr.write_bytes(b'A', 8);
+    /// }
+    /// // Attempt to extract a C nul-terminated string from the buffer.
+    /// let c_str = CStr::from_bytes_until_nul(&buffer[..]).unwrap();
+    /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA");
+    /// ```
+    ///
+    #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+    pub fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> {
+        let nul_pos = memchr::memchr(0, bytes);
+        match nul_pos {
+            Some(nul_pos) => {
+                let subslice = &bytes[..nul_pos + 1];
+                // SAFETY: We know there is a nul byte at nul_pos, so this slice
+                // (ending at the nul byte) is a well-formed C string.
+                Ok(unsafe { CStr::from_bytes_with_nul_unchecked(subslice) })
+            }
+            None => Err(FromBytesUntilNulError(())),
+        }
+    }
+
+    /// Creates a C string wrapper from a byte slice.
+    ///
+    /// This function will cast the provided `bytes` to a `CStr`
+    /// wrapper after ensuring that the byte slice is nul-terminated
+    /// and does not contain any interior nul bytes.
+    ///
+    /// If the nul byte may not be at the end,
+    /// [`CStr::from_bytes_until_nul`] can be used instead.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CStr;
+    ///
+    /// let cstr = CStr::from_bytes_with_nul(b"hello\0");
+    /// assert!(cstr.is_ok());
+    /// ```
+    ///
+    /// Creating a `CStr` without a trailing nul terminator is an error:
+    ///
+    /// ```
+    /// use std::ffi::CStr;
+    ///
+    /// let cstr = CStr::from_bytes_with_nul(b"hello");
+    /// assert!(cstr.is_err());
+    /// ```
+    ///
+    /// Creating a `CStr` with an interior nul byte is an error:
+    ///
+    /// ```
+    /// use std::ffi::CStr;
+    ///
+    /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
+    /// assert!(cstr.is_err());
+    /// ```
+    #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
+    pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
+        let nul_pos = memchr::memchr(0, bytes);
+        match nul_pos {
+            Some(nul_pos) if nul_pos + 1 == bytes.len() => {
+                // SAFETY: We know there is only one nul byte, at the end
+                // of the byte slice.
+                Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
+            }
+            Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
+            None => Err(FromBytesWithNulError::not_nul_terminated()),
+        }
+    }
+
+    /// Unsafely creates a C string wrapper from a byte slice.
+    ///
+    /// This function will cast the provided `bytes` to a `CStr` wrapper without
+    /// performing any sanity checks. The provided slice **must** be nul-terminated
+    /// and not contain any interior nul bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::{CStr, CString};
+    ///
+    /// unsafe {
+    ///     let cstring = CString::new("hello").expect("CString::new failed");
+    ///     let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
+    ///     assert_eq!(cstr, &*cstring);
+    /// }
+    /// ```
+    #[inline]
+    #[must_use]
+    #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
+    #[rustc_const_stable(feature = "const_cstr_unchecked", since = "1.59.0")]
+    pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
+        // We're in a const fn, so this is the best we can do
+        debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0);
+        // SAFETY: Calling an inner function with the same prerequisites.
+        unsafe { Self::_from_bytes_with_nul_unchecked(bytes) }
+    }
+
+    #[inline]
+    const unsafe fn _from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
+        // SAFETY: Casting to CStr is safe because its internal representation
+        // is a [u8] too (safe only inside std).
+        // Dereferencing the obtained pointer is safe because it comes from a
+        // reference. Making a reference is then safe because its lifetime
+        // is bound by the lifetime of the given `bytes`.
+        unsafe { &*(bytes as *const [u8] as *const CStr) }
+    }
+
+    /// Returns the inner pointer to this C string.
+    ///
+    /// The returned pointer will be valid for as long as `self` is, and points
+    /// to a contiguous region of memory terminated with a 0 byte to represent
+    /// the end of the string.
+    ///
+    /// **WARNING**
+    ///
+    /// The returned pointer is read-only; writing to it (including passing it
+    /// to C code that writes to it) causes undefined behavior.
+    ///
+    /// It is your responsibility to make sure that the underlying memory is not
+    /// freed too early. For example, the following code will cause undefined
+    /// behavior when `ptr` is used inside the `unsafe` block:
+    ///
+    /// ```no_run
+    /// # #![allow(unused_must_use)] #![allow(temporary_cstring_as_ptr)]
+    /// use std::ffi::CString;
+    ///
+    /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr();
+    /// unsafe {
+    ///     // `ptr` is dangling
+    ///     *ptr;
+    /// }
+    /// ```
+    ///
+    /// This happens because the pointer returned by `as_ptr` does not carry any
+    /// lifetime information and the `CString` is deallocated immediately after
+    /// the `CString::new("Hello").expect("CString::new failed").as_ptr()`
+    /// expression is evaluated.
+    /// To fix the problem, bind the `CString` to a local variable:
+    ///
+    /// ```no_run
+    /// # #![allow(unused_must_use)]
+    /// use std::ffi::CString;
+    ///
+    /// let hello = CString::new("Hello").expect("CString::new failed");
+    /// let ptr = hello.as_ptr();
+    /// unsafe {
+    ///     // `ptr` is valid because `hello` is in scope
+    ///     *ptr;
+    /// }
+    /// ```
+    ///
+    /// This way, the lifetime of the `CString` in `hello` encompasses
+    /// the lifetime of `ptr` and the `unsafe` block.
+    #[inline]
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
+    pub const fn as_ptr(&self) -> *const c_char {
+        self.inner.as_ptr()
+    }
+
+    /// Converts this C string to a byte slice.
+    ///
+    /// The returned slice will **not** contain the trailing nul terminator that this C
+    /// string has.
+    ///
+    /// > **Note**: This method is currently implemented as a constant-time
+    /// > cast, but it is planned to alter its definition in the future to
+    /// > perform the length calculation whenever this method is called.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CStr;
+    ///
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_bytes(), b"foo");
+    /// ```
+    #[inline]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_bytes(&self) -> &[u8] {
+        let bytes = self.to_bytes_with_nul();
+        // SAFETY: to_bytes_with_nul returns slice with length at least 1
+        unsafe { bytes.get_unchecked(..bytes.len() - 1) }
+    }
+
+    /// Converts this C string to a byte slice containing the trailing 0 byte.
+    ///
+    /// This function is the equivalent of [`CStr::to_bytes`] except that it
+    /// will retain the trailing nul terminator instead of chopping it off.
+    ///
+    /// > **Note**: This method is currently implemented as a 0-cost cast, but
+    /// > it is planned to alter its definition in the future to perform the
+    /// > length calculation whenever this method is called.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CStr;
+    ///
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0");
+    /// ```
+    #[inline]
+    #[must_use = "this returns the result of the operation, \
+                  without modifying the original"]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_bytes_with_nul(&self) -> &[u8] {
+        // SAFETY: Transmuting a slice of `c_char`s to a slice of `u8`s
+        // is safe on all supported targets.
+        unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
+    }
+
+    /// Yields a <code>&[str]</code> slice if the `CStr` contains valid UTF-8.
+    ///
+    /// If the contents of the `CStr` are valid UTF-8 data, this
+    /// function will return the corresponding <code>&[str]</code> slice. Otherwise,
+    /// it will return an error with details of where UTF-8 validation failed.
+    ///
+    /// [str]: prim@str "str"
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CStr;
+    ///
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_str(), Ok("foo"));
+    /// ```
+    #[stable(feature = "cstr_to_str", since = "1.4.0")]
+    pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
+        // N.B., when `CStr` is changed to perform the length check in `.to_bytes()`
+        // instead of in `from_ptr()`, it may be worth considering if this should
+        // be rewritten to do the UTF-8 check inline with the length calculation
+        // instead of doing it afterwards.
+        str::from_utf8(self.to_bytes())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialEq for CStr {
+    fn eq(&self, other: &CStr) -> bool {
+        self.to_bytes().eq(other.to_bytes())
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Eq for CStr {}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialOrd for CStr {
+    fn partial_cmp(&self, other: &CStr) -> Option<Ordering> {
+        self.to_bytes().partial_cmp(&other.to_bytes())
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Ord for CStr {
+    fn cmp(&self, other: &CStr) -> Ordering {
+        self.to_bytes().cmp(&other.to_bytes())
+    }
+}
+
+#[stable(feature = "cstr_range_from", since = "1.47.0")]
+impl ops::Index<ops::RangeFrom<usize>> for CStr {
+    type Output = CStr;
+
+    fn index(&self, index: ops::RangeFrom<usize>) -> &CStr {
+        let bytes = self.to_bytes_with_nul();
+        // we need to manually check the starting index to account for the null
+        // byte, since otherwise we could get an empty string that doesn't end
+        // in a null.
+        if index.start < bytes.len() {
+            // SAFETY: Non-empty tail of a valid `CStr` is still a valid `CStr`.
+            unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) }
+        } else {
+            panic!(
+                "index out of bounds: the len is {} but the index is {}",
+                bytes.len(),
+                index.start
+            );
+        }
+    }
+}
+
+#[stable(feature = "cstring_asref", since = "1.7.0")]
+impl AsRef<CStr> for CStr {
+    #[inline]
+    fn as_ref(&self) -> &CStr {
+        self
+    }
+}
diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs
index e61ea9ce87f..6c49521c223 100644
--- a/library/core/src/ffi/mod.rs
+++ b/library/core/src/ffi/mod.rs
@@ -14,6 +14,11 @@ use crate::marker::PhantomData;
 use crate::num::*;
 use crate::ops::{Deref, DerefMut};
 
+#[unstable(feature = "core_c_str", issue = "94079")]
+pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError};
+
+mod c_str;
+
 macro_rules! type_alias_no_nz {
     {
       $Docfile:tt, $Alias:ident = $Real:ty;
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 53fbe4cbc42..69f06fb06ef 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -470,6 +470,10 @@ pub trait Iterator {
     /// it will first try to advance the first iterator at most one time and if it still yielded an item
     /// try to advance the second iterator at most one time.
     ///
+    /// To 'undo' the result of zipping up two iterators, see [`unzip`].
+    ///
+    /// [`unzip`]: Iterator::unzip
+    ///
     /// # Examples
     ///
     /// Basic usage:
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 6546a5244fd..dafd07b1617 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -20,7 +20,7 @@
 // FIXME: Fill me in with more detail when the interface settles
 //! This library is built on the assumption of a few existing symbols:
 //!
-//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
+//! * `memcpy`, `memcmp`, `memset`, `strlen` - These are core memory routines which are
 //!   often generated by LLVM. Additionally, this library can make explicit
 //!   calls to these functions. Their signatures are the same as found in C.
 //!   These functions are often provided by the system libc, but can also be
@@ -117,6 +117,7 @@
 #![feature(const_intrinsic_copy)]
 #![feature(const_intrinsic_forget)]
 #![feature(const_likely)]
+#![feature(const_maybe_uninit_uninit_array)]
 #![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_assume_init)]
 #![feature(const_num_from_num)]
@@ -167,7 +168,7 @@
 #![feature(const_precise_live_drops)]
 #![feature(const_refs_to_cell)]
 #![feature(decl_macro)]
-#![feature(derive_default_enum)]
+#![cfg_attr(bootstrap, feature(derive_default_enum))]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
 #![feature(doc_notable_trait)]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 58d682fc4c8..cac7f435573 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -350,13 +350,13 @@ impl<T> MaybeUninit<T> {
     /// let mut buf: [MaybeUninit<u8>; 32] = MaybeUninit::uninit_array();
     /// let data = read(&mut buf);
     /// ```
-    #[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
-    #[rustc_const_unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
+    #[unstable(feature = "maybe_uninit_uninit_array", issue = "96097")]
+    #[rustc_const_unstable(feature = "const_maybe_uninit_uninit_array", issue = "96097")]
     #[must_use]
     #[inline(always)]
-    pub const fn uninit_array<const LEN: usize>() -> [Self; LEN] {
+    pub const fn uninit_array<const N: usize>() -> [Self; N] {
         // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
-        unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
+        unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
     }
 
     /// Creates a new `MaybeUninit<T>` in an uninitialized state, with the memory being
@@ -942,19 +942,24 @@ impl<T> MaybeUninit<T> {
     ///
     /// assert_eq!(array, [0, 1, 2]);
     /// ```
-    #[unstable(feature = "maybe_uninit_array_assume_init", issue = "80908")]
+    #[unstable(feature = "maybe_uninit_array_assume_init", issue = "96097")]
+    #[rustc_const_unstable(feature = "const_maybe_uninit_array_assume_init", issue = "96097")]
     #[inline(always)]
     #[track_caller]
-    pub unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] {
+    pub const unsafe fn array_assume_init<const N: usize>(array: [Self; N]) -> [T; N] {
         // SAFETY:
         // * The caller guarantees that all elements of the array are initialized
         // * `MaybeUninit<T>` and T are guaranteed to have the same layout
         // * `MaybeUninit` does not drop, so there are no double-frees
         // And thus the conversion is safe
-        unsafe {
+        let ret = unsafe {
             intrinsics::assert_inhabited::<[T; N]>();
             (&array as *const _ as *const [T; N]).read()
-        }
+        };
+
+        // FIXME: required to avoid `~const Destruct` bound
+        super::forget(array);
+        ret
     }
 
     /// Assuming all the elements are initialized, get a slice to them.
diff --git a/library/core/src/prelude/mod.rs b/library/core/src/prelude/mod.rs
index ccd36a428e2..3cd3a3b780e 100644
--- a/library/core/src/prelude/mod.rs
+++ b/library/core/src/prelude/mod.rs
@@ -45,3 +45,13 @@ pub mod rust_2021 {
     #[doc(no_inline)]
     pub use crate::convert::{TryFrom, TryInto};
 }
+
+/// The 2024 edition of the core prelude.
+///
+/// See the [module-level documentation](self) for more.
+#[unstable(feature = "prelude_2024", issue = "none")]
+pub mod rust_2024 {
+    #[unstable(feature = "prelude_2024", issue = "none")]
+    #[doc(no_inline)]
+    pub use super::rust_2021::*;
+}
diff --git a/library/portable-simd/crates/core_simd/src/intrinsics.rs b/library/portable-simd/crates/core_simd/src/intrinsics.rs
index 426c4de6ab1..82508c6882d 100644
--- a/library/portable-simd/crates/core_simd/src/intrinsics.rs
+++ b/library/portable-simd/crates/core_simd/src/intrinsics.rs
@@ -61,6 +61,10 @@ extern "platform-intrinsic" {
     /// xor
     pub(crate) fn simd_xor<T>(x: T, y: T) -> T;
 
+    /// getelementptr (without inbounds)
+    #[cfg(not(bootstrap))]
+    pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T;
+
     /// fptoui/fptosi/uitofp/sitofp
     /// casting floats to integers is truncating, so it is safe to convert values like e.g. 1.5
     /// but the truncated value must fit in the target type or the result is poison.
diff --git a/library/portable-simd/crates/core_simd/src/vector/ptr.rs b/library/portable-simd/crates/core_simd/src/vector/ptr.rs
index 417d255c28d..68a9c67f795 100644
--- a/library/portable-simd/crates/core_simd/src/vector/ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/vector/ptr.rs
@@ -1,5 +1,8 @@
 //! Private implementation details of public gather/scatter APIs.
+#[cfg(not(bootstrap))]
+use crate::simd::intrinsics;
 use crate::simd::{LaneCount, Simd, SupportedLaneCount};
+#[cfg(bootstrap)]
 use core::mem;
 
 /// A vector of *const T.
@@ -21,12 +24,16 @@ where
     #[inline]
     #[must_use]
     pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
+        #[cfg(bootstrap)]
         // Safety: converting pointers to usize and vice-versa is safe
         // (even if using that pointer is not)
         unsafe {
             let x: Simd<usize, LANES> = mem::transmute_copy(&self);
             mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
         }
+        #[cfg(not(bootstrap))]
+        // Safety: this intrinsic doesn't have a precondition
+        unsafe { intrinsics::simd_arith_offset(self, addend) }
     }
 }
 
@@ -49,11 +56,15 @@ where
     #[inline]
     #[must_use]
     pub fn wrapping_add(self, addend: Simd<usize, LANES>) -> Self {
+        #[cfg(bootstrap)]
         // Safety: converting pointers to usize and vice-versa is safe
         // (even if using that pointer is not)
         unsafe {
             let x: Simd<usize, LANES> = mem::transmute_copy(&self);
             mem::transmute_copy(&{ x + (addend * Simd::splat(mem::size_of::<T>())) })
         }
+        #[cfg(not(bootstrap))]
+        // Safety: this intrinsic doesn't have a precondition
+        unsafe { intrinsics::simd_arith_offset(self, addend) }
     }
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index dd9b035e86d..f2d65832060 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
 libc = { version = "0.2.116", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.69" }
+compiler_builtins = { version = "0.1.71" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] }
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index 4fb94908c80..3f85c2095cb 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -26,6 +26,7 @@ use crate::borrow::Cow;
 use crate::cell;
 use crate::char;
 use crate::fmt::{self, Debug, Display, Write};
+use crate::io;
 use crate::mem::transmute;
 use crate::num;
 use crate::str;
@@ -612,6 +613,48 @@ impl Error for alloc::collections::TryReserveError {}
 #[unstable(feature = "duration_checked_float", issue = "83400")]
 impl Error for time::FromFloatSecsError {}
 
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for alloc::ffi::NulError {
+    #[allow(deprecated)]
+    fn description(&self) -> &str {
+        "nul byte found in data"
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<alloc::ffi::NulError> for io::Error {
+    /// Converts a [`alloc::ffi::NulError`] into a [`io::Error`].
+    fn from(_: alloc::ffi::NulError) -> io::Error {
+        io::const_io_error!(io::ErrorKind::InvalidInput, "data provided contains a nul byte")
+    }
+}
+
+#[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
+impl Error for core::ffi::FromBytesWithNulError {
+    #[allow(deprecated)]
+    fn description(&self) -> &str {
+        self.__description()
+    }
+}
+
+#[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
+impl Error for core::ffi::FromBytesUntilNulError {}
+
+#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
+impl Error for alloc::ffi::FromVecWithNulError {}
+
+#[stable(feature = "cstring_into", since = "1.7.0")]
+impl Error for alloc::ffi::IntoStringError {
+    #[allow(deprecated)]
+    fn description(&self) -> &str {
+        "C string contained non-utf8 bytes"
+    }
+
+    fn source(&self) -> Option<&(dyn Error + 'static)> {
+        Some(self.__source())
+    }
+}
+
 // Copied from `any.rs`.
 impl dyn Error + 'static {
     /// Returns `true` if the inner type is the same as `T`.
diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs
index 13e3dacc30d..0141a2bccdf 100644
--- a/library/std/src/ffi/mod.rs
+++ b/library/std/src/ffi/mod.rs
@@ -146,12 +146,24 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
-pub use self::c_str::FromBytesWithNulError;
+/// See [alloc::ffi::FromVecWithNulError].
 #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
-pub use self::c_str::FromVecWithNulError;
+pub type FromVecWithNulError = alloc::ffi::FromVecWithNulError;
+/// See [alloc::ffi::CString].
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type CString = alloc::ffi::CString;
+/// See [alloc::ffi::IntoStringError].
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type IntoStringError = alloc::ffi::IntoStringError;
+/// See [alloc::ffi::NulError].
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::c_str::{CStr, CString, IntoStringError, NulError};
+pub type NulError = alloc::ffi::NulError;
+/// See [core::ffi::CStr].
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type CStr = core::ffi::CStr;
+/// See [core::ffi::FromBytesWithNulError].
+#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
+pub type FromBytesWithNulError = core::ffi::FromBytesWithNulError;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::os_str::{OsStr, OsString};
@@ -176,5 +188,4 @@ pub use core::ffi::{c_ptrdiff_t, c_size_t, c_ssize_t};
 )]
 pub use core::ffi::{VaList, VaListImpl};
 
-mod c_str;
 mod os_str;
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 60e7c2af8e4..da7753216d0 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -260,7 +260,10 @@
 #![feature(atomic_mut_ptr)]
 #![feature(char_error_internals)]
 #![feature(char_internals)]
+#![feature(core_c_str)]
 #![feature(core_intrinsics)]
+#![feature(cstr_from_bytes_until_nul)]
+#![feature(cstr_internals)]
 #![feature(duration_checked_float)]
 #![feature(duration_constants)]
 #![feature(exact_size_is_empty)]
@@ -276,6 +279,7 @@
 #![feature(panic_info_message)]
 #![feature(panic_internals)]
 #![feature(portable_simd)]
+#![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
 #![feature(raw_os_nonzero)]
 #![feature(slice_internals)]
@@ -286,6 +290,7 @@
 //
 // Library features (alloc):
 #![feature(alloc_layout_extra)]
+#![feature(alloc_c_string)]
 #![feature(allocator_api)]
 #![feature(get_mut_unchecked)]
 #![feature(map_try_insert)]
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index d4bf6aeefee..c314bbbb68e 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -132,3 +132,17 @@ pub mod rust_2021 {
     #[doc(no_inline)]
     pub use core::prelude::rust_2021::*;
 }
+
+/// The 2024 version of the prelude of The Rust Standard Library.
+///
+/// See the [module-level documentation](self) for more.
+#[unstable(feature = "prelude_2024", issue = "none")]
+pub mod rust_2024 {
+    #[unstable(feature = "prelude_2024", issue = "none")]
+    #[doc(no_inline)]
+    pub use super::v1::*;
+
+    #[unstable(feature = "prelude_2024", issue = "none")]
+    #[doc(no_inline)]
+    pub use core::prelude::rust_2024::*;
+}
diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs
index 0226c4d7a25..f7533696df4 100644
--- a/library/std/src/prelude/v1.rs
+++ b/library/std/src/prelude/v1.rs
@@ -95,3 +95,7 @@ pub use crate::string::{String, ToString};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
 pub use crate::vec::Vec;
+
+#[cfg(bootstrap)]
+#[unstable(feature = "cstr_internals", issue = "none")]
+pub use alloc::ffi::CStrExt;
diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs
index 08eca423802..60b7a973cc2 100644
--- a/library/std/src/sys/hermit/mod.rs
+++ b/library/std/src/sys/hermit/mod.rs
@@ -71,16 +71,6 @@ pub fn unsupported_err() -> crate::io::Error {
     )
 }
 
-pub unsafe fn strlen(start: *const c_char) -> usize {
-    let mut str = start;
-
-    while *str != 0 {
-        str = str.offset(1);
-    }
-
-    (str as usize) - (start as usize)
-}
-
 #[no_mangle]
 pub extern "C" fn floor(x: f64) -> f64 {
     unsafe { intrinsics::floorf64(x) }
diff --git a/library/std/src/sys/sgx/mod.rs b/library/std/src/sys/sgx/mod.rs
index 1333edb9881..696400670e0 100644
--- a/library/std/src/sys/sgx/mod.rs
+++ b/library/std/src/sys/sgx/mod.rs
@@ -5,7 +5,6 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 
 use crate::io::ErrorKind;
-use crate::os::raw::c_char;
 use crate::sync::atomic::{AtomicBool, Ordering};
 
 pub mod abi;
@@ -130,15 +129,6 @@ pub fn decode_error_kind(code: i32) -> ErrorKind {
     }
 }
 
-pub unsafe fn strlen(mut s: *const c_char) -> usize {
-    let mut n = 0;
-    while unsafe { *s } != 0 {
-        n += 1;
-        s = unsafe { s.offset(1) };
-    }
-    return n;
-}
-
 pub fn abort_internal() -> ! {
     abi::usercalls::exit(true)
 }
diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs
index 492b1a55475..5ffa381f2e5 100644
--- a/library/std/src/sys/solid/mod.rs
+++ b/library/std/src/sys/solid/mod.rs
@@ -99,5 +99,3 @@ pub fn hashmap_random_keys() -> (u64, u64) {
         (x1, x2)
     }
 }
-
-pub use libc::strlen;
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs
index b45d1c0149c..62760373a6a 100644
--- a/library/std/src/sys/unix/futex.rs
+++ b/library/std/src/sys/unix/futex.rs
@@ -4,7 +4,7 @@
     all(target_os = "emscripten", target_feature = "atomics")
 ))]
 
-use crate::sync::atomic::AtomicI32;
+use crate::sync::atomic::AtomicU32;
 use crate::time::Duration;
 
 /// Wait for a futex_wake operation to wake us.
@@ -13,7 +13,7 @@ use crate::time::Duration;
 ///
 /// Returns false on timeout, and true in all other cases.
 #[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -> bool {
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
     use super::time::Timespec;
     use crate::ptr::null;
     use crate::sync::atomic::Ordering::Relaxed;
@@ -35,7 +35,7 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -
         let r = unsafe {
             libc::syscall(
                 libc::SYS_futex,
-                futex as *const AtomicI32,
+                futex as *const AtomicU32,
                 libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG,
                 expected,
                 timespec.as_ref().map_or(null(), |t| &t.t as *const libc::timespec),
@@ -53,10 +53,10 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -
 }
 
 #[cfg(target_os = "emscripten")]
-pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) {
     extern "C" {
         fn emscripten_futex_wait(
-            addr: *const AtomicI32,
+            addr: *const AtomicU32,
             val: libc::c_uint,
             max_wait_ms: libc::c_double,
         ) -> libc::c_int;
@@ -64,10 +64,8 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
 
     unsafe {
         emscripten_futex_wait(
-            futex as *const AtomicI32,
-            // `val` is declared unsigned to match the Emscripten headers, but since it's used as
-            // an opaque value, we can ignore the meaning of signed vs. unsigned and cast here.
-            expected as libc::c_uint,
+            futex,
+            expected,
             timeout.map_or(crate::f64::INFINITY, |d| d.as_secs_f64() * 1000.0),
         );
     }
@@ -78,11 +76,11 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
 /// Returns true if this actually woke up such a thread,
 /// or false if no thread was waiting on this futex.
 #[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn futex_wake(futex: &AtomicI32) -> bool {
+pub fn futex_wake(futex: &AtomicU32) -> bool {
     unsafe {
         libc::syscall(
             libc::SYS_futex,
-            futex as *const AtomicI32,
+            futex as *const AtomicU32,
             libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
             1,
         ) > 0
@@ -91,11 +89,11 @@ pub fn futex_wake(futex: &AtomicI32) -> bool {
 
 /// Wake up all threads that are waiting on futex_wait on this futex.
 #[cfg(any(target_os = "linux", target_os = "android"))]
-pub fn futex_wake_all(futex: &AtomicI32) {
+pub fn futex_wake_all(futex: &AtomicU32) {
     unsafe {
         libc::syscall(
             libc::SYS_futex,
-            futex as *const AtomicI32,
+            futex as *const AtomicU32,
             libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
             i32::MAX,
         );
@@ -103,10 +101,10 @@ pub fn futex_wake_all(futex: &AtomicI32) {
 }
 
 #[cfg(target_os = "emscripten")]
-pub fn futex_wake(futex: &AtomicI32) -> bool {
+pub fn futex_wake(futex: &AtomicU32) -> bool {
     extern "C" {
-        fn emscripten_futex_wake(addr: *const AtomicI32, count: libc::c_int) -> libc::c_int;
+        fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;
     }
 
-    unsafe { emscripten_futex_wake(futex as *const AtomicI32, 1) > 0 }
+    unsafe { emscripten_futex_wake(futex, 1) > 0 }
 }
diff --git a/library/std/src/sys/unix/locks/futex.rs b/library/std/src/sys/unix/locks/futex.rs
index d97777e4da2..b166e7c453c 100644
--- a/library/std/src/sys/unix/locks/futex.rs
+++ b/library/std/src/sys/unix/locks/futex.rs
@@ -1,6 +1,6 @@
 use crate::cell::UnsafeCell;
 use crate::sync::atomic::{
-    AtomicI32, AtomicUsize,
+    AtomicU32, AtomicUsize,
     Ordering::{Acquire, Relaxed, Release},
 };
 use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all};
@@ -13,13 +13,13 @@ pub struct Mutex {
     /// 0: unlocked
     /// 1: locked, no other threads waiting
     /// 2: locked, and other threads waiting (contended)
-    futex: AtomicI32,
+    futex: AtomicU32,
 }
 
 impl Mutex {
     #[inline]
     pub const fn new() -> Self {
-        Self { futex: AtomicI32::new(0) }
+        Self { futex: AtomicU32::new(0) }
     }
 
     #[inline]
@@ -71,7 +71,7 @@ impl Mutex {
         }
     }
 
-    fn spin(&self) -> i32 {
+    fn spin(&self) -> u32 {
         let mut spin = 100;
         loop {
             // We only use `load` (and not `swap` or `compare_exchange`)
@@ -110,13 +110,13 @@ pub struct Condvar {
     // The value of this atomic is simply incremented on every notification.
     // This is used by `.wait()` to not miss any notifications after
     // unlocking the mutex and before waiting for notifications.
-    futex: AtomicI32,
+    futex: AtomicU32,
 }
 
 impl Condvar {
     #[inline]
     pub const fn new() -> Self {
-        Self { futex: AtomicI32::new(0) }
+        Self { futex: AtomicU32::new(0) }
     }
 
     #[inline]
diff --git a/library/std/src/sys/unix/locks/futex_rwlock.rs b/library/std/src/sys/unix/locks/futex_rwlock.rs
index aa16da97e4c..e42edb25858 100644
--- a/library/std/src/sys/unix/locks/futex_rwlock.rs
+++ b/library/std/src/sys/unix/locks/futex_rwlock.rs
@@ -1,5 +1,5 @@
 use crate::sync::atomic::{
-    AtomicI32,
+    AtomicU32,
     Ordering::{Acquire, Relaxed, Release},
 };
 use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all};
@@ -14,36 +14,36 @@ pub struct RwLock {
     //   0x3FFF_FFFF: Write locked
     // Bit 30: Readers are waiting on this futex.
     // Bit 31: Writers are waiting on the writer_notify futex.
-    state: AtomicI32,
+    state: AtomicU32,
     // The 'condition variable' to notify writers through.
     // Incremented on every signal.
-    writer_notify: AtomicI32,
+    writer_notify: AtomicU32,
 }
 
-const READ_LOCKED: i32 = 1;
-const MASK: i32 = (1 << 30) - 1;
-const WRITE_LOCKED: i32 = MASK;
-const MAX_READERS: i32 = MASK - 1;
-const READERS_WAITING: i32 = 1 << 30;
-const WRITERS_WAITING: i32 = 1 << 31;
+const READ_LOCKED: u32 = 1;
+const MASK: u32 = (1 << 30) - 1;
+const WRITE_LOCKED: u32 = MASK;
+const MAX_READERS: u32 = MASK - 1;
+const READERS_WAITING: u32 = 1 << 30;
+const WRITERS_WAITING: u32 = 1 << 31;
 
-fn is_unlocked(state: i32) -> bool {
+fn is_unlocked(state: u32) -> bool {
     state & MASK == 0
 }
 
-fn is_write_locked(state: i32) -> bool {
+fn is_write_locked(state: u32) -> bool {
     state & MASK == WRITE_LOCKED
 }
 
-fn has_readers_waiting(state: i32) -> bool {
+fn has_readers_waiting(state: u32) -> bool {
     state & READERS_WAITING != 0
 }
 
-fn has_writers_waiting(state: i32) -> bool {
+fn has_writers_waiting(state: u32) -> bool {
     state & WRITERS_WAITING != 0
 }
 
-fn is_read_lockable(state: i32) -> bool {
+fn is_read_lockable(state: u32) -> bool {
     // This also returns false if the counter could overflow if we tried to read lock it.
     //
     // We don't allow read-locking if there's readers waiting, even if the lock is unlocked
@@ -53,14 +53,14 @@ fn is_read_lockable(state: i32) -> bool {
     state & MASK < MAX_READERS && !has_readers_waiting(state) && !has_writers_waiting(state)
 }
 
-fn has_reached_max_readers(state: i32) -> bool {
+fn has_reached_max_readers(state: u32) -> bool {
     state & MASK == MAX_READERS
 }
 
 impl RwLock {
     #[inline]
     pub const fn new() -> Self {
-        Self { state: AtomicI32::new(0), writer_notify: AtomicI32::new(0) }
+        Self { state: AtomicU32::new(0), writer_notify: AtomicU32::new(0) }
     }
 
     #[inline]
@@ -227,7 +227,7 @@ impl RwLock {
     /// If both are waiting, this will wake up only one writer, but will fall
     /// back to waking up readers if there was no writer to wake up.
     #[cold]
-    fn wake_writer_or_readers(&self, mut state: i32) {
+    fn wake_writer_or_readers(&self, mut state: u32) {
         assert!(is_unlocked(state));
 
         // The readers waiting bit might be turned on at any point now,
@@ -287,7 +287,7 @@ impl RwLock {
     }
 
     /// Spin for a while, but stop directly at the given condition.
-    fn spin_until(&self, f: impl Fn(i32) -> bool) -> i32 {
+    fn spin_until(&self, f: impl Fn(u32) -> bool) -> u32 {
         let mut spin = 100; // Chosen by fair dice roll.
         loop {
             let state = self.state.load(Relaxed);
@@ -299,12 +299,12 @@ impl RwLock {
         }
     }
 
-    fn spin_write(&self) -> i32 {
+    fn spin_write(&self) -> u32 {
         // Stop spinning when it's unlocked or when there's waiting writers, to keep things somewhat fair.
         self.spin_until(|state| is_unlocked(state) || has_writers_waiting(state))
     }
 
-    fn spin_read(&self) -> i32 {
+    fn spin_read(&self) -> u32 {
         // Stop spinning when it's unlocked or read locked, or when there's waiting threads.
         self.spin_until(|state| {
             !is_write_locked(state) || has_readers_waiting(state) || has_writers_waiting(state)
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index 3ad03a88681..aedeb02e656 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -3,7 +3,6 @@
 use crate::io::ErrorKind;
 
 pub use self::rand::hashmap_random_keys;
-pub use libc::strlen;
 
 #[cfg(not(target_os = "espidf"))]
 #[macro_use]
diff --git a/library/std/src/sys/unsupported/common.rs b/library/std/src/sys/unsupported/common.rs
index 5274f53a7db..4c9ade4a8c7 100644
--- a/library/std/src/sys/unsupported/common.rs
+++ b/library/std/src/sys/unsupported/common.rs
@@ -4,10 +4,6 @@ pub mod memchr {
     pub use core::slice::memchr::{memchr, memrchr};
 }
 
-// This is not necessarily correct. May want to consider making it part of the
-// spec definition?
-use crate::os::raw::c_char;
-
 // SAFETY: must be called only once during runtime initialization.
 // NOTE: this is not guaranteed to run, for example when Rust code is called externally.
 pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
@@ -38,15 +34,3 @@ pub fn abort_internal() -> ! {
 pub fn hashmap_random_keys() -> (u64, u64) {
     (1, 2)
 }
-
-pub unsafe fn strlen(mut s: *const c_char) -> usize {
-    // SAFETY: The caller must guarantee `s` points to a valid 0-terminated string.
-    unsafe {
-        let mut n = 0;
-        while *s != 0 {
-            n += 1;
-            s = s.offset(1);
-        }
-        n
-    }
-}
diff --git a/library/std/src/sys/wasm/atomics/futex.rs b/library/std/src/sys/wasm/atomics/futex.rs
index 3d8bf42f725..bbe9bd6951a 100644
--- a/library/std/src/sys/wasm/atomics/futex.rs
+++ b/library/std/src/sys/wasm/atomics/futex.rs
@@ -1,17 +1,21 @@
 use crate::arch::wasm32;
 use crate::convert::TryInto;
-use crate::sync::atomic::AtomicI32;
+use crate::sync::atomic::AtomicU32;
 use crate::time::Duration;
 
-pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) {
     let timeout = timeout.and_then(|t| t.as_nanos().try_into().ok()).unwrap_or(-1);
     unsafe {
-        wasm32::memory_atomic_wait32(futex as *const AtomicI32 as *mut i32, expected, timeout);
+        wasm32::memory_atomic_wait32(
+            futex as *const AtomicU32 as *mut i32,
+            expected as i32,
+            timeout,
+        );
     }
 }
 
-pub fn futex_wake(futex: &AtomicI32) {
+pub fn futex_wake(futex: &AtomicU32) {
     unsafe {
-        wasm32::memory_atomic_notify(futex as *const AtomicI32 as *mut i32, 1);
+        wasm32::memory_atomic_notify(futex as *const AtomicU32 as *mut i32, 1);
     }
 }
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs
index 47917e57b19..31c7208bbf1 100644
--- a/library/std/src/sys/windows/mod.rs
+++ b/library/std/src/sys/windows/mod.rs
@@ -7,7 +7,6 @@ use crate::path::PathBuf;
 use crate::time::Duration;
 
 pub use self::rand::hashmap_random_keys;
-pub use libc::strlen;
 
 #[macro_use]
 pub mod compat;
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index 09d1dd55989..013c776c476 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -165,6 +165,46 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
     }
 }
 
+/// Takes an asynchronous source pipe and returns a synchronous pipe suitable
+/// for sending to a child process.
+///
+/// This is achieved by creating a new set of pipes and spawning a thread that
+/// relays messages between the source and the synchronous pipe.
+pub fn spawn_pipe_relay(
+    source: &AnonPipe,
+    ours_readable: bool,
+    their_handle_inheritable: bool,
+) -> io::Result<AnonPipe> {
+    // We need this handle to live for the lifetime of the thread spawned below.
+    let source = source.duplicate()?;
+
+    // create a new pair of anon pipes.
+    let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?;
+
+    // Spawn a thread that passes messages from one pipe to the other.
+    // Any errors will simply cause the thread to exit.
+    let (reader, writer) = if ours_readable { (ours, source) } else { (source, ours) };
+    crate::thread::spawn(move || {
+        let mut buf = [0_u8; 4096];
+        'reader: while let Ok(len) = reader.read(&mut buf) {
+            if len == 0 {
+                break;
+            }
+            let mut start = 0;
+            while let Ok(written) = writer.write(&buf[start..len]) {
+                start += written;
+                if start == len {
+                    continue 'reader;
+                }
+            }
+            break;
+        }
+    });
+
+    // Return the pipe that should be sent to the child process.
+    Ok(theirs)
+}
+
 fn random_number() -> usize {
     static N: AtomicUsize = AtomicUsize::new(0);
     loop {
@@ -192,6 +232,9 @@ impl AnonPipe {
     pub fn into_handle(self) -> Handle {
         self.inner
     }
+    fn duplicate(&self) -> io::Result<Self> {
+        self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| AnonPipe { inner })
+    }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
         let result = unsafe {
diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs
index a13585a0222..a0c0f5dc3ec 100644
--- a/library/std/src/sys/windows/process.rs
+++ b/library/std/src/sys/windows/process.rs
@@ -172,6 +172,7 @@ pub enum Stdio {
     Inherit,
     Null,
     MakePipe,
+    Pipe(AnonPipe),
     Handle(Handle),
 }
 
@@ -528,6 +529,11 @@ impl Stdio {
                 Ok(pipes.theirs.into_handle())
             }
 
+            Stdio::Pipe(ref source) => {
+                let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
+                pipe::spawn_pipe_relay(source, ours_readable, true).map(AnonPipe::into_handle)
+            }
+
             Stdio::Handle(ref handle) => handle.duplicate(0, true, c::DUPLICATE_SAME_ACCESS),
 
             // Open up a reference to NUL with appropriate read/write
@@ -552,7 +558,7 @@ impl Stdio {
 
 impl From<AnonPipe> for Stdio {
     fn from(pipe: AnonPipe) -> Stdio {
-        Stdio::Handle(pipe.into_handle())
+        Stdio::Pipe(pipe)
     }
 }
 
diff --git a/library/std/src/sys_common/thread_parker/futex.rs b/library/std/src/sys_common/thread_parker/futex.rs
index 0132743b244..fbf6231ff4a 100644
--- a/library/std/src/sys_common/thread_parker/futex.rs
+++ b/library/std/src/sys_common/thread_parker/futex.rs
@@ -1,14 +1,14 @@
-use crate::sync::atomic::AtomicI32;
+use crate::sync::atomic::AtomicU32;
 use crate::sync::atomic::Ordering::{Acquire, Release};
 use crate::sys::futex::{futex_wait, futex_wake};
 use crate::time::Duration;
 
-const PARKED: i32 = -1;
-const EMPTY: i32 = 0;
-const NOTIFIED: i32 = 1;
+const PARKED: u32 = u32::MAX;
+const EMPTY: u32 = 0;
+const NOTIFIED: u32 = 1;
 
 pub struct Parker {
-    state: AtomicI32,
+    state: AtomicU32,
 }
 
 // Notes about memory ordering:
@@ -34,7 +34,7 @@ pub struct Parker {
 impl Parker {
     #[inline]
     pub const fn new() -> Self {
-        Parker { state: AtomicI32::new(EMPTY) }
+        Parker { state: AtomicU32::new(EMPTY) }
     }
 
     // Assumes this is only called by the thread that owns the Parker,
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 077a86af50b..a2802f76008 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -441,7 +441,6 @@ impl Step for Std {
         t!(fs::create_dir_all(&out));
         let compiler = builder.compiler(stage, builder.config.build);
 
-        builder.ensure(compile::Std { compiler, target });
         let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc");
 
         t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css")));
@@ -548,7 +547,6 @@ impl Step for Rustc {
     fn run(self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
-        builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
 
         let paths = builder
             .paths
@@ -563,9 +561,12 @@ impl Step for Rustc {
         let out = builder.compiler_doc_out(target);
         t!(fs::create_dir_all(&out));
 
-        // Build rustc.
+        // Build the standard library, so that proc-macros can use it.
+        // (Normally, only the metadata would be necessary, but proc-macros are special since they run at compile-time.)
         let compiler = builder.compiler(stage, builder.config.build);
-        builder.ensure(compile::Rustc { compiler, target });
+        builder.ensure(compile::Std { compiler, target: builder.config.build });
+
+        builder.info(&format!("Documenting stage{} compiler ({})", stage, target));
 
         // This uses a shared directory so that librustdoc documentation gets
         // correctly built and merged with the rustc documentation. This is
@@ -642,7 +643,6 @@ macro_rules! tool_doc {
     ($tool: ident, $should_run: literal, $path: literal, [$($krate: literal),+ $(,)?] $(,)?) => {
         #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
         pub struct $tool {
-            stage: u32,
             target: TargetSelection,
         }
 
@@ -657,7 +657,7 @@ macro_rules! tool_doc {
             }
 
             fn make_run(run: RunConfig<'_>) {
-                run.builder.ensure($tool { stage: run.builder.top_stage, target: run.target });
+                run.builder.ensure($tool { target: run.target });
             }
 
             /// Generates compiler documentation.
@@ -667,8 +667,21 @@ macro_rules! tool_doc {
             /// we do not merge it with the other documentation from std, test and
             /// proc_macros. This is largely just a wrapper around `cargo doc`.
             fn run(self, builder: &Builder<'_>) {
-                let stage = self.stage;
+                let stage = builder.top_stage;
                 let target = self.target;
+
+                // This is the intended out directory for compiler documentation.
+                let out = builder.compiler_doc_out(target);
+                t!(fs::create_dir_all(&out));
+
+                // Build rustc docs so that we generate relative links.
+                builder.ensure(Rustc { stage, target });
+                // Rustdoc needs the rustc sysroot available to build.
+                // FIXME: is there a way to only ensure `check::Rustc` here? Last time I tried it failed
+                // with strange errors, but only on a full bors test ...
+                let compiler = builder.compiler(stage, builder.config.build);
+                builder.ensure(compile::Rustc { compiler, target });
+
                 builder.info(
                     &format!(
                         "Documenting stage{} {} ({})",
@@ -678,15 +691,6 @@ macro_rules! tool_doc {
                     ),
                 );
 
-                // This is the intended out directory for compiler documentation.
-                let out = builder.compiler_doc_out(target);
-                t!(fs::create_dir_all(&out));
-
-                let compiler = builder.compiler(stage, builder.config.build);
-
-                // Build rustc docs so that we generate relative links.
-                builder.ensure(Rustc { stage, target });
-
                 // Symlink compiler docs to the output directory of rustdoc documentation.
                 let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
                 t!(fs::create_dir_all(&out_dir));
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 5622422d50f..173ee170c9f 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -99,7 +99,7 @@ x--expand-yaml-anchors--remove:
         run: git config --global core.autocrlf false
 
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
 
@@ -703,7 +703,7 @@ jobs:
     if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'rust-lang-ci/rust'
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
         with:
           fetch-depth: 2
 
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 2cf26603273..952d8ef48fe 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -15,12 +15,15 @@
 - [Platform Support](platform-support.md)
     - [Template for target-specific documentation](platform-support/TEMPLATE.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
+    - [aarch64-unknown-none-hermitkernel](platform-support/aarch64-unknown-none-hermitkernel.md)
     - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
     - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
+    - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
+    - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
     - [*-unknown-openbsd](platform-support/openbsd.md)
-    - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
     - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md)
+    - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
 - [Target Tier Policy](target-tier-policy.md)
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index b3c4a52c414..12ac575210a 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -248,9 +248,9 @@ target | std | host | notes
 `i686-uwp-windows-gnu` | ? |  |
 `i686-uwp-windows-msvc` | ? |  |
 `i686-wrs-vxworks` | ? |  |
-`m68k-unknown-linux-gnu` | ? |  | Motorola 680x0 Linux
+[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
-`mips64-openwrt-linux-musl` | ? |  | MIPS64 for OpenWrt Linux MUSL
+[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? |  | MIPS64 for OpenWrt Linux MUSL
 `mipsel-sony-psp` | * |  | MIPS (LE) Sony PlayStation Portable (PSP)
 `mipsel-unknown-linux-uclibc` | ✓ |  | MIPS (LE) Linux with uClibc
 `mipsel-unknown-none` | * |  | Bare MIPS (LE) softfloat
diff --git a/src/doc/rustc/src/tests/index.md b/src/doc/rustc/src/tests/index.md
index 0e0eb85db74..32baed9c944 100644
--- a/src/doc/rustc/src/tests/index.md
+++ b/src/doc/rustc/src/tests/index.md
@@ -15,7 +15,8 @@ fn it_works() {
 ```
 
 Tests "pass" if they return without an error. They "fail" if they [panic], or
-return a [`Result`] with an error.
+return a type such as [`Result`] that implements the [`Termination`] trait
+with a non-zero value.
 
 By passing the [`--test` option] to `rustc`, the compiler will build the crate
 in a special mode to construct an executable that will run the tests in the
@@ -304,6 +305,7 @@ Experimental support for using custom test harnesses is available on the
 [`libtest`]: ../../test/index.html
 [`main` function]: ../../reference/crates-and-source-files.html#main-functions
 [`Result`]: ../../std/result/index.html
+[`Termination`]: ../../std/process/trait.Termination.html
 [`test` cfg option]: ../../reference/conditional-compilation.html#test
 [attribute-ignore]: ../../reference/attributes/testing.html#the-ignore-attribute
 [attribute-should_panic]: ../../reference/attributes/testing.html#the-should_panic-attribute
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 731e18b1eec..06c63ec97d7 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -119,11 +119,14 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
     fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
         // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
         // file, we want to link to it. Otherwise no need to create a link.
-        if !span.overlaps(m.inner) {
+        if !span.overlaps(m.spans.inner_span) {
             // Now that we confirmed it's a file import, we want to get the span for the module
             // name only and not all the "mod foo;".
             if let Some(Node::Item(item)) = self.tcx.hir().find(id) {
-                self.matches.insert(item.ident.span, LinkFromSrc::Local(clean::Span::new(m.inner)));
+                self.matches.insert(
+                    item.ident.span,
+                    LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
+                );
             }
         }
         intravisit::walk_mod(self, m, id);
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 00e10c6d5a7..a620ffa9878 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -215,7 +215,7 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> {
                     // We don't try to detect stuff `<like, this>` because that's not valid HTML,
                     // and we don't try to detect stuff `<like this>` because that's not valid Rust.
                     if let Some(Some(generics_start)) = (is_open_tag
-                        && dox[..range.end].ends_with(">"))
+                        && dox[..range.end].ends_with('>'))
                     .then(|| extract_path_backwards(&dox, range.start))
                     {
                         let generics_sp = match super::source_span_for_markdown_range(
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index e793ee75fd2..75276d18fe5 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -154,7 +154,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         m: &'tcx hir::Mod<'tcx>,
         name: Symbol,
     ) -> Module<'tcx> {
-        let mut om = Module::new(name, id, m.inner);
+        let mut om = Module::new(name, id, m.spans.inner_span);
         let def_id = self.cx.tcx.hir().local_def_id(id).to_def_id();
         // Keep track of if there were any private modules in the path.
         let orig_inside_public_path = self.inside_public_path;
diff --git a/src/test/assembly/asm/global_asm.rs b/src/test/assembly/asm/global_asm.rs
index 0358bc6d27c..b76ce7ac387 100644
--- a/src/test/assembly/asm/global_asm.rs
+++ b/src/test/assembly/asm/global_asm.rs
@@ -1,15 +1,26 @@
 // only-x86_64
+// only-linux
 // assembly-output: emit-asm
 // compile-flags: -C llvm-args=--x86-asm-syntax=intel
 
-#![feature(asm_const)]
+#![feature(asm_const, asm_sym)]
 #![crate_type = "rlib"]
 
 use std::arch::global_asm;
 
+#[no_mangle]
+fn my_func() {}
+
+#[no_mangle]
+static MY_STATIC: i32 = 0;
+
 // CHECK: mov eax, eax
 global_asm!("mov eax, eax");
 // CHECK: mov ebx, 5
 global_asm!("mov ebx, {}", const 5);
 // CHECK: mov ecx, 5
 global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
+// CHECK: call my_func
+global_asm!("call {}", sym my_func);
+// CHECK: lea rax, [rip + MY_STATIC]
+global_asm!("lea rax, [rip + {}]", sym MY_STATIC);
diff --git a/src/test/codegen/simd_arith_offset.rs b/src/test/codegen/simd_arith_offset.rs
new file mode 100644
index 00000000000..a858270d4e7
--- /dev/null
+++ b/src/test/codegen/simd_arith_offset.rs
@@ -0,0 +1,26 @@
+// compile-flags: -C no-prepopulate-passes
+// only-64bit (because the LLVM type of i64 for usize shows up)
+//
+
+#![crate_type = "lib"]
+#![feature(repr_simd, platform_intrinsics)]
+
+extern "platform-intrinsic" {
+    pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T;
+}
+
+/// A vector of *const T.
+#[derive(Debug, Copy, Clone)]
+#[repr(simd)]
+pub struct SimdConstPtr<T, const LANES: usize>([*const T; LANES]);
+
+#[derive(Debug, Copy, Clone)]
+#[repr(simd)]
+pub struct Simd<T, const LANES: usize>([T; LANES]);
+
+// CHECK-LABEL: smoke
+#[no_mangle]
+pub fn smoke(ptrs: SimdConstPtr<u8, 8>, offsets: Simd<usize, 8>) -> SimdConstPtr<u8, 8> {
+    // CHECK: getelementptr i8, <8 x i8*> %_3, <8 x i64> %_4
+    unsafe { simd_arith_offset(ptrs, offsets) }
+}
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
index d8ceace7fff..4cda243ffb5 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile
@@ -2,10 +2,25 @@ include ../tools.mk
 
 # ignore-stage1
 
+# This test both exists as a check that -Zcodegen-backend is capable of loading external codegen
+# backends and that this external codegen backend is only included in the dep info if
+# -Zbinary-dep-depinfo is used.
+
 all:
 	/bin/echo || exit 0 # This test requires /bin/echo to exist
 	$(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \
 		-o $(TMPDIR)/the_backend.dylib
+
+	$(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
+		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \
+		--emit link,dep-info
+	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib
+	# don't declare a dependency on the codegen backend if -Zbinary-dep-depinfo isn't used.
+	grep -v "the_backend.dylib" $(TMPDIR)/some_crate.d
+	
 	$(RUSTC) some_crate.rs --crate-name some_crate --crate-type lib -o $(TMPDIR)/some_crate \
-		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options
-	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/some_crate
+		-Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options \
+		--emit link,dep-info -Zbinary-dep-depinfo
+	grep -x "This has been \"compiled\" successfully." $(TMPDIR)/libsome_crate.rlib
+	# but declare a dependency on the codegen backend if -Zbinary-dep-depinfo it used.
+	grep "the_backend.dylib" $(TMPDIR)/some_crate.d
diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs
new file mode 100644
index 00000000000..c71e5bee12e
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.rs
@@ -0,0 +1,6 @@
+// Regression test for issue #95879.
+
+use unresolved_crate::module::Name; //~ ERROR failed to resolve
+
+/// [Name]
+pub struct S;
diff --git a/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
new file mode 100644
index 00000000000..b60ab6050d7
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-doc/unresolved-import-recovery.stderr
@@ -0,0 +1,11 @@
+error[E0433]: failed to resolve: maybe a missing crate `unresolved_crate`?
+  --> $DIR/unresolved-import-recovery.rs:3:5
+   |
+LL | use unresolved_crate::module::Name;
+   |     ^^^^^^^^^^^^^^^^ maybe a missing crate `unresolved_crate`?
+
+error: Compilation failed, aborting rustdoc
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/arg-count-mismatch.rs b/src/test/ui/arg-count-mismatch.rs
deleted file mode 100644
index 18926f5daf7..00000000000
--- a/src/test/ui/arg-count-mismatch.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// error-pattern: arguments were supplied
-
-fn f(x: isize) { }
-
-fn main() { let i: (); i = f(); }
diff --git a/src/test/ui/arg-count-mismatch.stderr b/src/test/ui/arg-count-mismatch.stderr
deleted file mode 100644
index d0577e4864a..00000000000
--- a/src/test/ui/arg-count-mismatch.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0061]: this function takes 1 argument but 0 arguments were supplied
-  --> $DIR/arg-count-mismatch.rs:5:28
-   |
-LL | fn main() { let i: (); i = f(); }
-   |                            ^-- supplied 0 arguments
-   |                            |
-   |                            expected 1 argument
-   |
-note: function defined here
-  --> $DIR/arg-count-mismatch.rs:3:4
-   |
-LL | fn f(x: isize) { }
-   |    ^ --------
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/arg-type-mismatch.rs b/src/test/ui/arg-type-mismatch.rs
deleted file mode 100644
index 04ce2888785..00000000000
--- a/src/test/ui/arg-type-mismatch.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-// error-pattern: mismatched types
-
-fn f(x: isize) { }
-
-fn main() { let i: (); i = f(()); }
diff --git a/src/test/ui/arg-type-mismatch.stderr b/src/test/ui/arg-type-mismatch.stderr
deleted file mode 100644
index 05b21efeece..00000000000
--- a/src/test/ui/arg-type-mismatch.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/arg-type-mismatch.rs:5:30
-   |
-LL | fn main() { let i: (); i = f(()); }
-   |                              ^^ expected `isize`, found `()`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/argument-suggestions/basic.rs b/src/test/ui/argument-suggestions/basic.rs
new file mode 100644
index 00000000000..765b2d5d68e
--- /dev/null
+++ b/src/test/ui/argument-suggestions/basic.rs
@@ -0,0 +1,25 @@
+// Some basic "obvious" cases for the heuristic error messages added for #65853
+// One for each of the detected cases
+
+enum E { X, Y }
+enum F { X2, Y2 }
+struct G {}
+struct H {}
+struct X {}
+struct Y {}
+struct Z {}
+
+
+fn invalid(_i: u32) {}
+fn extra() {}
+fn missing(_i: u32) {}
+fn swapped(_i: u32, _s: &str) {}
+fn permuted(_x: X, _y: Y, _z: Z) {}
+
+fn main() {
+    invalid(1.0); //~ ERROR mismatched types
+    extra(""); //~ ERROR this function takes
+    missing(); //~ ERROR this function takes
+    swapped("", 1); //~ ERROR arguments to this function are incorrect
+    permuted(Y {}, Z {}, X {}); //~ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/basic.stderr b/src/test/ui/argument-suggestions/basic.stderr
new file mode 100644
index 00000000000..78f82b07619
--- /dev/null
+++ b/src/test/ui/argument-suggestions/basic.stderr
@@ -0,0 +1,87 @@
+error[E0308]: mismatched types
+  --> $DIR/basic.rs:20:13
+   |
+LL |     invalid(1.0);
+   |     ------- ^^^ expected `u32`, found floating-point number
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/basic.rs:13:4
+   |
+LL | fn invalid(_i: u32) {}
+   |    ^^^^^^^ -------
+
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+  --> $DIR/basic.rs:21:5
+   |
+LL |     extra("");
+   |     ^^^^^ -- argument unexpected
+   |
+note: function defined here
+  --> $DIR/basic.rs:14:4
+   |
+LL | fn extra() {}
+   |    ^^^^^
+help: remove the extra argument
+   |
+LL |     extra();
+   |     ~~~~~~~
+
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+  --> $DIR/basic.rs:22:5
+   |
+LL |     missing();
+   |     ^^^^^^^-- an argument of type `u32` is missing
+   |
+note: function defined here
+  --> $DIR/basic.rs:15:4
+   |
+LL | fn missing(_i: u32) {}
+   |    ^^^^^^^ -------
+help: provide the argument
+   |
+LL |     missing({u32});
+   |     ~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/basic.rs:23:5
+   |
+LL |     swapped("", 1);
+   |     ^^^^^^^ --  - expected `&str`,found `{integer}`
+   |             |
+   |             expected `u32`,found `&'static str`
+   |
+note: function defined here
+  --> $DIR/basic.rs:16:4
+   |
+LL | fn swapped(_i: u32, _s: &str) {}
+   |    ^^^^^^^ -------  --------
+help: swap these arguments
+   |
+LL |     swapped(1, "");
+   |     ~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/basic.rs:24:5
+   |
+LL |     permuted(Y {}, Z {}, X {});
+   |     ^^^^^^^^ ----  ----  ---- expected `Z`,found `X`
+   |              |     |
+   |              |     expected `Y`,found `Z`
+   |              expected `X`,found `Y`
+   |
+note: function defined here
+  --> $DIR/basic.rs:17:4
+   |
+LL | fn permuted(_x: X, _y: Y, _z: Z) {}
+   |    ^^^^^^^^ -----  -----  -----
+help: reorder these arguments
+   |
+LL |     permuted(X {}, Y {}, Z {});
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/complex.rs b/src/test/ui/argument-suggestions/complex.rs
new file mode 100644
index 00000000000..384cdca7e4f
--- /dev/null
+++ b/src/test/ui/argument-suggestions/complex.rs
@@ -0,0 +1,16 @@
+// A complex case with mixed suggestions from #65853
+
+enum E { X, Y }
+enum F { X2, Y2 }
+struct G {}
+struct H {}
+struct X {}
+struct Y {}
+struct Z {}
+
+fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
+
+fn main() {
+  complex(1.0, H {}, &"", G{}, F::X2, Z {}, X {}, Y {});
+  //~^ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/complex.stderr b/src/test/ui/argument-suggestions/complex.stderr
new file mode 100644
index 00000000000..c628f7dff34
--- /dev/null
+++ b/src/test/ui/argument-suggestions/complex.stderr
@@ -0,0 +1,19 @@
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/complex.rs:14:3
+   |
+LL |   complex(1.0, H {}, &"", G{}, F::X2, Z {}, X {}, Y {});
+   |   ^^^^^^^ --- expected `u32`, found floating-point number
+   |
+note: function defined here
+  --> $DIR/complex.rs:11:4
+   |
+LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
+   |    ^^^^^^^ -------  --------  -----  -----  -----  -----  -----  ------
+help: did you mean
+   |
+LL |   complex({u32}, &"", {E}, F::X2, G{}, X {}, Y {}, Z {});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/argument-suggestions/extra_arguments.rs b/src/test/ui/argument-suggestions/extra_arguments.rs
new file mode 100644
index 00000000000..3706ac4e8e1
--- /dev/null
+++ b/src/test/ui/argument-suggestions/extra_arguments.rs
@@ -0,0 +1,35 @@
+fn empty() {}
+fn one_arg(_a: i32) {}
+fn two_arg_same(_a: i32, _b: i32) {}
+fn two_arg_diff(_a: i32, _b: &str) {}
+
+fn main() {
+  empty(""); //~ ERROR this function takes
+
+  one_arg(1, 1); //~ ERROR this function takes
+  one_arg(1, ""); //~ ERROR this function takes
+  one_arg(1, "", 1.0); //~ ERROR this function takes
+
+  two_arg_same(1, 1, 1); //~ ERROR this function takes
+  two_arg_same(1, 1, 1.0); //~ ERROR this function takes
+
+  two_arg_diff(1, 1, ""); //~ ERROR this function takes
+  two_arg_diff(1, "", ""); //~ ERROR this function takes
+  two_arg_diff(1, 1, "", ""); //~ ERROR this function takes
+  two_arg_diff(1, "", 1, ""); //~ ERROR this function takes
+
+  // Check with weird spacing and newlines
+  two_arg_same(1, 1,     ""); //~ ERROR this function takes
+  two_arg_diff(1, 1,     ""); //~ ERROR this function takes
+  two_arg_same( //~ ERROR this function takes
+    1,
+    1,
+    ""
+  );
+
+  two_arg_diff( //~ ERROR this function takes
+    1,
+    1,
+    ""
+  );
+}
diff --git a/src/test/ui/argument-suggestions/extra_arguments.stderr b/src/test/ui/argument-suggestions/extra_arguments.stderr
new file mode 100644
index 00000000000..9b63f9bcbfa
--- /dev/null
+++ b/src/test/ui/argument-suggestions/extra_arguments.stderr
@@ -0,0 +1,239 @@
+error[E0061]: this function takes 0 arguments but 1 argument was supplied
+  --> $DIR/extra_arguments.rs:7:3
+   |
+LL |   empty("");
+   |   ^^^^^ -- argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:1:4
+   |
+LL | fn empty() {}
+   |    ^^^^^
+help: remove the extra argument
+   |
+LL |   empty();
+   |   ~~~~~~~
+
+error[E0061]: this function takes 1 argument but 2 arguments were supplied
+  --> $DIR/extra_arguments.rs:9:3
+   |
+LL |   one_arg(1, 1);
+   |   ^^^^^^^    - argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:2:4
+   |
+LL | fn one_arg(_a: i32) {}
+   |    ^^^^^^^ -------
+help: remove the extra argument
+   |
+LL |   one_arg(1);
+   |   ~~~~~~~~~~
+
+error[E0061]: this function takes 1 argument but 2 arguments were supplied
+  --> $DIR/extra_arguments.rs:10:3
+   |
+LL |   one_arg(1, "");
+   |   ^^^^^^^    -- argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:2:4
+   |
+LL | fn one_arg(_a: i32) {}
+   |    ^^^^^^^ -------
+help: remove the extra argument
+   |
+LL |   one_arg(1);
+   |   ~~~~~~~~~~
+
+error[E0061]: this function takes 1 argument but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:11:3
+   |
+LL |   one_arg(1, "", 1.0);
+   |   ^^^^^^^    --  --- argument unexpected
+   |              |
+   |              argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:2:4
+   |
+LL | fn one_arg(_a: i32) {}
+   |    ^^^^^^^ -------
+help: remove the extra arguments
+   |
+LL |   one_arg(1);
+   |   ~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:13:3
+   |
+LL |   two_arg_same(1, 1, 1);
+   |   ^^^^^^^^^^^^       - argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:3:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL |   two_arg_same(1, 1);
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:14:3
+   |
+LL |   two_arg_same(1, 1, 1.0);
+   |   ^^^^^^^^^^^^       --- argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:3:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL |   two_arg_same(1, 1);
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:16:3
+   |
+LL |   two_arg_diff(1, 1, "");
+   |   ^^^^^^^^^^^^    - argument of type `&str` unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:4:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: &str) {}
+   |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL |   two_arg_diff(1, "");
+   |   ~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:17:3
+   |
+LL |   two_arg_diff(1, "", "");
+   |   ^^^^^^^^^^^^        -- argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:4:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: &str) {}
+   |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL |   two_arg_diff(1, "");
+   |   ~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 4 arguments were supplied
+  --> $DIR/extra_arguments.rs:18:3
+   |
+LL |   two_arg_diff(1, 1, "", "");
+   |   ^^^^^^^^^^^^    -      -- argument unexpected
+   |                   |
+   |                   argument of type `&str` unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:4:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: &str) {}
+   |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra arguments
+   |
+LL |   two_arg_diff(1, "");
+   |   ~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 4 arguments were supplied
+  --> $DIR/extra_arguments.rs:19:3
+   |
+LL |   two_arg_diff(1, "", 1, "");
+   |   ^^^^^^^^^^^^        -  -- argument unexpected
+   |                       |
+   |                       argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:4:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: &str) {}
+   |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra arguments
+   |
+LL |   two_arg_diff(1, "");
+   |   ~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:22:3
+   |
+LL |   two_arg_same(1, 1,     "");
+   |   ^^^^^^^^^^^^           -- argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:3:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL |   two_arg_same(1, 1);
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:23:3
+   |
+LL |   two_arg_diff(1, 1,     "");
+   |   ^^^^^^^^^^^^    - argument of type `&str` unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:4:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: &str) {}
+   |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL |   two_arg_diff(1, "");
+   |   ~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:24:3
+   |
+LL |   two_arg_same(
+   |   ^^^^^^^^^^^^
+...
+LL |     ""
+   |     -- argument unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:3:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL |   two_arg_same(1, 1);
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/extra_arguments.rs:30:3
+   |
+LL |   two_arg_diff(
+   |   ^^^^^^^^^^^^
+LL |     1,
+LL |     1,
+   |     - argument of type `&str` unexpected
+   |
+note: function defined here
+  --> $DIR/extra_arguments.rs:4:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: &str) {}
+   |    ^^^^^^^^^^^^ -------  --------
+help: remove the extra argument
+   |
+LL |   two_arg_diff(1, "");
+   |   ~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/invalid_arguments.rs b/src/test/ui/argument-suggestions/invalid_arguments.rs
new file mode 100644
index 00000000000..53fbdd4b5da
--- /dev/null
+++ b/src/test/ui/argument-suggestions/invalid_arguments.rs
@@ -0,0 +1,43 @@
+// More nuanced test cases for invalid arguments #65853
+
+struct X {}
+
+fn one_arg(_a: i32) {}
+fn two_arg_same(_a: i32, _b: i32) {}
+fn two_arg_diff(_a: i32, _b: f32) {}
+fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+
+fn main() {
+  // Providing an incorrect argument for a single parameter function
+  one_arg(1.0); //~ ERROR mismatched types
+
+  // Providing one or two invalid arguments to a two parameter function
+  two_arg_same(1, ""); //~ ERROR mismatched types
+  two_arg_same("", 1); //~ ERROR mismatched types
+  two_arg_same("", ""); //~ ERROR arguments to this function are incorrect
+  two_arg_diff(1, ""); //~ ERROR mismatched types
+  two_arg_diff("", 1.0); //~ ERROR mismatched types
+  two_arg_diff("", ""); //~ ERROR arguments to this function are incorrect
+
+  // Providing invalid arguments to a three parameter function
+  three_arg_diff(X{}, 1.0, ""); //~ ERROR mismatched types
+  three_arg_diff(1, X {}, ""); //~ ERROR mismatched types
+  three_arg_diff(1, 1.0, X {}); //~ ERROR mismatched types
+
+  three_arg_diff(X {}, X {}, ""); //~ ERROR arguments to this function are incorrect
+  three_arg_diff(X {}, 1.0, X {}); //~ ERROR arguments to this function are incorrect
+  three_arg_diff(1, X {}, X {}); //~ ERROR arguments to this function are incorrect
+
+  three_arg_diff(X {}, X {}, X {}); //~ ERROR arguments to this function are incorrect
+
+  three_arg_repeat(X {}, 1, ""); //~ ERROR mismatched types
+  three_arg_repeat(1, X {}, ""); //~ ERROR mismatched types
+  three_arg_repeat(1, 1, X {}); //~ ERROR mismatched types
+
+  three_arg_repeat(X {}, X {}, ""); //~ ERROR arguments to this function are incorrect
+  three_arg_repeat(X {}, 1, X {}); //~ ERROR arguments to this function are incorrect
+  three_arg_repeat(1, X {}, X{}); //~ ERROR arguments to this function are incorrect
+
+  three_arg_repeat(X {}, X {}, X {}); //~ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/invalid_arguments.stderr b/src/test/ui/argument-suggestions/invalid_arguments.stderr
new file mode 100644
index 00000000000..33f27d48fec
--- /dev/null
+++ b/src/test/ui/argument-suggestions/invalid_arguments.stderr
@@ -0,0 +1,299 @@
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:13:11
+   |
+LL |   one_arg(1.0);
+   |   ------- ^^^ expected `i32`, found floating-point number
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:5:4
+   |
+LL | fn one_arg(_a: i32) {}
+   |    ^^^^^^^ -------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:16:19
+   |
+LL |   two_arg_same(1, "");
+   |   ------------    ^^ expected `i32`, found `&str`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:6:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:17:16
+   |
+LL |   two_arg_same("", 1);
+   |   ------------ ^^ expected `i32`, found `&str`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:6:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:18:3
+   |
+LL |   two_arg_same("", "");
+   |   ^^^^^^^^^^^^ --  -- expected `i32`, found `&str`
+   |                |
+   |                expected `i32`, found `&str`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:6:4
+   |
+LL | fn two_arg_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:19:19
+   |
+LL |   two_arg_diff(1, "");
+   |   ------------    ^^ expected `f32`, found `&str`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:7:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: f32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:20:16
+   |
+LL |   two_arg_diff("", 1.0);
+   |   ------------ ^^ expected `i32`, found `&str`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:7:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: f32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:21:3
+   |
+LL |   two_arg_diff("", "");
+   |   ^^^^^^^^^^^^ --  -- expected `f32`, found `&str`
+   |                |
+   |                expected `i32`, found `&str`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:7:4
+   |
+LL | fn two_arg_diff(_a: i32, _b: f32) {}
+   |    ^^^^^^^^^^^^ -------  -------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:24:18
+   |
+LL |   three_arg_diff(X{}, 1.0, "");
+   |   -------------- ^^^ expected `i32`, found struct `X`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:25:21
+   |
+LL |   three_arg_diff(1, X {}, "");
+   |   --------------    ^^^^ expected `f32`, found struct `X`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:26:26
+   |
+LL |   three_arg_diff(1, 1.0, X {});
+   |   --------------         ^^^^ expected `&str`, found struct `X`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:28:3
+   |
+LL |   three_arg_diff(X {}, X {}, "");
+   |   ^^^^^^^^^^^^^^ ----  ---- expected `f32`, found struct `X`
+   |                  |
+   |                  expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:29:3
+   |
+LL |   three_arg_diff(X {}, 1.0, X {});
+   |   ^^^^^^^^^^^^^^ ----       ---- expected `&str`, found struct `X`
+   |                  |
+   |                  expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:30:3
+   |
+LL |   three_arg_diff(1, X {}, X {});
+   |   ^^^^^^^^^^^^^^    ----  ---- expected `&str`, found struct `X`
+   |                     |
+   |                     expected `f32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:32:3
+   |
+LL |   three_arg_diff(X {}, X {}, X {});
+   |   ^^^^^^^^^^^^^^ ----  ----  ---- expected `&str`, found struct `X`
+   |                  |     |
+   |                  |     expected `f32`, found struct `X`
+   |                  expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:8:4
+   |
+LL | fn three_arg_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:34:20
+   |
+LL |   three_arg_repeat(X {}, 1, "");
+   |   ---------------- ^^^^ expected `i32`, found struct `X`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:35:23
+   |
+LL |   three_arg_repeat(1, X {}, "");
+   |   ----------------    ^^^^ expected `i32`, found struct `X`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: mismatched types
+  --> $DIR/invalid_arguments.rs:36:26
+   |
+LL |   three_arg_repeat(1, 1, X {});
+   |   ----------------       ^^^^ expected `&str`, found struct `X`
+   |   |
+   |   arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:38:3
+   |
+LL |   three_arg_repeat(X {}, X {}, "");
+   |   ^^^^^^^^^^^^^^^^ ----  ---- expected `i32`, found struct `X`
+   |                    |
+   |                    expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:39:3
+   |
+LL |   three_arg_repeat(X {}, 1, X {});
+   |   ^^^^^^^^^^^^^^^^ ----     ---- expected `&str`, found struct `X`
+   |                    |
+   |                    expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:40:3
+   |
+LL |   three_arg_repeat(1, X {}, X{});
+   |   ^^^^^^^^^^^^^^^^    ----  --- expected `&str`, found struct `X`
+   |                       |
+   |                       expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/invalid_arguments.rs:42:3
+   |
+LL |   three_arg_repeat(X {}, X {}, X {});
+   |   ^^^^^^^^^^^^^^^^ ----  ----  ---- expected `&str`, found struct `X`
+   |                    |     |
+   |                    |     expected `i32`, found struct `X`
+   |                    expected `i32`, found struct `X`
+   |
+note: function defined here
+  --> $DIR/invalid_arguments.rs:9:4
+   |
+LL | fn three_arg_repeat(_a: i32, _b: i32, _c: &str) {}
+   |    ^^^^^^^^^^^^^^^^ -------  -------  --------
+
+error: aborting due to 21 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/argument-suggestions/missing_arguments.rs b/src/test/ui/argument-suggestions/missing_arguments.rs
new file mode 100644
index 00000000000..ae0dabf27b1
--- /dev/null
+++ b/src/test/ui/argument-suggestions/missing_arguments.rs
@@ -0,0 +1,40 @@
+fn one_arg(_a: i32) {}
+fn two_same(_a: i32, _b: i32) {}
+fn two_diff(_a: i32, _b: f32) {}
+fn three_same(_a: i32, _b: i32, _c: i32) {}
+fn three_diff(_a: i32, _b: f32, _c: &str) {}
+fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
+fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
+
+fn main() {
+  one_arg(); //~ ERROR this function takes
+  // The headers here show the types expected,
+  // with formatting to emphasize which arguments are missing
+  /*         i32     f32    */
+  two_same(               ); //~ ERROR this function takes
+  two_same(   1           ); //~ ERROR this function takes
+  two_diff(               ); //~ ERROR this function takes
+  two_diff(   1           ); //~ ERROR this function takes
+  two_diff(          1.0  ); //~ ERROR this function takes
+
+  /*           i32     i32     i32    */
+  three_same(                       ); //~ ERROR this function takes
+  three_same(   1                   ); //~ ERROR this function takes
+  three_same(   1,      1           ); //~ ERROR this function takes
+
+  /*           i32     f32     &str   */
+  three_diff(          1.0,     ""  ); //~ ERROR this function takes
+  three_diff(   1,              ""  ); //~ ERROR this function takes
+  three_diff(   1,     1.0          ); //~ ERROR this function takes
+  three_diff(                   ""  ); //~ ERROR this function takes
+  three_diff(          1.0          ); //~ ERROR this function takes
+  three_diff(   1                   ); //~ ERROR this function takes
+
+  /*              i32     f32     f32     &str   */
+  four_repeated(                               ); //~ ERROR this function takes
+  four_repeated(   1,                     ""   ); //~ ERROR this function takes
+
+  /*        i32   f32   i32   f32   &str   */
+  complex(                               ); //~ ERROR this function takes
+  complex(   1,                     ""   ); //~ ERROR this function takes
+}
diff --git a/src/test/ui/argument-suggestions/missing_arguments.stderr b/src/test/ui/argument-suggestions/missing_arguments.stderr
new file mode 100644
index 00000000000..b4dadb1b9da
--- /dev/null
+++ b/src/test/ui/argument-suggestions/missing_arguments.stderr
@@ -0,0 +1,310 @@
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+  --> $DIR/missing_arguments.rs:10:3
+   |
+LL |   one_arg();
+   |   ^^^^^^^-- an argument of type `i32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:1:4
+   |
+LL | fn one_arg(_a: i32) {}
+   |    ^^^^^^^ -------
+help: provide the argument
+   |
+LL |   one_arg({i32});
+   |   ~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 0 arguments were supplied
+  --> $DIR/missing_arguments.rs:14:3
+   |
+LL |   two_same(               );
+   |   ^^^^^^^^----------------- two arguments of type `i32` and `i32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:2:4
+   |
+LL | fn two_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^ -------  -------
+help: provide the arguments
+   |
+LL |   two_same({i32}, {i32});
+   |   ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:15:3
+   |
+LL |   two_same(   1           );
+   |   ^^^^^^^^----------------- an argument of type `i32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:2:4
+   |
+LL | fn two_same(_a: i32, _b: i32) {}
+   |    ^^^^^^^^ -------  -------
+help: provide the argument
+   |
+LL |   two_same(1, {i32});
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 0 arguments were supplied
+  --> $DIR/missing_arguments.rs:16:3
+   |
+LL |   two_diff(               );
+   |   ^^^^^^^^----------------- two arguments of type `i32` and `f32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:3:4
+   |
+LL | fn two_diff(_a: i32, _b: f32) {}
+   |    ^^^^^^^^ -------  -------
+help: provide the arguments
+   |
+LL |   two_diff({i32}, {f32});
+   |   ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:17:3
+   |
+LL |   two_diff(   1           );
+   |   ^^^^^^^^----------------- an argument of type `f32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:3:4
+   |
+LL | fn two_diff(_a: i32, _b: f32) {}
+   |    ^^^^^^^^ -------  -------
+help: provide the argument
+   |
+LL |   two_diff(1, {f32});
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 2 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:18:3
+   |
+LL |   two_diff(          1.0  );
+   |   ^^^^^^^^           --- an argument of type `i32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:3:4
+   |
+LL | fn two_diff(_a: i32, _b: f32) {}
+   |    ^^^^^^^^ -------  -------
+help: provide the argument
+   |
+LL |   two_diff({i32}, 1.0);
+   |   ~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 0 arguments were supplied
+  --> $DIR/missing_arguments.rs:21:3
+   |
+LL |   three_same(                       );
+   |   ^^^^^^^^^^------------------------- three arguments of type `i32`, `i32`, and `i32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:4:4
+   |
+LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
+   |    ^^^^^^^^^^ -------  -------  -------
+help: provide the arguments
+   |
+LL |   three_same({i32}, {i32}, {i32});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:22:3
+   |
+LL |   three_same(   1                   );
+   |   ^^^^^^^^^^------------------------- two arguments of type `i32` and `i32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:4:4
+   |
+LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
+   |    ^^^^^^^^^^ -------  -------  -------
+help: provide the arguments
+   |
+LL |   three_same(1, {i32}, {i32});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/missing_arguments.rs:23:3
+   |
+LL |   three_same(   1,      1           );
+   |   ^^^^^^^^^^------------------------- an argument of type `i32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:4:4
+   |
+LL | fn three_same(_a: i32, _b: i32, _c: i32) {}
+   |    ^^^^^^^^^^ -------  -------  -------
+help: provide the argument
+   |
+LL |   three_same(1, 1, {i32});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/missing_arguments.rs:26:3
+   |
+LL |   three_diff(          1.0,     ""  );
+   |   ^^^^^^^^^^           --- an argument of type `i32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:5:4
+   |
+LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the argument
+   |
+LL |   three_diff({i32}, 1.0, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/missing_arguments.rs:27:3
+   |
+LL |   three_diff(   1,              ""  );
+   |   ^^^^^^^^^^                    -- an argument of type `f32` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:5:4
+   |
+LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the argument
+   |
+LL |   three_diff(1, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/missing_arguments.rs:28:3
+   |
+LL |   three_diff(   1,     1.0          );
+   |   ^^^^^^^^^^------------------------- an argument of type `&str` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:5:4
+   |
+LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the argument
+   |
+LL |   three_diff(1, 1.0, {&str});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:29:3
+   |
+LL |   three_diff(                   ""  );
+   |   ^^^^^^^^^^------------------------- two arguments of type `i32` and `f32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:5:4
+   |
+LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the arguments
+   |
+LL |   three_diff({i32}, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:30:3
+   |
+LL |   three_diff(          1.0          );
+   |   ^^^^^^^^^^-------------------------
+   |             |          |
+   |             |          an argument of type `i32` is missing
+   |             an argument of type `&str` is missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:5:4
+   |
+LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the arguments
+   |
+LL |   three_diff({i32}, 1.0, {&str});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 1 argument was supplied
+  --> $DIR/missing_arguments.rs:31:3
+   |
+LL |   three_diff(   1                   );
+   |   ^^^^^^^^^^------------------------- two arguments of type `f32` and `&str` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:5:4
+   |
+LL | fn three_diff(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the arguments
+   |
+LL |   three_diff(1, {f32}, {&str});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 4 arguments but 0 arguments were supplied
+  --> $DIR/missing_arguments.rs:34:3
+   |
+LL |   four_repeated(                               );
+   |   ^^^^^^^^^^^^^--------------------------------- multiple arguments are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:6:4
+   |
+LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
+   |    ^^^^^^^^^^^^^ -------  -------  -------  --------
+help: provide the arguments
+   |
+LL |   four_repeated({i32}, {f32}, {f32}, {&str});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 4 arguments but 2 arguments were supplied
+  --> $DIR/missing_arguments.rs:35:3
+   |
+LL |   four_repeated(   1,                     ""   );
+   |   ^^^^^^^^^^^^^--------------------------------- two arguments of type `f32` and `f32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:6:4
+   |
+LL | fn four_repeated(_a: i32, _b: f32, _c: f32, _d: &str) {}
+   |    ^^^^^^^^^^^^^ -------  -------  -------  --------
+help: provide the arguments
+   |
+LL |   four_repeated(1, {f32}, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 5 arguments but 0 arguments were supplied
+  --> $DIR/missing_arguments.rs:38:3
+   |
+LL |   complex(                               );
+   |   ^^^^^^^--------------------------------- multiple arguments are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:7:4
+   |
+LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
+   |    ^^^^^^^ -------  -------  -------  -------  --------
+help: provide the arguments
+   |
+LL |   complex({i32}, {f32}, {i32}, {f32}, {&str});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 5 arguments but 2 arguments were supplied
+  --> $DIR/missing_arguments.rs:39:3
+   |
+LL |   complex(   1,                     ""   );
+   |   ^^^^^^^--------------------------------- three arguments of type `f32`, `i32`, and `i32` are missing
+   |
+note: function defined here
+  --> $DIR/missing_arguments.rs:7:4
+   |
+LL | fn complex(_a: i32, _b: f32, _c: i32, _d: f32, _e: &str) {}
+   |    ^^^^^^^ -------  -------  -------  -------  --------
+help: provide the arguments
+   |
+LL |   complex(1, {f32}, {i32}, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 19 previous errors
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/mixed_cases.rs b/src/test/ui/argument-suggestions/mixed_cases.rs
new file mode 100644
index 00000000000..73678482b30
--- /dev/null
+++ b/src/test/ui/argument-suggestions/mixed_cases.rs
@@ -0,0 +1,24 @@
+// Cases where multiple argument suggestions are mixed
+
+struct X {}
+
+fn two_args(_a: i32, _b: f32) {}
+fn three_args(_a: i32, _b: f32, _c: &str) {}
+
+fn main() {
+  // Extra + Invalid
+  two_args(1, "", X {}); //~ ERROR this function takes
+  three_args(1, "", X {}, ""); //~ ERROR this function takes
+
+  // Missing and Invalid
+  three_args(1, X {}); //~ ERROR this function takes
+
+  // Missing and Extra
+  three_args(1, "", X {}); //~ ERROR arguments to this function are incorrect
+
+  // Swapped and Invalid
+  three_args("", X {}, 1); //~ ERROR arguments to this function are incorrect
+
+  // Swapped and missing
+  three_args("", 1); //~ ERROR this function takes
+}
diff --git a/src/test/ui/argument-suggestions/mixed_cases.stderr b/src/test/ui/argument-suggestions/mixed_cases.stderr
new file mode 100644
index 00000000000..61da02f5837
--- /dev/null
+++ b/src/test/ui/argument-suggestions/mixed_cases.stderr
@@ -0,0 +1,117 @@
+error[E0061]: this function takes 2 arguments but 3 arguments were supplied
+  --> $DIR/mixed_cases.rs:10:3
+   |
+LL |   two_args(1, "", X {});
+   |   ^^^^^^^^    --  ---- argument unexpected
+   |               |
+   |               expected `f32`, found `&str`
+   |
+note: function defined here
+  --> $DIR/mixed_cases.rs:5:4
+   |
+LL | fn two_args(_a: i32, _b: f32) {}
+   |    ^^^^^^^^ -------  -------
+help: remove the extra argument
+   |
+LL |   two_args(1, {f32});
+   |   ~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 4 arguments were supplied
+  --> $DIR/mixed_cases.rs:11:3
+   |
+LL |   three_args(1, "", X {}, "");
+   |   ^^^^^^^^^^    --  ----  -- argument unexpected
+   |                 |   |
+   |                 |   argument of type `&str` unexpected
+   |                 an argument of type `f32` is missing
+   |
+note: function defined here
+  --> $DIR/mixed_cases.rs:6:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: did you mean
+   |
+LL |   three_args(1, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/mixed_cases.rs:14:3
+   |
+LL |   three_args(1, X {});
+   |   ^^^^^^^^^^---------
+   |             |   |
+   |             |   expected `f32`, found struct `X`
+   |             an argument of type `&str` is missing
+   |
+note: function defined here
+  --> $DIR/mixed_cases.rs:6:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: provide the argument
+   |
+LL |   three_args(1, {f32}, {&str});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/mixed_cases.rs:17:3
+   |
+LL |   three_args(1, "", X {});
+   |   ^^^^^^^^^^    --  ---- argument of type `&str` unexpected
+   |                 |
+   |                 an argument of type `f32` is missing
+   |
+note: function defined here
+  --> $DIR/mixed_cases.rs:6:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: did you mean
+   |
+LL |   three_args(1, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/mixed_cases.rs:20:3
+   |
+LL |   three_args("", X {}, 1);
+   |   ^^^^^^^^^^ --  ----  - expected `&str`,found `{integer}`
+   |              |   |
+   |              |   expected `f32`, found struct `X`
+   |              expected `i32`,found `&'static str`
+   |
+note: function defined here
+  --> $DIR/mixed_cases.rs:6:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: swap these arguments
+   |
+LL |   three_args(1, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0061]: this function takes 3 arguments but 2 arguments were supplied
+  --> $DIR/mixed_cases.rs:23:3
+   |
+LL |   three_args("", 1);
+   |   ^^^^^^^^^^ --  -
+   |              |   |
+   |              |   an argument of type `f32` is missing
+   |              |   expected `&str`,found `{integer}`
+   |              expected `i32`,found `&'static str`
+   |
+note: function defined here
+  --> $DIR/mixed_cases.rs:6:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: did you mean
+   |
+LL |   three_args(1, {f32}, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/argument-suggestions/permuted_arguments.rs b/src/test/ui/argument-suggestions/permuted_arguments.rs
new file mode 100644
index 00000000000..f512fde651c
--- /dev/null
+++ b/src/test/ui/argument-suggestions/permuted_arguments.rs
@@ -0,0 +1,13 @@
+// More complicated permutations
+struct X {}
+struct Y {}
+
+fn three_args(_a: i32, _b: f32, _c: &str) {}
+fn many_args(_a: i32, _b: f32, _c: &str, _d: X, _e: Y) {}
+
+fn main() {
+  // b, c, a
+  three_args(1.0, "", 1); //~ ERROR arguments to this function are incorrect
+  // d, e, b, a, c
+  many_args(X {}, Y {}, 1, 1.0, ""); //~ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/permuted_arguments.stderr b/src/test/ui/argument-suggestions/permuted_arguments.stderr
new file mode 100644
index 00000000000..52890f4e6a5
--- /dev/null
+++ b/src/test/ui/argument-suggestions/permuted_arguments.stderr
@@ -0,0 +1,43 @@
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/permuted_arguments.rs:10:3
+   |
+LL |   three_args(1.0, "", 1);
+   |   ^^^^^^^^^^ ---  --  - expected `&str`,found `{integer}`
+   |              |    |
+   |              |    expected `f32`,found `&'static str`
+   |              expected `i32`,found `{float}`
+   |
+note: function defined here
+  --> $DIR/permuted_arguments.rs:5:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: reorder these arguments
+   |
+LL |   three_args(1, 1.0, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/permuted_arguments.rs:12:3
+   |
+LL |   many_args(X {}, Y {}, 1, 1.0, "");
+   |   ^^^^^^^^^ ----  ----  -  ---  -- expected `Y`,found `&'static str`
+   |             |     |     |  |
+   |             |     |     |  expected `X`,found `{float}`
+   |             |     |     expected `&str`,found `{integer}`
+   |             |     expected `f32`,found `Y`
+   |             expected `i32`,found `X`
+   |
+note: function defined here
+  --> $DIR/permuted_arguments.rs:6:4
+   |
+LL | fn many_args(_a: i32, _b: f32, _c: &str, _d: X, _e: Y) {}
+   |    ^^^^^^^^^ -------  -------  --------  -----  -----
+help: reorder these arguments
+   |
+LL |   many_args(1, 1.0, "", X {}, Y {});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/argument-suggestions/swapped_arguments.rs b/src/test/ui/argument-suggestions/swapped_arguments.rs
new file mode 100644
index 00000000000..a21de610c6a
--- /dev/null
+++ b/src/test/ui/argument-suggestions/swapped_arguments.rs
@@ -0,0 +1,14 @@
+struct X {}
+
+fn two_args(_a: i32, _b: f32) {}
+fn three_args(_a: i32, _b: f32, _c: &str) {}
+fn four_args(_a: i32, _b: f32, _c: &str, _d: X) {}
+
+fn main() {
+  two_args(1.0, 1); //~ ERROR arguments to this function are incorrect
+  three_args(1.0,   1,  ""); //~ ERROR arguments to this function are incorrect
+  three_args(  1,  "", 1.0); //~ ERROR arguments to this function are incorrect
+  three_args( "", 1.0,   1); //~ ERROR arguments to this function are incorrect
+
+  four_args(1.0, 1, X {}, ""); //~ ERROR arguments to this function are incorrect
+}
diff --git a/src/test/ui/argument-suggestions/swapped_arguments.stderr b/src/test/ui/argument-suggestions/swapped_arguments.stderr
new file mode 100644
index 00000000000..672f0d5bb56
--- /dev/null
+++ b/src/test/ui/argument-suggestions/swapped_arguments.stderr
@@ -0,0 +1,95 @@
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/swapped_arguments.rs:8:3
+   |
+LL |   two_args(1.0, 1);
+   |   ^^^^^^^^ ---  - expected `f32`,found `{integer}`
+   |            |
+   |            expected `i32`,found `{float}`
+   |
+note: function defined here
+  --> $DIR/swapped_arguments.rs:3:4
+   |
+LL | fn two_args(_a: i32, _b: f32) {}
+   |    ^^^^^^^^ -------  -------
+help: swap these arguments
+   |
+LL |   two_args(1, 1.0);
+   |   ~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/swapped_arguments.rs:9:3
+   |
+LL |   three_args(1.0,   1,  "");
+   |   ^^^^^^^^^^ ---    - expected `f32`,found `{integer}`
+   |              |
+   |              expected `i32`,found `{float}`
+   |
+note: function defined here
+  --> $DIR/swapped_arguments.rs:4:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: swap these arguments
+   |
+LL |   three_args(1, 1.0, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/swapped_arguments.rs:10:3
+   |
+LL |   three_args(  1,  "", 1.0);
+   |   ^^^^^^^^^^       --  --- expected `&str`,found `{float}`
+   |                    |
+   |                    expected `f32`,found `&'static str`
+   |
+note: function defined here
+  --> $DIR/swapped_arguments.rs:4:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: swap these arguments
+   |
+LL |   three_args(1, 1.0, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/swapped_arguments.rs:11:3
+   |
+LL |   three_args( "", 1.0,   1);
+   |   ^^^^^^^^^^  --         - expected `&str`,found `{integer}`
+   |               |
+   |               expected `i32`,found `&'static str`
+   |
+note: function defined here
+  --> $DIR/swapped_arguments.rs:4:4
+   |
+LL | fn three_args(_a: i32, _b: f32, _c: &str) {}
+   |    ^^^^^^^^^^ -------  -------  --------
+help: swap these arguments
+   |
+LL |   three_args(1, 1.0, "");
+   |   ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/swapped_arguments.rs:13:3
+   |
+LL |   four_args(1.0, 1, X {}, "");
+   |   ^^^^^^^^^ ---  -  ----  -- expected `X`,found `&'static str`
+   |             |    |  |
+   |             |    |  expected `&str`,found `X`
+   |             |    expected `f32`,found `{integer}`
+   |             expected `i32`,found `{float}`
+   |
+note: function defined here
+  --> $DIR/swapped_arguments.rs:5:4
+   |
+LL | fn four_args(_a: i32, _b: f32, _c: &str, _d: X) {}
+   |    ^^^^^^^^^ -------  -------  --------  -----
+help: did you mean
+   |
+LL |   four_args(1, 1.0, "", X {});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/asm/aarch64/parse-error.rs b/src/test/ui/asm/aarch64/parse-error.rs
index 59d6b28d0fd..cbc93cd3f75 100644
--- a/src/test/ui/asm/aarch64/parse-error.rs
+++ b/src/test/ui/asm/aarch64/parse-error.rs
@@ -29,7 +29,7 @@ fn main() {
         asm!("{}", in(reg) foo => bar);
         //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
         asm!("{}", sym foo + bar);
-        //~^ ERROR argument to `sym` must be a path expression
+        //~^ ERROR expected a path for argument to `sym`
         asm!("", options(foo));
         //~^ ERROR expected one of
         asm!("", options(nomem foo));
diff --git a/src/test/ui/asm/aarch64/parse-error.stderr b/src/test/ui/asm/aarch64/parse-error.stderr
index 3f705ba5b64..f2013046cda 100644
--- a/src/test/ui/asm/aarch64/parse-error.stderr
+++ b/src/test/ui/asm/aarch64/parse-error.stderr
@@ -58,7 +58,7 @@ error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
 LL |         asm!("{}", in(reg) foo => bar);
    |                                ^^ expected one of 7 possible tokens
 
-error: argument to `sym` must be a path expression
+error: expected a path for argument to `sym`
   --> $DIR/parse-error.rs:31:24
    |
 LL |         asm!("{}", sym foo + bar);
@@ -350,17 +350,17 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
-error: expected one of `clobber_abi`, `const`, or `options`, found `""`
+error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
   --> $DIR/parse-error.rs:126:28
    |
 LL | global_asm!("", options(), "");
-   |                            ^^ expected one of `clobber_abi`, `const`, or `options`
+   |                            ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
-error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
+error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
   --> $DIR/parse-error.rs:128:30
    |
 LL | global_asm!("{}", const FOO, "{}", const FOO);
-   |                              ^^^^ expected one of `clobber_abi`, `const`, or `options`
+   |                              ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: asm template must be a string literal
   --> $DIR/parse-error.rs:130:13
diff --git a/src/test/ui/asm/aarch64/type-check-2.rs b/src/test/ui/asm/aarch64/type-check-2.rs
index 1b91f5d0678..9e53a2e0c52 100644
--- a/src/test/ui/asm/aarch64/type-check-2.rs
+++ b/src/test/ui/asm/aarch64/type-check-2.rs
@@ -2,7 +2,7 @@
 
 #![feature(repr_simd, never_type, asm_sym)]
 
-use std::arch::asm;
+use std::arch::{asm, global_asm};
 
 #[repr(simd)]
 #[derive(Clone, Copy)]
@@ -39,9 +39,7 @@ fn main() {
         asm!("{}", sym S);
         asm!("{}", sym main);
         asm!("{}", sym C);
-        //~^ ERROR asm `sym` operand must point to a fn or static
-        asm!("{}", sym x);
-        //~^ ERROR asm `sym` operand must point to a fn or static
+        //~^ ERROR invalid `sym` operand
 
         // Register operands must be Copy
 
@@ -84,3 +82,12 @@ fn main() {
         asm!("{}", in(reg) u);
     }
 }
+
+// Sym operands must point to a function or static
+
+const C: i32 = 0;
+static S: i32 = 0;
+global_asm!("{}", sym S);
+global_asm!("{}", sym main);
+global_asm!("{}", sym C);
+//~^ ERROR invalid `sym` operand
diff --git a/src/test/ui/asm/aarch64/type-check-2.stderr b/src/test/ui/asm/aarch64/type-check-2.stderr
index beb301c7c74..6047bed6e78 100644
--- a/src/test/ui/asm/aarch64/type-check-2.stderr
+++ b/src/test/ui/asm/aarch64/type-check-2.stderr
@@ -1,13 +1,13 @@
 error: arguments for inline assembly must be copyable
-  --> $DIR/type-check-2.rs:48:31
+  --> $DIR/type-check-2.rs:46:31
    |
 LL |         asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `SimdNonCopy` does not implement the Copy trait
 
-error: cannot use value of type `[closure@$DIR/type-check-2.rs:60:28: 60:38]` for inline assembly
-  --> $DIR/type-check-2.rs:60:28
+error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly
+  --> $DIR/type-check-2.rs:58:28
    |
 LL |         asm!("{}", in(reg) |x: i32| x);
    |                            ^^^^^^^^^^
@@ -15,7 +15,7 @@ LL |         asm!("{}", in(reg) |x: i32| x);
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `Vec<i32>` for inline assembly
-  --> $DIR/type-check-2.rs:62:28
+  --> $DIR/type-check-2.rs:60:28
    |
 LL |         asm!("{}", in(reg) vec![0]);
    |                            ^^^^^^^
@@ -24,7 +24,7 @@ LL |         asm!("{}", in(reg) vec![0]);
    = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: cannot use value of type `(i32, i32, i32)` for inline assembly
-  --> $DIR/type-check-2.rs:64:28
+  --> $DIR/type-check-2.rs:62:28
    |
 LL |         asm!("{}", in(reg) (1, 2, 3));
    |                            ^^^^^^^^^
@@ -32,7 +32,7 @@ LL |         asm!("{}", in(reg) (1, 2, 3));
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `[i32; 3]` for inline assembly
-  --> $DIR/type-check-2.rs:66:28
+  --> $DIR/type-check-2.rs:64:28
    |
 LL |         asm!("{}", in(reg) [1, 2, 3]);
    |                            ^^^^^^^^^
@@ -40,7 +40,7 @@ LL |         asm!("{}", in(reg) [1, 2, 3]);
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `fn() {main}` for inline assembly
-  --> $DIR/type-check-2.rs:74:31
+  --> $DIR/type-check-2.rs:72:31
    |
 LL |         asm!("{}", inout(reg) f);
    |                               ^
@@ -48,24 +48,28 @@ LL |         asm!("{}", inout(reg) f);
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `&mut i32` for inline assembly
-  --> $DIR/type-check-2.rs:77:31
+  --> $DIR/type-check-2.rs:75:31
    |
 LL |         asm!("{}", inout(reg) r);
    |                               ^
    |
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
-error: asm `sym` operand must point to a fn or static
-  --> $DIR/type-check-2.rs:41:24
+error: invalid `sym` operand
+  --> $DIR/type-check-2.rs:41:20
    |
 LL |         asm!("{}", sym C);
-   |                        ^
+   |                    ^^^^^ is an `i32`
+   |
+   = help: `sym` operands must refer to either a function or a static
 
-error: asm `sym` operand must point to a fn or static
-  --> $DIR/type-check-2.rs:43:24
+error: invalid `sym` operand
+  --> $DIR/type-check-2.rs:92:19
+   |
+LL | global_asm!("{}", sym C);
+   |                   ^^^^^ is an `i32`
    |
-LL |         asm!("{}", sym x);
-   |                        ^
+   = help: `sym` operands must refer to either a function or a static
 
 error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/type-check-2.rs:19:28
diff --git a/src/test/ui/asm/type-check-1.rs b/src/test/ui/asm/type-check-1.rs
index 695fd27efd4..9f0121e11b4 100644
--- a/src/test/ui/asm/type-check-1.rs
+++ b/src/test/ui/asm/type-check-1.rs
@@ -3,7 +3,7 @@
 // ignore-spirv
 // ignore-wasm32
 
-#![feature(asm_const)]
+#![feature(asm_const, asm_sym)]
 
 use std::arch::{asm, global_asm};
 
@@ -44,6 +44,8 @@ fn main() {
         asm!("{}", const const_bar(0));
         asm!("{}", const const_bar(x));
         //~^ ERROR attempt to use a non-constant value in a constant
+        asm!("{}", sym x);
+        //~^ ERROR invalid `sym` operand
 
         // Const operands must be integers and must be constants.
 
@@ -59,6 +61,11 @@ fn main() {
     }
 }
 
+unsafe fn generic<T>() {
+    asm!("{}", sym generic::<T>);
+    //~^ generic parameters may not be used in const operations
+}
+
 // Const operands must be integers and must be constants.
 
 global_asm!("{}", const 0);
diff --git a/src/test/ui/asm/type-check-1.stderr b/src/test/ui/asm/type-check-1.stderr
index d774c78ca9a..7dba69fb745 100644
--- a/src/test/ui/asm/type-check-1.stderr
+++ b/src/test/ui/asm/type-check-1.stderr
@@ -25,14 +25,31 @@ LL |         let x = 0;
 LL |         asm!("{}", const const_bar(x));
    |                                    ^ non-constant value
 
+error: invalid `sym` operand
+  --> $DIR/type-check-1.rs:47:24
+   |
+LL |         asm!("{}", sym x);
+   |                        ^ is a local variable
+   |
+   = help: `sym` operands must refer to either a function or a static
+
+error: generic parameters may not be used in const operations
+  --> $DIR/type-check-1.rs:65:30
+   |
+LL |     asm!("{}", sym generic::<T>);
+   |                              ^ cannot perform const operation using `T`
+   |
+   = note: type parameters may not be used in const expressions
+   = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:53:26
+  --> $DIR/type-check-1.rs:55:26
    |
 LL |         asm!("{}", const 0f32);
    |                          ^^^^ expected integer, found `f32`
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:55:26
+  --> $DIR/type-check-1.rs:57:26
    |
 LL |         asm!("{}", const 0 as *mut u8);
    |                          ^^^^^^^^^^^^ expected integer, found *-ptr
@@ -41,7 +58,7 @@ LL |         asm!("{}", const 0 as *mut u8);
            found raw pointer `*mut u8`
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:57:26
+  --> $DIR/type-check-1.rs:59:26
    |
 LL |         asm!("{}", const &0);
    |                          ^^ expected integer, found `&{integer}`
@@ -92,13 +109,13 @@ LL |         asm!("{}", inout(reg) v[..]);
    = note: all inline asm arguments must have a statically known size
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:67:25
+  --> $DIR/type-check-1.rs:74:25
    |
 LL | global_asm!("{}", const 0f32);
    |                         ^^^^ expected integer, found `f32`
 
 error[E0308]: mismatched types
-  --> $DIR/type-check-1.rs:69:25
+  --> $DIR/type-check-1.rs:76:25
    |
 LL | global_asm!("{}", const 0 as *mut u8);
    |                         ^^^^^^^^^^^^ expected integer, found *-ptr
@@ -106,7 +123,7 @@ LL | global_asm!("{}", const 0 as *mut u8);
    = note:     expected type `{integer}`
            found raw pointer `*mut u8`
 
-error: aborting due to 13 previous errors
+error: aborting due to 15 previous errors
 
 Some errors have detailed explanations: E0277, E0308, E0435.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/asm/x86_64/parse-error.rs b/src/test/ui/asm/x86_64/parse-error.rs
index f0629f9f51c..9aeb6b2853f 100644
--- a/src/test/ui/asm/x86_64/parse-error.rs
+++ b/src/test/ui/asm/x86_64/parse-error.rs
@@ -29,7 +29,7 @@ fn main() {
         asm!("{}", in(reg) foo => bar);
         //~^ ERROR expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
         asm!("{}", sym foo + bar);
-        //~^ ERROR argument to `sym` must be a path expression
+        //~^ ERROR expected a path for argument to `sym`
         asm!("", options(foo));
         //~^ ERROR expected one of
         asm!("", options(nomem foo));
diff --git a/src/test/ui/asm/x86_64/parse-error.stderr b/src/test/ui/asm/x86_64/parse-error.stderr
index 194cd66a66e..1fd317a96a8 100644
--- a/src/test/ui/asm/x86_64/parse-error.stderr
+++ b/src/test/ui/asm/x86_64/parse-error.stderr
@@ -58,7 +58,7 @@ error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, or an operator, found `=>`
 LL |         asm!("{}", in(reg) foo => bar);
    |                                ^^ expected one of 7 possible tokens
 
-error: argument to `sym` must be a path expression
+error: expected a path for argument to `sym`
   --> $DIR/parse-error.rs:31:24
    |
 LL |         asm!("{}", sym foo + bar);
@@ -362,17 +362,17 @@ LL | global_asm!("{a}", a = const FOO, a = const BAR);
    |
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`
 
-error: expected one of `clobber_abi`, `const`, or `options`, found `""`
+error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `""`
   --> $DIR/parse-error.rs:130:28
    |
 LL | global_asm!("", options(), "");
-   |                            ^^ expected one of `clobber_abi`, `const`, or `options`
+   |                            ^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
-error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
+error: expected one of `clobber_abi`, `const`, `options`, or `sym`, found `"{}"`
   --> $DIR/parse-error.rs:132:30
    |
 LL | global_asm!("{}", const FOO, "{}", const FOO);
-   |                              ^^^^ expected one of `clobber_abi`, `const`, or `options`
+   |                              ^^^^ expected one of `clobber_abi`, `const`, `options`, or `sym`
 
 error: asm template must be a string literal
   --> $DIR/parse-error.rs:134:13
diff --git a/src/test/ui/asm/x86_64/type-check-2.rs b/src/test/ui/asm/x86_64/type-check-2.rs
index f95aebb78b5..eb87ea91085 100644
--- a/src/test/ui/asm/x86_64/type-check-2.rs
+++ b/src/test/ui/asm/x86_64/type-check-2.rs
@@ -2,7 +2,7 @@
 
 #![feature(repr_simd, never_type, asm_sym)]
 
-use std::arch::asm;
+use std::arch::{asm, global_asm};
 
 #[repr(simd)]
 struct SimdNonCopy(f32, f32, f32, f32);
@@ -35,9 +35,7 @@ fn main() {
         asm!("{}", sym S);
         asm!("{}", sym main);
         asm!("{}", sym C);
-        //~^ ERROR asm `sym` operand must point to a fn or static
-        asm!("{}", sym x);
-        //~^ ERROR asm `sym` operand must point to a fn or static
+        //~^ ERROR invalid `sym` operand
 
         // Register operands must be Copy
 
@@ -80,3 +78,12 @@ fn main() {
         asm!("{}", in(reg) u);
     }
 }
+
+// Sym operands must point to a function or static
+
+const C: i32 = 0;
+static S: i32 = 0;
+global_asm!("{}", sym S);
+global_asm!("{}", sym main);
+global_asm!("{}", sym C);
+//~^ ERROR invalid `sym` operand
diff --git a/src/test/ui/asm/x86_64/type-check-2.stderr b/src/test/ui/asm/x86_64/type-check-2.stderr
index cec750fdf9a..cb3960acdf9 100644
--- a/src/test/ui/asm/x86_64/type-check-2.stderr
+++ b/src/test/ui/asm/x86_64/type-check-2.stderr
@@ -1,13 +1,13 @@
 error: arguments for inline assembly must be copyable
-  --> $DIR/type-check-2.rs:44:32
+  --> $DIR/type-check-2.rs:42:32
    |
 LL |         asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `SimdNonCopy` does not implement the Copy trait
 
-error: cannot use value of type `[closure@$DIR/type-check-2.rs:56:28: 56:38]` for inline assembly
-  --> $DIR/type-check-2.rs:56:28
+error: cannot use value of type `[closure@$DIR/type-check-2.rs:54:28: 54:38]` for inline assembly
+  --> $DIR/type-check-2.rs:54:28
    |
 LL |         asm!("{}", in(reg) |x: i32| x);
    |                            ^^^^^^^^^^
@@ -15,7 +15,7 @@ LL |         asm!("{}", in(reg) |x: i32| x);
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `Vec<i32>` for inline assembly
-  --> $DIR/type-check-2.rs:58:28
+  --> $DIR/type-check-2.rs:56:28
    |
 LL |         asm!("{}", in(reg) vec![0]);
    |                            ^^^^^^^
@@ -24,7 +24,7 @@ LL |         asm!("{}", in(reg) vec![0]);
    = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: cannot use value of type `(i32, i32, i32)` for inline assembly
-  --> $DIR/type-check-2.rs:60:28
+  --> $DIR/type-check-2.rs:58:28
    |
 LL |         asm!("{}", in(reg) (1, 2, 3));
    |                            ^^^^^^^^^
@@ -32,7 +32,7 @@ LL |         asm!("{}", in(reg) (1, 2, 3));
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `[i32; 3]` for inline assembly
-  --> $DIR/type-check-2.rs:62:28
+  --> $DIR/type-check-2.rs:60:28
    |
 LL |         asm!("{}", in(reg) [1, 2, 3]);
    |                            ^^^^^^^^^
@@ -40,7 +40,7 @@ LL |         asm!("{}", in(reg) [1, 2, 3]);
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `fn() {main}` for inline assembly
-  --> $DIR/type-check-2.rs:70:31
+  --> $DIR/type-check-2.rs:68:31
    |
 LL |         asm!("{}", inout(reg) f);
    |                               ^
@@ -48,24 +48,28 @@ LL |         asm!("{}", inout(reg) f);
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
 error: cannot use value of type `&mut i32` for inline assembly
-  --> $DIR/type-check-2.rs:73:31
+  --> $DIR/type-check-2.rs:71:31
    |
 LL |         asm!("{}", inout(reg) r);
    |                               ^
    |
    = note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
 
-error: asm `sym` operand must point to a fn or static
-  --> $DIR/type-check-2.rs:37:24
+error: invalid `sym` operand
+  --> $DIR/type-check-2.rs:37:20
    |
 LL |         asm!("{}", sym C);
-   |                        ^
+   |                    ^^^^^ is an `i32`
+   |
+   = help: `sym` operands must refer to either a function or a static
 
-error: asm `sym` operand must point to a fn or static
-  --> $DIR/type-check-2.rs:39:24
+error: invalid `sym` operand
+  --> $DIR/type-check-2.rs:88:19
+   |
+LL | global_asm!("{}", sym C);
+   |                   ^^^^^ is an `i32`
    |
-LL |         asm!("{}", sym x);
-   |                        ^
+   = help: `sym` operands must refer to either a function or a static
 
 error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/type-check-2.rs:15:28
diff --git a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
index 07f207627f4..b904ad102e9 100644
--- a/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-type-projection-from-supertrait.stderr
@@ -2,25 +2,57 @@ error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:27:23
    |
 LL | fn b() { dent(ModelT, Blue); }
-   |                       ^^^^ expected struct `Black`, found struct `Blue`
+   |          ----         ^^^^ expected struct `Black`, found struct `Blue`
+   |          |
+   |          arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/associated-type-projection-from-supertrait.rs:25:4
+   |
+LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
+   |    ^^^^        ----  ---------------
 
 error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:28:23
    |
 LL | fn c() { dent(ModelU, Black); }
-   |                       ^^^^^ expected struct `Blue`, found struct `Black`
+   |          ----         ^^^^^ expected struct `Blue`, found struct `Black`
+   |          |
+   |          arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/associated-type-projection-from-supertrait.rs:25:4
+   |
+LL | fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
+   |    ^^^^        ----  ---------------
 
 error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:32:28
    |
 LL | fn f() { ModelT.chip_paint(Blue); }
-   |                            ^^^^ expected struct `Black`, found struct `Blue`
+   |                 ---------- ^^^^ expected struct `Black`, found struct `Blue`
+   |                 |
+   |                 arguments to this function are incorrect
+   |
+note: associated function defined here
+  --> $DIR/associated-type-projection-from-supertrait.rs:12:8
+   |
+LL |     fn chip_paint(&self, c: Self::Color) { }
+   |        ^^^^^^^^^^ -----  --------------
 
 error[E0308]: mismatched types
   --> $DIR/associated-type-projection-from-supertrait.rs:33:28
    |
 LL | fn g() { ModelU.chip_paint(Black); }
-   |                            ^^^^^ expected struct `Blue`, found struct `Black`
+   |                 ---------- ^^^^^ expected struct `Blue`, found struct `Black`
+   |                 |
+   |                 arguments to this function are incorrect
+   |
+note: associated function defined here
+  --> $DIR/associated-type-projection-from-supertrait.rs:12:8
+   |
+LL |     fn chip_paint(&self, c: Self::Color) { }
+   |        ^^^^^^^^^^ -----  --------------
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr
index 2d8d513409d..1d0b84d31d4 100644
--- a/src/test/ui/associated-types/associated-types-path-2.stderr
+++ b/src/test/ui/associated-types/associated-types-path-2.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/associated-types-path-2.rs:19:14
    |
 LL |     f1(2i32, 4i32);
-   |              ^^^^ expected `u32`, found `i32`
+   |     --       ^^^^ expected `u32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/associated-types-path-2.rs:13:8
    |
+LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
+   |        ^^         ----  -------
 help: change the type of the numeric literal from `i32` to `u32`
    |
 LL |     f1(2i32, 4u32);
diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr
index 289a567209c..627bf05bba2 100644
--- a/src/test/ui/async-await/dont-suggest-missing-await.stderr
+++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/dont-suggest-missing-await.rs:14:18
    |
 LL |         take_u32(x)
-   |                  ^ expected `u32`, found opaque type
+   |         -------- ^ expected `u32`, found opaque type
+   |         |
+   |         arguments to this function are incorrect
    |
 note: while checking the return type of the `async fn`
   --> $DIR/dont-suggest-missing-await.rs:7:24
@@ -11,6 +13,11 @@ LL | async fn make_u32() -> u32 {
    |                        ^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `u32`
            found opaque type `impl Future<Output = u32>`
+note: function defined here
+  --> $DIR/dont-suggest-missing-await.rs:5:4
+   |
+LL | fn take_u32(x: u32) {}
+   |    ^^^^^^^^ ------
 help: consider `await`ing on the `Future`
    |
 LL |         take_u32(x.await)
diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr
index 3ebc4392f2c..b205fd61915 100644
--- a/src/test/ui/async-await/generator-desc.stderr
+++ b/src/test/ui/async-await/generator-desc.stderr
@@ -2,52 +2,67 @@ error[E0308]: mismatched types
   --> $DIR/generator-desc.rs:10:25
    |
 LL |     fun(async {}, async {});
-   |               --        ^^ expected `async` block, found a different `async` block
-   |               |
+   |               --        ^^
+   |               |         |
+   |               |         expected `async` block, found a different `async` block
+   |               |         arguments to this function are incorrect
    |               the expected `async` block
    |
    = note: expected `async` block `[static generator@$DIR/generator-desc.rs:10:15: 10:17]`
               found `async` block `[static generator@$DIR/generator-desc.rs:10:25: 10:27]`
+note: function defined here
+  --> $SRC_DIR/core/src/future/mod.rs:LL:COL
+   |
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+   |              ^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/generator-desc.rs:12:16
    |
 LL |     fun(one(), two());
-   |                ^^^^^ expected opaque type, found a different opaque type
-   |
-note: while checking the return type of the `async fn`
-  --> $DIR/generator-desc.rs:5:16
+   |     ---        ^^^^^ expected opaque type, found a different opaque type
+   |     |
+   |     arguments to this function are incorrect
    |
-LL | async fn one() {}
-   |                ^ checked the `Output` of this `async fn`, expected opaque type
 note: while checking the return type of the `async fn`
   --> $DIR/generator-desc.rs:6:16
    |
 LL | async fn two() {}
    |                ^ checked the `Output` of this `async fn`, found opaque type
-   = note: expected opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>)
-              found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>)
+   = note:     expected type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:5:16>)
+           found opaque type `impl Future<Output = ()>` (opaque type at <$DIR/generator-desc.rs:6:16>)
    = help: consider `await`ing on both `Future`s
    = note: distinct uses of `impl Trait` result in different opaque types
+note: function defined here
+  --> $DIR/generator-desc.rs:8:4
+   |
+LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
+   |    ^^^                         -----  -----
 
 error[E0308]: mismatched types
   --> $DIR/generator-desc.rs:14:26
    |
 LL |     fun((async || {})(), (async || {})());
-   |                   --     ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
-   |                   |
-   |                   the expected `async` closure body
+   |     ---                  ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
+   |     |
+   |     arguments to this function are incorrect
    |
   ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
    |
 LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
-   |                                           -------------------------------
-   |                                           |
-   |                                           the expected opaque type
-   |                                           the found opaque type
+   |                                           ------------------------------- the found opaque type
+   |
+   = note:     expected type `impl Future<Output = ()>` (`async` closure body)
+           found opaque type `impl Future<Output = ()>` (`async` closure body)
+note: function defined here
+  --> $DIR/generator-desc.rs:8:4
+   |
+LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
+   |    ^^^                         -----  -----
+help: consider `await`ing on the `Future`
    |
-   = note: expected opaque type `impl Future<Output = ()>` (`async` closure body)
-              found opaque type `impl Future<Output = ()>` (`async` closure body)
+LL |     fun((async || {})(), (async || {})().await);
+   |                                         ++++++
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr
index d951c8ed094..a5958baffba 100644
--- a/src/test/ui/async-await/suggest-missing-await-closure.stderr
+++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/suggest-missing-await-closure.rs:16:18
    |
 LL |         take_u32(x)
-   |                  ^ expected `u32`, found opaque type
+   |         -------- ^ expected `u32`, found opaque type
+   |         |
+   |         arguments to this function are incorrect
    |
 note: while checking the return type of the `async fn`
   --> $DIR/suggest-missing-await-closure.rs:8:24
@@ -11,6 +13,11 @@ LL | async fn make_u32() -> u32 {
    |                        ^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `u32`
            found opaque type `impl Future<Output = u32>`
+note: function defined here
+  --> $DIR/suggest-missing-await-closure.rs:6:4
+   |
+LL | fn take_u32(_x: u32) {}
+   |    ^^^^^^^^ -------
 help: consider `await`ing on the `Future`
    |
 LL |         take_u32(x.await)
diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr
index 76073c4c879..ba9ed5cb65f 100644
--- a/src/test/ui/async-await/suggest-missing-await.stderr
+++ b/src/test/ui/async-await/suggest-missing-await.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/suggest-missing-await.rs:12:14
    |
 LL |     take_u32(x)
-   |              ^ expected `u32`, found opaque type
+   |     -------- ^ expected `u32`, found opaque type
+   |     |
+   |     arguments to this function are incorrect
    |
 note: while checking the return type of the `async fn`
   --> $DIR/suggest-missing-await.rs:5:24
@@ -11,6 +13,11 @@ LL | async fn make_u32() -> u32 {
    |                        ^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `u32`
            found opaque type `impl Future<Output = u32>`
+note: function defined here
+  --> $DIR/suggest-missing-await.rs:3:4
+   |
+LL | fn take_u32(_x: u32) {}
+   |    ^^^^^^^^ -------
 help: consider `await`ing on the `Future`
    |
 LL |     take_u32(x.await)
diff --git a/src/test/ui/binding/issue-53114-safety-checks.rs b/src/test/ui/binding/issue-53114-safety-checks.rs
index ca4f0efd239..5042ad024af 100644
--- a/src/test/ui/binding/issue-53114-safety-checks.rs
+++ b/src/test/ui/binding/issue-53114-safety-checks.rs
@@ -20,13 +20,13 @@ fn let_wild_gets_unsafe_field() {
     let u1 = U { a: I(0) };
     let u2 = U { a: I(1) };
     let p = P { a: &2, b: &3 };
-    let _ = &p.b;  //~ WARN    reference to packed field
+    let _ = &p.b;  //~ ERROR    reference to packed field
     //~^  WARN will become a hard error
     let _ = u1.a;  // #53114: should eventually signal error as well
     let _ = &u2.a; //~ ERROR  [E0133]
 
     // variation on above with `_` in substructure
-    let (_,) = (&p.b,);  //~ WARN     reference to packed field
+    let (_,) = (&p.b,);  //~ ERROR     reference to packed field
     //~^  WARN will become a hard error
     let (_,) = (u1.a,);  //~ ERROR   [E0133]
     let (_,) = (&u2.a,); //~ ERROR   [E0133]
@@ -36,13 +36,13 @@ fn match_unsafe_field_to_wild() {
     let u1 = U { a: I(0) };
     let u2 = U { a: I(1) };
     let p = P { a: &2, b: &3 };
-    match &p.b  { _ => { } } //~ WARN     reference to packed field
+    match &p.b  { _ => { } } //~ ERROR     reference to packed field
     //~^  WARN will become a hard error
     match u1.a  { _ => { } } //~ ERROR   [E0133]
     match &u2.a { _ => { } } //~ ERROR   [E0133]
 
     // variation on above with `_` in substructure
-    match (&p.b,)  { (_,) => { } } //~ WARN     reference to packed field
+    match (&p.b,)  { (_,) => { } } //~ ERROR     reference to packed field
     //~^  WARN will become a hard error
     match (u1.a,)  { (_,) => { } } //~ ERROR   [E0133]
     match (&u2.a,) { (_,) => { } } //~ ERROR   [E0133]
diff --git a/src/test/ui/binding/issue-53114-safety-checks.stderr b/src/test/ui/binding/issue-53114-safety-checks.stderr
index 84cdb1453f8..f3840273cfa 100644
--- a/src/test/ui/binding/issue-53114-safety-checks.stderr
+++ b/src/test/ui/binding/issue-53114-safety-checks.stderr
@@ -1,16 +1,16 @@
-warning: reference to packed field is unaligned
+error: reference to packed field is unaligned
   --> $DIR/issue-53114-safety-checks.rs:23:13
    |
 LL |     let _ = &p.b;
    |             ^^^^
    |
-   = note: `#[warn(unaligned_references)]` on by default
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
-warning: reference to packed field is unaligned
+error: reference to packed field is unaligned
   --> $DIR/issue-53114-safety-checks.rs:29:17
    |
 LL |     let (_,) = (&p.b,);
@@ -21,7 +21,7 @@ LL |     let (_,) = (&p.b,);
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
-warning: reference to packed field is unaligned
+error: reference to packed field is unaligned
   --> $DIR/issue-53114-safety-checks.rs:39:11
    |
 LL |     match &p.b  { _ => { } }
@@ -32,7 +32,7 @@ LL |     match &p.b  { _ => { } }
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
-warning: reference to packed field is unaligned
+error: reference to packed field is unaligned
   --> $DIR/issue-53114-safety-checks.rs:45:12
    |
 LL |     match (&p.b,)  { (_,) => { } }
@@ -99,6 +99,58 @@ LL |     match (&u2.a,) { (_,) => { } }
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
-error: aborting due to 7 previous errors; 4 warnings emitted
+error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-53114-safety-checks.rs:23:13
+   |
+LL |     let _ = &p.b;
+   |             ^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-53114-safety-checks.rs:29:17
+   |
+LL |     let (_,) = (&p.b,);
+   |                 ^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-53114-safety-checks.rs:39:11
+   |
+LL |     match &p.b  { _ => { } }
+   |           ^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-53114-safety-checks.rs:45:12
+   |
+LL |     match (&p.b,)  { (_,) => { } }
+   |            ^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
diff --git a/src/test/ui/c-variadic/variadic-ffi-1.stderr b/src/test/ui/c-variadic/variadic-ffi-1.stderr
index 5b4e656d9dc..9acf1e93b07 100644
--- a/src/test/ui/c-variadic/variadic-ffi-1.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-1.stderr
@@ -8,29 +8,33 @@ error[E0060]: this function takes at least 2 arguments but 0 arguments were supp
   --> $DIR/variadic-ffi-1.rs:20:9
    |
 LL |         foo();
-   |         ^^^-- supplied 0 arguments
-   |         |
-   |         expected at least 2 arguments
+   |         ^^^-- two arguments of type `isize` and `u8` are missing
    |
 note: function defined here
   --> $DIR/variadic-ffi-1.rs:13:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
+help: provide the arguments
+   |
+LL |         foo({isize}, {u8});
+   |         ~~~~~~~~~~~~~~~~~~
 
 error[E0060]: this function takes at least 2 arguments but 1 argument was supplied
   --> $DIR/variadic-ffi-1.rs:21:9
    |
 LL |         foo(1);
-   |         ^^^ - supplied 1 argument
-   |         |
-   |         expected at least 2 arguments
+   |         ^^^--- an argument of type `u8` is missing
    |
 note: function defined here
   --> $DIR/variadic-ffi-1.rs:13:8
    |
 LL |     fn foo(f: isize, x: u8, ...);
    |        ^^^
+help: provide the argument
+   |
+LL |         foo(1, {u8});
+   |         ~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/variadic-ffi-1.rs:23:56
diff --git a/src/test/ui/cast/cast-int-to-char.stderr b/src/test/ui/cast/cast-int-to-char.stderr
index 55b9462db8d..ef606b6ae5f 100644
--- a/src/test/ui/cast/cast-int-to-char.stderr
+++ b/src/test/ui/cast/cast-int-to-char.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/cast-int-to-char.rs:4:16
    |
 LL |     foo::<u32>('0');
-   |                ^^^ expected `u32`, found `char`
+   |     ---------- ^^^ expected `u32`, found `char`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/cast-int-to-char.rs:1:4
+   |
+LL | fn foo<T>(_t: T) {}
+   |    ^^^    -----
 help: you can cast a `char` to a `u32`, since a `char` always occupies 4 bytes
    |
 LL |     foo::<u32>('0' as u32);
@@ -13,8 +20,15 @@ error[E0308]: mismatched types
   --> $DIR/cast-int-to-char.rs:5:16
    |
 LL |     foo::<i32>('0');
-   |                ^^^ expected `i32`, found `char`
+   |     ---------- ^^^ expected `i32`, found `char`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/cast-int-to-char.rs:1:4
    |
+LL | fn foo<T>(_t: T) {}
+   |    ^^^    -----
 help: you can cast a `char` to an `i32`, since a `char` always occupies 4 bytes
    |
 LL |     foo::<i32>('0' as i32);
@@ -24,8 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/cast-int-to-char.rs:6:16
    |
 LL |     foo::<u64>('0');
-   |                ^^^ expected `u64`, found `char`
+   |     ---------- ^^^ expected `u64`, found `char`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/cast-int-to-char.rs:1:4
    |
+LL | fn foo<T>(_t: T) {}
+   |    ^^^    -----
 help: you can cast a `char` to a `u64`, since a `char` always occupies 4 bytes
    |
 LL |     foo::<u64>('0' as u64);
@@ -35,8 +56,15 @@ error[E0308]: mismatched types
   --> $DIR/cast-int-to-char.rs:7:16
    |
 LL |     foo::<i64>('0');
-   |                ^^^ expected `i64`, found `char`
+   |     ---------- ^^^ expected `i64`, found `char`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/cast-int-to-char.rs:1:4
+   |
+LL | fn foo<T>(_t: T) {}
+   |    ^^^    -----
 help: you can cast a `char` to an `i64`, since a `char` always occupies 4 bytes
    |
 LL |     foo::<i64>('0' as i64);
@@ -46,7 +74,15 @@ error[E0308]: mismatched types
   --> $DIR/cast-int-to-char.rs:8:17
    |
 LL |     foo::<char>(0u32);
-   |                 ^^^^ expected `char`, found `u32`
+   |     ----------- ^^^^ expected `char`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/cast-int-to-char.rs:1:4
+   |
+LL | fn foo<T>(_t: T) {}
+   |    ^^^    -----
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs
index 4799f488d7d..1488f329648 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.rs
@@ -1,7 +1,5 @@
 // edition:2021
 
-// check-pass
-
 // Given how the closure desugaring is implemented (at least at the time of writing this test),
 // we don't need to truncate the captured path to a reference into a packed-struct if the field
 // being referenced will be moved into the closure, since it's safe to move out a field from a
@@ -11,9 +9,8 @@
 // inlined we will truncate the capture to access just the struct regardless of if the field
 // might get moved into the closure.
 //
-// It is possible for someone to try writing the code that relies on the desugaring to access a ref
-// into a packed-struct without explicity using unsafe. Here we test that the compiler warns the
-// user that such an access is still unsafe.
+// It is possible for someone to try writing the code that relies on the desugaring to create a ref
+// into a packed-struct. Here we test that the compiler still detects that case.
 fn test_missing_unsafe_warning_on_repr_packed() {
     #[repr(packed)]
     struct Foo { x: String }
@@ -22,7 +19,7 @@ fn test_missing_unsafe_warning_on_repr_packed() {
 
     let c = || {
         println!("{}", foo.x);
-        //~^ WARNING: reference to packed field is unaligned
+        //~^ ERROR: reference to packed field is unaligned
         //~| WARNING: this was previously accepted by the compiler but is being phased out
         let _z = foo.x;
     };
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
index fc0179d2cb4..8629837ba8d 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr
@@ -1,15 +1,29 @@
-warning: reference to packed field is unaligned
-  --> $DIR/repr_packed.rs:24:24
+error: reference to packed field is unaligned
+  --> $DIR/repr_packed.rs:21:24
    |
 LL |         println!("{}", foo.x);
    |                        ^^^^^
    |
-   = note: `#[warn(unaligned_references)]` on by default
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
-   = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-warning: 1 warning emitted
+error: aborting due to previous error
+
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/repr_packed.rs:21:24
+   |
+LL |         println!("{}", foo.x);
+   |                        ^^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/closures/closure-reform-bad.stderr b/src/test/ui/closures/closure-reform-bad.stderr
index 37813879ce7..534828ab348 100644
--- a/src/test/ui/closures/closure-reform-bad.stderr
+++ b/src/test/ui/closures/closure-reform-bad.stderr
@@ -4,7 +4,9 @@ error[E0308]: mismatched types
 LL |     let f = |s: &str| println!("{}{}", s, string);
    |             ------------------------------------- the found closure
 LL |     call_bare(f)
-   |               ^ expected fn pointer, found closure
+   |     --------- ^ expected fn pointer, found closure
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected fn pointer `for<'r> fn(&'r str)`
                  found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50]`
@@ -13,6 +15,11 @@ note: closures can only be coerced to `fn` types if they do not capture any vari
    |
 LL |     let f = |s: &str| println!("{}{}", s, string);
    |                                           ^^^^^^ `string` captured here
+note: function defined here
+  --> $DIR/closure-reform-bad.rs:4:4
+   |
+LL | fn call_bare(f: fn(&str)) {
+   |    ^^^^^^^^^ -----------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-84128.stderr b/src/test/ui/closures/issue-84128.stderr
index 70d9273ddf7..09c44d261af 100644
--- a/src/test/ui/closures/issue-84128.stderr
+++ b/src/test/ui/closures/issue-84128.stderr
@@ -2,13 +2,20 @@ error[E0308]: mismatched types
   --> $DIR/issue-84128.rs:13:13
    |
 LL |         Foo(())
-   |             ^^ expected integer, found `()`
+   |         --- ^^ expected integer, found `()`
+   |         |
+   |         arguments to this struct are incorrect
    |
 note: return type inferred to be `{integer}` here
   --> $DIR/issue-84128.rs:10:20
    |
 LL |             return Foo(0);
    |                    ^^^^^^
+note: tuple struct defined here
+  --> $DIR/issue-84128.rs:5:8
+   |
+LL | struct Foo<T>(T);
+   |        ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/issue-87461.stderr b/src/test/ui/closures/issue-87461.stderr
index a3cff2c1212..b35fa2b8c9a 100644
--- a/src/test/ui/closures/issue-87461.stderr
+++ b/src/test/ui/closures/issue-87461.stderr
@@ -2,19 +2,25 @@ error[E0308]: mismatched types
   --> $DIR/issue-87461.rs:10:8
    |
 LL |     Ok(())
-   |        ^^ expected `u16`, found `()`
+   |     -- ^^ expected `u16`, found `()`
+   |     |
+   |     arguments to this enum variant are incorrect
 
 error[E0308]: mismatched types
   --> $DIR/issue-87461.rs:17:8
    |
 LL |     Ok(())
-   |        ^^ expected `u16`, found `()`
+   |     -- ^^ expected `u16`, found `()`
+   |     |
+   |     arguments to this enum variant are incorrect
 
 error[E0308]: mismatched types
   --> $DIR/issue-87461.rs:26:12
    |
 LL |         Ok(())
-   |            ^^ expected `u16`, found `()`
+   |         -- ^^ expected `u16`, found `()`
+   |         |
+   |         arguments to this enum variant are incorrect
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/coercion/coerce-mut.stderr b/src/test/ui/coercion/coerce-mut.stderr
index 2601ca5e91e..11a4f310154 100644
--- a/src/test/ui/coercion/coerce-mut.stderr
+++ b/src/test/ui/coercion/coerce-mut.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/coerce-mut.rs:5:7
    |
 LL |     f(&x);
-   |       ^^ types differ in mutability
+   |     - ^^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut i32`
                       found reference `&{integer}`
+note: function defined here
+  --> $DIR/coerce-mut.rs:1:4
+   |
+LL | fn f(x: &mut i32) {}
+   |    ^ -----------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
index 59b0ec496f1..4f266b166d6 100644
--- a/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
+++ b/src/test/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/coerce-reborrow-multi-arg-fail.rs:4:18
    |
 LL |     test(&mut 7, &7);
-   |                  ^^ types differ in mutability
+   |     ----         ^^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
    |
-   = note: expected mutable reference `&mut {integer}`
-                      found reference `&{integer}`
+   = note:   expected type `&mut {integer}`
+           found reference `&{integer}`
+note: function defined here
+  --> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
+   |
+LL | fn test<T>(_a: T, _b: T) {}
+   |    ^^^^    -----  -----
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coercion/coerce-to-bang.stderr b/src/test/ui/coercion/coerce-to-bang.stderr
index 390aa7c692d..add8f14cfa5 100644
--- a/src/test/ui/coercion/coerce-to-bang.stderr
+++ b/src/test/ui/coercion/coerce-to-bang.stderr
@@ -2,46 +2,81 @@ error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:6:17
    |
 LL |     foo(return, 22, 44);
-   |                 ^^ expected `!`, found integer
+   |     ---         ^^ expected `!`, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `!`
               found type `{integer}`
+note: function defined here
+  --> $DIR/coerce-to-bang.rs:3:4
+   |
+LL | fn foo(x: usize, y: !, z: usize) { }
+   |    ^^^ --------  ----  --------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:18:13
    |
 LL |     foo(22, 44, return);
-   |             ^^ expected `!`, found integer
+   |     ---     ^^ expected `!`, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `!`
               found type `{integer}`
+note: function defined here
+  --> $DIR/coerce-to-bang.rs:3:4
+   |
+LL | fn foo(x: usize, y: !, z: usize) { }
+   |    ^^^ --------  ----  --------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:26:12
    |
 LL |     foo(a, b, c); // ... and hence a reference to `a` is expected to diverge.
-   |            ^ expected `!`, found integer
+   |     ---    ^ expected `!`, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `!`
               found type `{integer}`
+note: function defined here
+  --> $DIR/coerce-to-bang.rs:3:4
+   |
+LL | fn foo(x: usize, y: !, z: usize) { }
+   |    ^^^ --------  ----  --------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:36:12
    |
 LL |     foo(a, b, c);
-   |            ^ expected `!`, found integer
+   |     ---    ^ expected `!`, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `!`
               found type `{integer}`
+note: function defined here
+  --> $DIR/coerce-to-bang.rs:3:4
+   |
+LL | fn foo(x: usize, y: !, z: usize) { }
+   |    ^^^ --------  ----  --------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:45:12
    |
 LL |     foo(a, b, c);
-   |            ^ expected `!`, found integer
+   |     ---    ^ expected `!`, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `!`
               found type `{integer}`
+note: function defined here
+  --> $DIR/coerce-to-bang.rs:3:4
+   |
+LL | fn foo(x: usize, y: !, z: usize) { }
+   |    ^^^ --------  ----  --------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-to-bang.rs:50:21
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr
new file mode 100644
index 00000000000..e9854f0b9b5
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.min.stderr
@@ -0,0 +1,29 @@
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/const-argument-cross-crate-mismatch.rs:7:41
+   |
+LL |     let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^----------^
+   |                                                                   |
+   |                                                                   expected `[u8; 3]`, found `[u8; 2]`
+   |
+help: provide an argument of the correct type
+   |
+LL |     let _ = const_generic_lib::function(({[u8; 3]}));
+   |                                         ^^^^^^^^^^^
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/const-argument-cross-crate-mismatch.rs:9:39
+   |
+LL |     let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                                                                 |
+   |                                                                 expected `[u8; 2]`, found `[u8; 3]`
+   |
+help: provide an argument of the correct type
+   |
+LL |     let _: const_generic_lib::Alias = ({[u8; 2]});
+   |                                       ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
index aefd514f7a6..42f469d9817 100644
--- a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
@@ -2,13 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/const-argument-cross-crate-mismatch.rs:6:67
    |
 LL |     let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
-   |                                                                   ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                                         ------------------------- ^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 2 elements
+   |                                         |
+   |                                         arguments to this struct are incorrect
 
 error[E0308]: mismatched types
   --> $DIR/const-argument-cross-crate-mismatch.rs:8:65
    |
 LL |     let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
-   |                                                                 ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
+   |                                       ------------------------- ^^^^^^^^^^^^^^^ expected an array with a fixed size of 2 elements, found one with 3 elements
+   |                                       |
+   |                                       arguments to this struct are incorrect
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
index 5d45e302888..9bea4105d58 100644
--- a/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/issue-62504.min.stderr
@@ -1,19 +1,26 @@
+error: constant expression depends on a generic parameter
+  --> $DIR/issue-62504.rs:18:25
+   |
+LL |         ArrayHolder([0; Self::SIZE])
+   |                         ^^^^^^^^^^
+   |
+   = note: this may fail depending on what value the parameter takes
+
 error[E0308]: mismatched types
   --> $DIR/issue-62504.rs:18:21
    |
 LL |         ArrayHolder([0; Self::SIZE])
-   |                     ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+   |         ----------- ^^^^^^^^^^^^^^^ expected `X`, found `Self::SIZE`
+   |         |
+   |         arguments to this struct are incorrect
    |
    = note: expected array `[u32; X]`
               found array `[u32; _]`
-
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-62504.rs:18:25
+note: tuple struct defined here
+  --> $DIR/issue-62504.rs:14:8
    |
-LL |         ArrayHolder([0; Self::SIZE])
-   |                         ^^^^^^^^^^
-   |
-   = note: this may fail depending on what value the parameter takes
+LL | struct ArrayHolder<const X: usize>([u32; X]);
+   |        ^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr
index 667f82ee0cf..1002b359f60 100644
--- a/src/test/ui/derives/deriving-with-repr-packed.stderr
+++ b/src/test/ui/derives/deriving-with-repr-packed.stderr
@@ -45,3 +45,67 @@ LL | #[derive(PartialEq)]
 
 error: aborting due to 4 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
+  --> $DIR/deriving-with-repr-packed.rs:8:16
+   |
+LL | #[derive(Copy, Clone, PartialEq, Eq)]
+   |                ^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deriving-with-repr-packed.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
+  --> $DIR/deriving-with-repr-packed.rs:8:23
+   |
+LL | #[derive(Copy, Clone, PartialEq, Eq)]
+   |                       ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deriving-with-repr-packed.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
+  --> $DIR/deriving-with-repr-packed.rs:16:10
+   |
+LL | #[derive(PartialEq, Eq)]
+   |          ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deriving-with-repr-packed.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+Future breakage diagnostic:
+error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
+  --> $DIR/deriving-with-repr-packed.rs:25:10
+   |
+LL | #[derive(PartialEq)]
+   |          ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/deriving-with-repr-packed.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs
index 931ff1a5847..d1a81c72c2f 100644
--- a/src/test/ui/deriving/deriving-default-enum.rs
+++ b/src/test/ui/deriving/deriving-default-enum.rs
@@ -1,7 +1,5 @@
 // run-pass
 
-#![feature(derive_default_enum)]
-
 // nb: does not impl Default
 #[derive(Debug, PartialEq)]
 struct NotDefault;
diff --git a/src/test/ui/deriving/deriving-with-helper.rs b/src/test/ui/deriving/deriving-with-helper.rs
index d8f0b27a2e5..1c30b0b6fba 100644
--- a/src/test/ui/deriving/deriving-with-helper.rs
+++ b/src/test/ui/deriving/deriving-with-helper.rs
@@ -5,7 +5,6 @@
 #![feature(lang_items)]
 #![feature(no_core)]
 #![feature(rustc_attrs)]
-#![feature(derive_default_enum)]
 
 #![no_core]
 
diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr
index dbe46704b93..95b572133c5 100644
--- a/src/test/ui/did_you_mean/issue-42764.stderr
+++ b/src/test/ui/did_you_mean/issue-42764.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-42764.rs:11:43
    |
 LL |     this_function_expects_a_double_option(n);
-   |                                           ^ expected enum `DoubleOption`, found `usize`
+   |     ------------------------------------- ^ expected enum `DoubleOption`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected enum `DoubleOption<_>`
               found type `usize`
+note: function defined here
+  --> $DIR/issue-42764.rs:7:4
+   |
+LL | fn this_function_expects_a_double_option<T>(d: DoubleOption<T>) {}
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    ------------------
 help: try wrapping the expression in a variant of `DoubleOption`
    |
 LL |     this_function_expects_a_double_option(DoubleOption::FirstSome(n));
diff --git a/src/test/ui/disambiguate-identical-names.stderr b/src/test/ui/disambiguate-identical-names.stderr
index 0c6bd9379f7..42925cfed55 100644
--- a/src/test/ui/disambiguate-identical-names.stderr
+++ b/src/test/ui/disambiguate-identical-names.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/disambiguate-identical-names.rs:13:10
    |
 LL |     test(&v);
-   |          ^^ expected struct `std::vec::Vec`, found struct `HashMap`
+   |     ---- ^^ expected struct `std::vec::Vec`, found struct `HashMap`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&std::vec::Vec<std::vec::Vec<u32>>`
               found reference `&HashMap<u8, u8>`
+note: function defined here
+  --> $DIR/disambiguate-identical-names.rs:6:4
+   |
+LL | fn test(_v: &Vec<Vec<u32>>) {
+   |    ^^^^ ------------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr
index 31579e28289..a151b20f865 100644
--- a/src/test/ui/error-codes/E0057.stderr
+++ b/src/test/ui/error-codes/E0057.stderr
@@ -2,17 +2,23 @@ error[E0057]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/E0057.rs:3:13
    |
 LL |     let a = f();
-   |             ^-- supplied 0 arguments
-   |             |
-   |             expected 1 argument
+   |             ^-- an argument is missing
+   |
+help: provide the argument
+   |
+LL |     let a = f({_});
+   |             ~~~~~~
 
 error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/E0057.rs:5:13
    |
 LL |     let c = f(2, 3);
-   |             ^ -  - supplied 2 arguments
-   |             |
-   |             expected 1 argument
+   |             ^    - argument unexpected
+   |
+help: remove the extra argument
+   |
+LL |     let c = f(2);
+   |             ~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0060.rs b/src/test/ui/error-codes/E0060.rs
index 941eb2a210b..7050a1dff6c 100644
--- a/src/test/ui/error-codes/E0060.rs
+++ b/src/test/ui/error-codes/E0060.rs
@@ -5,5 +5,4 @@ extern "C" {
 fn main() {
     unsafe { printf(); }
     //~^ ERROR E0060
-    //~| expected at least 1 argument
 }
diff --git a/src/test/ui/error-codes/E0060.stderr b/src/test/ui/error-codes/E0060.stderr
index c80014d1476..9dd649239e2 100644
--- a/src/test/ui/error-codes/E0060.stderr
+++ b/src/test/ui/error-codes/E0060.stderr
@@ -2,15 +2,17 @@ error[E0060]: this function takes at least 1 argument but 0 arguments were suppl
   --> $DIR/E0060.rs:6:14
    |
 LL |     unsafe { printf(); }
-   |              ^^^^^^-- supplied 0 arguments
-   |              |
-   |              expected at least 1 argument
+   |              ^^^^^^-- an argument of type `*const u8` is missing
    |
 note: function defined here
   --> $DIR/E0060.rs:2:8
    |
 LL |     fn printf(_: *const u8, ...) -> u32;
    |        ^^^^^^
+help: provide the argument
+   |
+LL |     unsafe { printf({*const u8}); }
+   |              ~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0061.rs b/src/test/ui/error-codes/E0061.rs
index c7b5fe4310e..b6fae6c63d7 100644
--- a/src/test/ui/error-codes/E0061.rs
+++ b/src/test/ui/error-codes/E0061.rs
@@ -5,9 +5,7 @@ fn f2(a: u16) {}
 fn main() {
     f(0);
     //~^ ERROR E0061
-    //~| expected 2 arguments
 
     f2();
     //~^ ERROR E0061
-    //~| expected 1 argument
 }
diff --git a/src/test/ui/error-codes/E0061.stderr b/src/test/ui/error-codes/E0061.stderr
index 98488a2d298..f92c548f2de 100644
--- a/src/test/ui/error-codes/E0061.stderr
+++ b/src/test/ui/error-codes/E0061.stderr
@@ -2,29 +2,33 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/E0061.rs:6:5
    |
 LL |     f(0);
-   |     ^ - supplied 1 argument
-   |     |
-   |     expected 2 arguments
+   |     ^--- an argument of type `&str` is missing
    |
 note: function defined here
   --> $DIR/E0061.rs:1:4
    |
 LL | fn f(a: u16, b: &str) {}
    |    ^ ------  -------
+help: provide the argument
+   |
+LL |     f(0, {&str});
+   |     ~~~~~~~~~~~~
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
-  --> $DIR/E0061.rs:10:5
+  --> $DIR/E0061.rs:9:5
    |
 LL |     f2();
-   |     ^^-- supplied 0 arguments
-   |     |
-   |     expected 1 argument
+   |     ^^-- an argument of type `u16` is missing
    |
 note: function defined here
   --> $DIR/E0061.rs:3:4
    |
 LL | fn f2(a: u16) {}
    |    ^^ ------
+help: provide the argument
+   |
+LL |     f2({u16});
+   |     ~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/estr-subtyping.rs b/src/test/ui/estr-subtyping.rs
new file mode 100644
index 00000000000..9c5825fff85
--- /dev/null
+++ b/src/test/ui/estr-subtyping.rs
@@ -0,0 +1,15 @@
+fn wants_uniq(x: String) { }
+fn wants_slice(x: &str) { }
+
+fn has_uniq(x: String) {
+   wants_uniq(x);
+   wants_slice(&*x);
+}
+
+fn has_slice(x: &str) {
+   wants_uniq(x); //~ ERROR mismatched types
+   wants_slice(x);
+}
+
+fn main() {
+}
diff --git a/src/test/ui/estr-subtyping.stderr b/src/test/ui/estr-subtyping.stderr
new file mode 100644
index 00000000000..adebb7d1e63
--- /dev/null
+++ b/src/test/ui/estr-subtyping.stderr
@@ -0,0 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/estr-subtyping.rs:10:15
+   |
+LL |    wants_uniq(x);
+   |    ---------- ^- help: try using a conversion method: `.to_string()`
+   |    |          |
+   |    |          expected struct `String`, found `&str`
+   |    arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/estr-subtyping.rs:1:4
+   |
+LL | fn wants_uniq(x: String) { }
+   |    ^^^^^^^^^^ ---------
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs b/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
deleted file mode 100644
index 05a5d4e1422..00000000000
--- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[derive(Default)] //~ ERROR deriving `Default` on enums is experimental
-enum Foo {
-    #[default]
-    Alpha,
-}
-
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr b/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
deleted file mode 100644
index 58dd4d508a7..00000000000
--- a/src/test/ui/feature-gates/feature-gate-derive_default_enum.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: deriving `Default` on enums is experimental
-  --> $DIR/feature-gate-derive_default_enum.rs:1:10
-   |
-LL | #[derive(Default)]
-   |          ^^^^^^^
-   |
-   = note: see issue #86985 <https://github.com/rust-lang/rust/issues/86985> for more information
-   = help: add `#![feature(derive_default_enum)]` to the crate attributes to enable
-   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr
index 3f1f1006713..c25da900951 100644
--- a/src/test/ui/fmt/ifmt-bad-arg.stderr
+++ b/src/test/ui/fmt/ifmt-bad-arg.stderr
@@ -296,20 +296,36 @@ error[E0308]: mismatched types
   --> $DIR/ifmt-bad-arg.rs:78:32
    |
 LL |     println!("{} {:.*} {}", 1, 3.2, 4);
-   |                                ^^^ expected `usize`, found floating-point number
+   |     ---------------------------^^^----
+   |     |                          |
+   |     |                          expected `usize`, found floating-point number
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&usize`
               found reference `&{float}`
+note: associated function defined here
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+   |
+LL |     pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
+   |            ^^^^^^^^^^
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0308]: mismatched types
   --> $DIR/ifmt-bad-arg.rs:81:35
    |
 LL |     println!("{} {:07$.*} {}", 1, 3.2, 4);
-   |                                   ^^^ expected `usize`, found floating-point number
+   |     ------------------------------^^^----
+   |     |                             |
+   |     |                             expected `usize`, found floating-point number
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&usize`
               found reference `&{float}`
+note: associated function defined here
+  --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+   |
+LL |     pub fn from_usize(x: &usize) -> ArgumentV1<'_> {
+   |            ^^^^^^^^^^
    = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 36 previous errors
diff --git a/src/test/ui/fn/fn-item-type.rs b/src/test/ui/fn/fn-item-type.rs
index 415e87b42fa..16a0c10ea3a 100644
--- a/src/test/ui/fn/fn-item-type.rs
+++ b/src/test/ui/fn/fn-item-type.rs
@@ -12,7 +12,7 @@ impl<T> Foo for T { /* `foo` is still default here */ }
 fn main() {
     eq(foo::<u8>, bar::<u8>);
     //~^ ERROR mismatched types
-    //~| expected fn item `fn(_) -> _ {foo::<u8>}`
+    //~| expected type `fn(_) -> _ {foo::<u8>}`
     //~| found fn item `fn(_) -> _ {bar::<u8>}`
     //~| expected fn item, found a different fn item
     //~| different `fn` items always have unique types, even if their signatures are the same
@@ -28,7 +28,7 @@ fn main() {
 
     eq(bar::<String>, bar::<Vec<u8>>);
     //~^ ERROR mismatched types
-    //~| expected fn item `fn(_) -> _ {bar::<String>}`
+    //~| expected type `fn(_) -> _ {bar::<String>}`
     //~| found fn item `fn(_) -> _ {bar::<Vec<u8>>}`
     //~| expected struct `String`, found struct `Vec`
     //~| different `fn` items always have unique types, even if their signatures are the same
@@ -45,7 +45,7 @@ fn main() {
 
     eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
     //~^ ERROR mismatched types
-    //~| expected fn item `fn(_) -> _ {foo::<u8>}`
+    //~| expected type `fn(_) -> _ {foo::<u8>}`
     //~| found fn pointer `fn(_) -> _`
     //~| expected fn item, found fn pointer
     //~| change the expected type to be function pointer
diff --git a/src/test/ui/fn/fn-item-type.stderr b/src/test/ui/fn/fn-item-type.stderr
index 4bd51a668a6..1fb120eb7a7 100644
--- a/src/test/ui/fn/fn-item-type.stderr
+++ b/src/test/ui/fn/fn-item-type.stderr
@@ -2,60 +2,95 @@ error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:13:19
    |
 LL |     eq(foo::<u8>, bar::<u8>);
-   |                   ^^^^^^^^^ expected fn item, found a different fn item
+   |     --            ^^^^^^^^^ expected fn item, found a different fn item
+   |     |
+   |     arguments to this function are incorrect
    |
-   = note: expected fn item `fn(_) -> _ {foo::<u8>}`
-              found fn item `fn(_) -> _ {bar::<u8>}`
+   = note: expected type `fn(_) -> _ {foo::<u8>}`
+           found fn item `fn(_) -> _ {bar::<u8>}`
    = note: different `fn` items always have unique types, even if their signatures are the same
    = help: change the expected type to be function pointer `fn(isize) -> isize`
    = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize`
+note: function defined here
+  --> $DIR/fn-item-type.rs:7:4
+   |
+LL | fn eq<T>(x: T, y: T) { }
+   |    ^^    ----  ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:22:19
    |
 LL |     eq(foo::<u8>, foo::<i8>);
-   |                   ^^^^^^^^^ expected `u8`, found `i8`
+   |     --            ^^^^^^^^^ expected `u8`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
-   = note: expected fn item `fn(_) -> _ {foo::<u8>}`
-              found fn item `fn(_) -> _ {foo::<i8>}`
+   = note: expected type `fn(_) -> _ {foo::<u8>}`
+           found fn item `fn(_) -> _ {foo::<i8>}`
    = note: different `fn` items always have unique types, even if their signatures are the same
    = help: change the expected type to be function pointer `fn(isize) -> isize`
    = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize`
+note: function defined here
+  --> $DIR/fn-item-type.rs:7:4
+   |
+LL | fn eq<T>(x: T, y: T) { }
+   |    ^^    ----  ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:29:23
    |
 LL |     eq(bar::<String>, bar::<Vec<u8>>);
-   |                       ^^^^^^^^^^^^^^ expected struct `String`, found struct `Vec`
+   |     --                ^^^^^^^^^^^^^^ expected struct `String`, found struct `Vec`
+   |     |
+   |     arguments to this function are incorrect
    |
-   = note: expected fn item `fn(_) -> _ {bar::<String>}`
-              found fn item `fn(_) -> _ {bar::<Vec<u8>>}`
+   = note: expected type `fn(_) -> _ {bar::<String>}`
+           found fn item `fn(_) -> _ {bar::<Vec<u8>>}`
    = note: different `fn` items always have unique types, even if their signatures are the same
    = help: change the expected type to be function pointer `fn(isize) -> isize`
    = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `bar::<String> as fn(isize) -> isize`
+note: function defined here
+  --> $DIR/fn-item-type.rs:7:4
+   |
+LL | fn eq<T>(x: T, y: T) { }
+   |    ^^    ----  ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:39:26
    |
 LL |     eq(<u8 as Foo>::foo, <u16 as Foo>::foo);
-   |                          ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
+   |     --                   ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
-   = note: expected fn item `fn() {<u8 as Foo>::foo}`
-              found fn item `fn() {<u16 as Foo>::foo}`
+   = note: expected type `fn() {<u8 as Foo>::foo}`
+           found fn item `fn() {<u16 as Foo>::foo}`
    = note: different `fn` items always have unique types, even if their signatures are the same
    = help: change the expected type to be function pointer `fn()`
    = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `<u8 as Foo>::foo as fn()`
+note: function defined here
+  --> $DIR/fn-item-type.rs:7:4
+   |
+LL | fn eq<T>(x: T, y: T) { }
+   |    ^^    ----  ----
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:46:19
    |
 LL |     eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
+   |     --            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
+   |     |
+   |     arguments to this function are incorrect
    |
-   = note: expected fn item `fn(_) -> _ {foo::<u8>}`
+   = note:    expected type `fn(_) -> _ {foo::<u8>}`
            found fn pointer `fn(_) -> _`
    = help: change the expected type to be function pointer `fn(isize) -> isize`
    = help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `foo::<u8> as fn(isize) -> isize`
+note: function defined here
+  --> $DIR/fn-item-type.rs:7:4
+   |
+LL | fn eq<T>(x: T, y: T) { }
+   |    ^^    ----  ----
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
index 26deb598762..e48ab4aa96f 100644
--- a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
+++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
@@ -8,15 +8,7 @@ where
     //~^ ERROR cannot find type `T` in this scope
     //~| NOTE not found in this scope
 {
-    // The part where it claims that there is no method named `len` is a bug. Feel free to fix it.
-    // This test is intended to ensure that a different bug, where it claimed
-    // that `v` was a function, does not regress.
     fn method(v: Vec<u8>) { v.len(); }
-    //~^ ERROR type annotations needed
-    //~| NOTE cannot infer type
-    //~| NOTE type must be known at this point
-    //~| ERROR no method named `len`
-    //~| NOTE private field, not a method
 }
 
 fn main() {}
diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
index 958ce3c25d0..26bdf460f5e 100644
--- a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
+++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
@@ -12,21 +12,6 @@ error[E0412]: cannot find type `T` in this scope
 LL |     T: Copy,
    |     ^ not found in this scope
 
-error[E0282]: type annotations needed
-  --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
-   |
-LL |     fn method(v: Vec<u8>) { v.len(); }
-   |                               ^^^ cannot infer type
-   |
-   = note: type must be known at this point
-
-error[E0599]: no method named `len` found for struct `Vec<u8>` in the current scope
-  --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
-   |
-LL |     fn method(v: Vec<u8>) { v.len(); }
-   |                               ^^^ private field, not a method
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0282, E0412, E0599.
-For more information about an error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/generic-associated-types/issue-68648-2.stderr b/src/test/ui/generic-associated-types/issue-68648-2.stderr
index 7a7d5a6c231..06c1efcd80b 100644
--- a/src/test/ui/generic-associated-types/issue-68648-2.stderr
+++ b/src/test/ui/generic-associated-types/issue-68648-2.stderr
@@ -4,10 +4,17 @@ error[E0308]: mismatched types
 LL | fn bug<'a, T: Fun<F<'a> = T>>(t: T) -> T::F<'a> {
    |            - this type parameter
 LL |     T::identity(())
-   |                 ^^ expected type parameter `T`, found `()`
+   |     ----------- ^^ expected type parameter `T`, found `()`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                    found unit type `()`
+note: associated function defined here
+  --> $DIR/issue-68648-2.rs:6:8
+   |
+LL |     fn identity<'a>(t: Self::F<'a>) -> Self::F<'a> { t }
+   |        ^^^^^^^^     --------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic-associated-types/missing-bounds.stderr b/src/test/ui/generic-associated-types/missing-bounds.stderr
index c9603b8d1ea..240be93cf96 100644
--- a/src/test/ui/generic-associated-types/missing-bounds.stderr
+++ b/src/test/ui/generic-associated-types/missing-bounds.stderr
@@ -17,10 +17,17 @@ LL | impl<B> Add for A<B> where B: Add {
    |      - this type parameter
 ...
 LL |         A(self.0 + rhs.0)
-   |           ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+   |         - ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+   |         |
+   |         arguments to this struct are incorrect
    |
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
+note: tuple struct defined here
+  --> $DIR/missing-bounds.rs:5:8
+   |
+LL | struct A<B>(B);
+   |        ^
 help: consider further restricting this bound
    |
 LL | impl<B> Add for A<B> where B: Add + Add<Output = B> {
@@ -33,10 +40,17 @@ LL | impl<B: Add> Add for C<B> {
    |      - this type parameter
 ...
 LL |         Self(self.0 + rhs.0)
-   |              ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+   |         ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
+note: tuple struct defined here
+  --> $DIR/missing-bounds.rs:15:8
+   |
+LL | struct C<B>(B);
+   |        ^
 help: consider further restricting this bound
    |
 LL | impl<B: Add + Add<Output = B>> Add for C<B> {
@@ -62,10 +76,17 @@ LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B {
    |      - this type parameter
 ...
 LL |         Self(self.0 + rhs.0)
-   |              ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+   |         ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `B`
              found associated type `<B as Add>::Output`
+note: tuple struct defined here
+  --> $DIR/missing-bounds.rs:35:8
+   |
+LL | struct E<B>(B);
+   |        ^
 help: consider further restricting type parameter `B`
    |
 LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B, B: Add<Output = B> {
diff --git a/src/test/ui/hello.rs b/src/test/ui/hello.rs
index c207c25545e..c66b7c60fb4 100644
--- a/src/test/ui/hello.rs
+++ b/src/test/ui/hello.rs
@@ -1,5 +1,12 @@
 // run-pass
+// revisions: e2015 e2018 e2021 e2024
 
-pub fn main() {
-    println!("hello, world");
+//[e2018] edition:2018
+//[e2021] edition:2021
+//[e2024] edition:2024
+
+//[e2024] compile-flags: -Zunstable-options
+
+fn main() {
+    println!("hello");
 }
diff --git a/src/test/ui/hello2021.rs b/src/test/ui/hello2021.rs
deleted file mode 100644
index 134d8af5bfb..00000000000
--- a/src/test/ui/hello2021.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// run-pass
-// edition:2021
-
-fn main() {
-    println!("hello, 2021");
-}
diff --git a/src/test/ui/hrtb/issue-58451.stderr b/src/test/ui/hrtb/issue-58451.stderr
index 2cc1c7a2e72..d2b3b1c2aa0 100644
--- a/src/test/ui/hrtb/issue-58451.stderr
+++ b/src/test/ui/hrtb/issue-58451.stderr
@@ -2,15 +2,17 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/issue-58451.rs:12:9
    |
 LL |     f(&[f()]);
-   |         ^-- supplied 0 arguments
-   |         |
-   |         expected 1 argument
+   |         ^-- an argument is missing
    |
 note: function defined here
   --> $DIR/issue-58451.rs:5:4
    |
 LL | fn f<I>(i: I)
    |    ^    ----
+help: provide the argument
+   |
+LL |     f(&[f({_})]);
+   |         ~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/issues/issue-74282.stderr b/src/test/ui/impl-trait/issues/issue-74282.stderr
index 6e02a6b2b87..0f855ef5792 100644
--- a/src/test/ui/impl-trait/issues/issue-74282.stderr
+++ b/src/test/ui/impl-trait/issues/issue-74282.stderr
@@ -5,7 +5,9 @@ LL |   type Closure = impl Fn() -> u64;
    |                  ---------------- the expected opaque type
 ...
 LL |       Anonymous(|| {
-   |  _______________^
+   |  _____---------_^
+   | |     |
+   | |     arguments to this struct are incorrect
 LL | |         3
 LL | |     })
    | |_____^ expected closure, found a different closure
@@ -14,6 +16,11 @@ LL | |     })
                   found closure `[closure@$DIR/issue-74282.rs:8:15: 10:6]`
    = note: no two closures, even if identical, have the same type
    = help: consider boxing your closure and/or using it as a trait object
+note: tuple struct defined here
+  --> $DIR/issue-74282.rs:4:8
+   |
+LL | struct Anonymous(Closure);
+   |        ^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-74282.rs:8:5
diff --git a/src/test/ui/imports/overlapping_pub_trait.rs b/src/test/ui/imports/overlapping_pub_trait.rs
index f5f5d4ed380..69aba3ae9b4 100644
--- a/src/test/ui/imports/overlapping_pub_trait.rs
+++ b/src/test/ui/imports/overlapping_pub_trait.rs
@@ -4,10 +4,10 @@
  * This crate declares two public paths, `m::Tr` and `prelude::_`. Make sure we prefer the former.
  */
 extern crate overlapping_pub_trait_source;
+//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
+//~| SUGGESTION overlapping_pub_trait_source::m::Tr
 
 fn main() {
-    //~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
-    //~| SUGGESTION overlapping_pub_trait_source::m::Tr
     use overlapping_pub_trait_source::S;
     S.method();
     //~^ ERROR no method named `method` found for struct `S` in the current scope [E0599]
diff --git a/src/test/ui/imports/unnamed_pub_trait.rs b/src/test/ui/imports/unnamed_pub_trait.rs
index b06b1e1d07d..c38fb17b976 100644
--- a/src/test/ui/imports/unnamed_pub_trait.rs
+++ b/src/test/ui/imports/unnamed_pub_trait.rs
@@ -5,10 +5,10 @@
  * importing it by name, and instead we suggest importing it by glob.
  */
 extern crate unnamed_pub_trait_source;
+//~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
+//~| SUGGESTION unnamed_pub_trait_source::prelude::*; // trait Tr
 
 fn main() {
-    //~^ HELP the following trait is implemented but not in scope; perhaps add a `use` for it:
-    //~| SUGGESTION unnamed_pub_trait_source::prelude::*; // trait Tr
     use unnamed_pub_trait_source::S;
     S.method();
     //~^ ERROR no method named `method` found for struct `S` in the current scope [E0599]
diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr
index dae11a702fb..a9adff4fade 100644
--- a/src/test/ui/indexing-requires-a-uint.stderr
+++ b/src/test/ui/indexing-requires-a-uint.stderr
@@ -12,12 +12,15 @@ error[E0308]: mismatched types
   --> $DIR/indexing-requires-a-uint.rs:12:18
    |
 LL |     bar::<isize>(i);  // i should not be re-coerced back to an isize
-   |                  ^ expected `isize`, found `usize`
+   |     ------------ ^ expected `isize`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
-help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit
+note: function defined here
+  --> $DIR/indexing-requires-a-uint.rs:5:8
    |
-LL |     bar::<isize>(i.try_into().unwrap());  // i should not be re-coerced back to an isize
-   |                   ++++++++++++++++++++
+LL |     fn bar<T>(_: T) {}
+   |        ^^^    ----
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/inference/deref-suggestion.stderr b/src/test/ui/inference/deref-suggestion.stderr
index 28c9afaa52c..8ba9dacb4b2 100644
--- a/src/test/ui/inference/deref-suggestion.stderr
+++ b/src/test/ui/inference/deref-suggestion.stderr
@@ -2,16 +2,30 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:8:9
    |
 LL |     foo(s);
-   |         ^- help: try using a conversion method: `.to_string()`
-   |         |
-   |         expected struct `String`, found `&String`
+   |     --- ^- help: try using a conversion method: `.to_string()`
+   |     |   |
+   |     |   expected struct `String`, found `&String`
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/deref-suggestion.rs:5:4
+   |
+LL | fn foo(_: String) {}
+   |    ^^^ ---------
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:14:10
    |
 LL |     foo3(u);
-   |          ^ expected `u32`, found `&u32`
+   |     ---- ^ expected `u32`, found `&u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/deref-suggestion.rs:12:4
    |
+LL | fn foo3(_: u32) {}
+   |    ^^^^ ------
 help: consider dereferencing the borrow
    |
 LL |     foo3(*u);
@@ -21,8 +35,15 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:30:9
    |
 LL |     foo(&"aaa".to_owned());
-   |         ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |     --- ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/deref-suggestion.rs:5:4
+   |
+LL | fn foo(_: String) {}
+   |    ^^^ ---------
 help: consider removing the borrow
    |
 LL -     foo(&"aaa".to_owned());
@@ -33,8 +54,15 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:32:9
    |
 LL |     foo(&mut "aaa".to_owned());
-   |         ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |     --- ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/deref-suggestion.rs:5:4
    |
+LL | fn foo(_: String) {}
+   |    ^^^ ---------
 help: consider removing the borrow
    |
 LL -     foo(&mut "aaa".to_owned());
@@ -48,8 +76,15 @@ LL |     ($x:expr) => { &$x }
    |                    ^^^ expected `u32`, found `&{integer}`
 ...
 LL |     foo3(borrow!(0));
-   |          ---------- in this macro invocation
+   |     ---- ---------- in this macro invocation
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/deref-suggestion.rs:12:4
    |
+LL | fn foo3(_: u32) {}
+   |    ^^^^ ------
    = note: this error originates in the macro `borrow` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0308]: mismatched types
diff --git a/src/test/ui/inference/tutorial-suffix-inference-test.stderr b/src/test/ui/inference/tutorial-suffix-inference-test.stderr
index fbfbffbd24e..d83a1367dbf 100644
--- a/src/test/ui/inference/tutorial-suffix-inference-test.stderr
+++ b/src/test/ui/inference/tutorial-suffix-inference-test.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/tutorial-suffix-inference-test.rs:9:18
    |
 LL |     identity_u16(x);
-   |                  ^ expected `u16`, found `u8`
+   |     ------------ ^ expected `u16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/tutorial-suffix-inference-test.rs:6:8
+   |
+LL |     fn identity_u16(n: u16) -> u16 { n }
+   |        ^^^^^^^^^^^^ ------
 help: you can convert a `u8` to a `u16`
    |
 LL |     identity_u16(x.into());
@@ -13,8 +20,15 @@ error[E0308]: mismatched types
   --> $DIR/tutorial-suffix-inference-test.rs:12:18
    |
 LL |     identity_u16(y);
-   |                  ^ expected `u16`, found `i32`
+   |     ------------ ^ expected `u16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/tutorial-suffix-inference-test.rs:6:8
    |
+LL |     fn identity_u16(n: u16) -> u16 { n }
+   |        ^^^^^^^^^^^^ ------
 help: you can convert an `i32` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     identity_u16(y.try_into().unwrap());
@@ -24,8 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/tutorial-suffix-inference-test.rs:21:18
    |
 LL |     identity_u16(a);
-   |                  ^ expected `u16`, found `isize`
+   |     ------------ ^ expected `u16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/tutorial-suffix-inference-test.rs:6:8
    |
+LL |     fn identity_u16(n: u16) -> u16 { n }
+   |        ^^^^^^^^^^^^ ------
 help: you can convert an `isize` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     identity_u16(a.try_into().unwrap());
diff --git a/src/test/ui/issues/issue-10764.stderr b/src/test/ui/issues/issue-10764.stderr
index b0bafc9942e..4d8a85a1397 100644
--- a/src/test/ui/issues/issue-10764.stderr
+++ b/src/test/ui/issues/issue-10764.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-10764.rs:4:15
    |
 LL | fn main() { f(bar) }
-   |               ^^^ expected "Rust" fn, found "C" fn
+   |             - ^^^ expected "Rust" fn, found "C" fn
+   |             |
+   |             arguments to this function are incorrect
    |
    = note: expected fn pointer `fn()`
                  found fn item `extern "C" fn() {bar}`
+note: function defined here
+  --> $DIR/issue-10764.rs:1:4
+   |
+LL | fn f(_: extern "Rust" fn()) {}
+   |    ^ ---------------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-11374.stderr b/src/test/ui/issues/issue-11374.stderr
index d6a3e758de8..3a1d43310e2 100644
--- a/src/test/ui/issues/issue-11374.stderr
+++ b/src/test/ui/issues/issue-11374.stderr
@@ -2,13 +2,19 @@ error[E0308]: mismatched types
   --> $DIR/issue-11374.rs:26:15
    |
 LL |     c.read_to(v);
-   |               ^
-   |               |
-   |               expected `&mut [u8]`, found struct `Vec`
-   |               help: consider mutably borrowing here: `&mut v`
+   |       ------- ^
+   |       |       |
+   |       |       expected `&mut [u8]`, found struct `Vec`
+   |       |       help: consider mutably borrowing here: `&mut v`
+   |       arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut [u8]`
                          found struct `Vec<_>`
+note: associated function defined here
+  --> $DIR/issue-11374.rs:13:12
+   |
+LL |     pub fn read_to(&mut self, vec: &mut [u8]) {
+   |            ^^^^^^^ ---------  --------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-12997-2.stderr b/src/test/ui/issues/issue-12997-2.stderr
index 3b89e8bc451..2a3d0e3457b 100644
--- a/src/test/ui/issues/issue-12997-2.stderr
+++ b/src/test/ui/issues/issue-12997-2.stderr
@@ -4,8 +4,16 @@ error[E0308]: mismatched types
 LL | #[bench]
    | -------- in this procedural macro expansion
 LL | fn bar(x: isize) { }
-   | ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&mut Bencher`
+   | ^^^^^^^^^^^^^^^^^^^^
+   | |
+   | expected `isize`, found `&mut Bencher`
+   | arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/issue-12997-2.rs:8:4
+   |
+LL | fn bar(x: isize) { }
+   |    ^^^ --------
    = note: this error originates in the attribute macro `bench` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-13359.stderr b/src/test/ui/issues/issue-13359.stderr
index 075c92e65de..db6283ea11f 100644
--- a/src/test/ui/issues/issue-13359.stderr
+++ b/src/test/ui/issues/issue-13359.stderr
@@ -2,23 +2,29 @@ error[E0308]: mismatched types
   --> $DIR/issue-13359.rs:6:9
    |
 LL |     foo(1*(1 as isize));
-   |         ^^^^^^^^^^^^^^ expected `i16`, found `isize`
+   |     --- ^^^^^^^^^^^^^^ expected `i16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
-help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit
+note: function defined here
+  --> $DIR/issue-13359.rs:1:4
    |
-LL |     foo((1*(1 as isize)).try_into().unwrap());
-   |         +              +++++++++++++++++++++
+LL | fn foo(_s: i16) { }
+   |    ^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/issue-13359.rs:10:9
    |
 LL |     bar(1*(1 as usize));
-   |         ^^^^^^^^^^^^^^ expected `u32`, found `usize`
+   |     --- ^^^^^^^^^^^^^^ expected `u32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
-help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
+note: function defined here
+  --> $DIR/issue-13359.rs:3:4
    |
-LL |     bar((1*(1 as usize)).try_into().unwrap());
-   |         +              +++++++++++++++++++++
+LL | fn bar(_s: u32) { }
+   |    ^^^ -------
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr
index 527e0225eb9..657bda5f62b 100644
--- a/src/test/ui/issues/issue-13853.stderr
+++ b/src/test/ui/issues/issue-13853.stderr
@@ -20,13 +20,19 @@ error[E0308]: mismatched types
   --> $DIR/issue-13853.rs:37:13
    |
 LL |     iterate(graph);
-   |             ^^^^^
-   |             |
-   |             expected reference, found struct `Vec`
-   |             help: consider borrowing here: `&graph`
+   |     ------- ^^^^^
+   |     |       |
+   |     |       expected reference, found struct `Vec`
+   |     |       help: consider borrowing here: `&graph`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `Vec<Stuff>`
+note: function defined here
+  --> $DIR/issue-13853.rs:26:4
+   |
+LL | fn iterate<N: Node, G: Graph<N>>(graph: &G) {
+   |    ^^^^^^^                       ---------
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-1448-2.stderr b/src/test/ui/issues/issue-1448-2.stderr
index da44566d075..203dd92c9fb 100644
--- a/src/test/ui/issues/issue-1448-2.stderr
+++ b/src/test/ui/issues/issue-1448-2.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/issue-1448-2.rs:6:24
    |
 LL |     println!("{}", foo(10i32));
-   |                        ^^^^^ expected `u32`, found `i32`
+   |                    --- ^^^^^ expected `u32`, found `i32`
+   |                    |
+   |                    arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/issue-1448-2.rs:3:4
+   |
+LL | fn foo(a: u32) -> u32 { a }
+   |    ^^^ ------
 help: change the type of the numeric literal from `i32` to `u32`
    |
 LL |     println!("{}", foo(10u32));
diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr
index 0b09751676e..660dfe9ed3d 100644
--- a/src/test/ui/issues/issue-15783.stderr
+++ b/src/test/ui/issues/issue-15783.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-15783.rs:8:19
    |
 LL |     let msg = foo(x);
-   |                   ^ expected slice `[&str]`, found array `[&str; 1]`
+   |               --- ^ expected slice `[&str]`, found array `[&str; 1]`
+   |               |
+   |               arguments to this function are incorrect
    |
    = note: expected enum `Option<&[&str]>`
               found enum `Option<&[&str; 1]>`
+note: function defined here
+  --> $DIR/issue-15783.rs:1:8
+   |
+LL | pub fn foo(params: Option<&[&str]>) -> usize {
+   |        ^^^ -----------------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-16939.stderr b/src/test/ui/issues/issue-16939.stderr
index 8e4237039fa..294524f0b61 100644
--- a/src/test/ui/issues/issue-16939.stderr
+++ b/src/test/ui/issues/issue-16939.stderr
@@ -2,15 +2,17 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/issue-16939.rs:5:9
    |
 LL |     |t| f(t);
-   |         ^ - supplied 1 argument
-   |         |
-   |         expected 0 arguments
+   |         ^ - argument unexpected
    |
 note: associated function defined here
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
 LL |     extern "rust-call" fn call(&self, args: Args) -> Self::Output;
    |                           ^^^^
+help: remove the extra argument
+   |
+LL |     |t| f();
+   |         ~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-17033.stderr b/src/test/ui/issues/issue-17033.stderr
index 518fc30142c..f26bee5ff45 100644
--- a/src/test/ui/issues/issue-17033.stderr
+++ b/src/test/ui/issues/issue-17033.stderr
@@ -2,10 +2,11 @@ error[E0308]: mismatched types
   --> $DIR/issue-17033.rs:2:10
    |
 LL |     (*p)(())
-   |          ^^
-   |          |
-   |          expected `&mut ()`, found `()`
-   |          help: consider mutably borrowing here: `&mut ()`
+   |     ---- ^^
+   |     |    |
+   |     |    expected `&mut ()`, found `()`
+   |     |    help: consider mutably borrowing here: `&mut ()`
+   |     arguments to this function are incorrect
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-18819.stderr b/src/test/ui/issues/issue-18819.stderr
index b10d26abe34..db228fded6e 100644
--- a/src/test/ui/issues/issue-18819.stderr
+++ b/src/test/ui/issues/issue-18819.stderr
@@ -2,15 +2,26 @@ error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/issue-18819.rs:16:5
    |
 LL |     print_x(X);
-   |     ^^^^^^^ - supplied 1 argument
-   |     |
-   |     expected 2 arguments
+   |     ^^^^^^^---
+   |            ||
+   |            |expected reference, found struct `X`
+   |            an argument of type `&str` is missing
    |
+   = note: expected reference `&dyn Foo<Item = bool>`
+                 found struct `X`
 note: function defined here
   --> $DIR/issue-18819.rs:11:4
    |
 LL | fn print_x(_: &dyn Foo<Item=bool>, extra: &str) {
    |    ^^^^^^^ ----------------------  -----------
+help: consider borrowing here
+   |
+LL |     print_x(&X);
+   |             ~~
+help: provide the argument
+   |
+LL |     print_x({&dyn Foo<Item = bool>}, {&str});
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24819.stderr b/src/test/ui/issues/issue-24819.stderr
index 2f931e59d59..982a11fef80 100644
--- a/src/test/ui/issues/issue-24819.stderr
+++ b/src/test/ui/issues/issue-24819.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-24819.rs:5:9
    |
 LL |     foo(&mut v);
-   |         ^^^^^^ expected struct `HashSet`, found struct `Vec`
+   |     --- ^^^^^^ expected struct `HashSet`, found struct `Vec`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut HashSet<u32>`
               found mutable reference `&mut Vec<_>`
+note: function defined here
+  --> $DIR/issue-24819.rs:10:4
+   |
+LL | fn foo(h: &mut HashSet<u32>) {
+   |    ^^^ --------------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-26094.rs b/src/test/ui/issues/issue-26094.rs
index 78fb0491d82..981c3abb4ba 100644
--- a/src/test/ui/issues/issue-26094.rs
+++ b/src/test/ui/issues/issue-26094.rs
@@ -1,6 +1,6 @@
 macro_rules! some_macro {
     ($other: expr) => ({
-        $other(None) //~ NOTE supplied 1 argument
+        $other(None) //~ NOTE argument unexpected
     })
 }
 
@@ -9,5 +9,5 @@ fn some_function() {} //~ NOTE defined here
 fn main() {
     some_macro!(some_function);
     //~^ ERROR this function takes 0 arguments but 1 argument was supplied
-    //~| NOTE expected 0 arguments
+    //~| NOTE in this expansion of some_macro!
 }
diff --git a/src/test/ui/issues/issue-26094.stderr b/src/test/ui/issues/issue-26094.stderr
index a6f1ac9286c..1013518e1da 100644
--- a/src/test/ui/issues/issue-26094.stderr
+++ b/src/test/ui/issues/issue-26094.stderr
@@ -2,16 +2,20 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/issue-26094.rs:10:17
    |
 LL |         $other(None)
-   |                ---- supplied 1 argument
+   |                ---- argument unexpected
 ...
 LL |     some_macro!(some_function);
-   |                 ^^^^^^^^^^^^^ expected 0 arguments
+   |                 ^^^^^^^^^^^^^
    |
 note: function defined here
   --> $DIR/issue-26094.rs:7:4
    |
 LL | fn some_function() {}
    |    ^^^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL |         some_function()
+   |         ~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-3044.rs b/src/test/ui/issues/issue-3044.rs
index 81d76a90eb0..7363cae8370 100644
--- a/src/test/ui/issues/issue-3044.rs
+++ b/src/test/ui/issues/issue-3044.rs
@@ -2,5 +2,6 @@ fn main() {
     let needlesArr: Vec<char> = vec!['a', 'f'];
     needlesArr.iter().fold(|x, y| {
     });
-    //~^^ ERROR this function takes 2 arguments but 1 argument was supplied
+    //~^^ ERROR mismatched types
+    //~| ERROR this function takes 2 arguments but 1 argument was supplied
 }
diff --git a/src/test/ui/issues/issue-3044.stderr b/src/test/ui/issues/issue-3044.stderr
index b93aeade95e..5bb07cfda21 100644
--- a/src/test/ui/issues/issue-3044.stderr
+++ b/src/test/ui/issues/issue-3044.stderr
@@ -1,19 +1,34 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-3044.rs:3:35
+   |
+LL |       needlesArr.iter().fold(|x, y| {
+   |  ___________________________________^
+LL | |     });
+   | |_____^ expected closure, found `()`
+   |
+   = note: expected closure `[closure@$DIR/issue-3044.rs:3:28: 4:6]`
+            found unit type `()`
+
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/issue-3044.rs:3:23
    |
 LL |       needlesArr.iter().fold(|x, y| {
-   |  _______________________^^^^_-
-   | |                       |
-   | |                       expected 2 arguments
+   |  _______________________^^^^-
 LL | |     });
-   | |_____- supplied 1 argument
+   | |______- an argument is missing
    |
 note: associated function defined here
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
    |
 LL |     fn fold<B, F>(mut self, init: B, mut f: F) -> B
    |        ^^^^
+help: provide the argument
+   |
+LL ~     needlesArr.iter().fold(|x, y| {
+LL ~     }, {_});
+   |
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0061`.
+Some errors have detailed explanations: E0061, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/src/test/ui/issues/issue-43420-no-over-suggest.stderr b/src/test/ui/issues/issue-43420-no-over-suggest.stderr
index 77d52f6ecab..58fd1121a6b 100644
--- a/src/test/ui/issues/issue-43420-no-over-suggest.stderr
+++ b/src/test/ui/issues/issue-43420-no-over-suggest.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-43420-no-over-suggest.rs:8:9
    |
 LL |     foo(&a);
-   |         ^^ expected slice `[u16]`, found struct `Vec`
+   |     --- ^^ expected slice `[u16]`, found struct `Vec`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&[u16]`
               found reference `&Vec<u8>`
+note: function defined here
+  --> $DIR/issue-43420-no-over-suggest.rs:4:4
+   |
+LL | fn foo(b: &[u16]) {}
+   |    ^^^ ---------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-4517.stderr b/src/test/ui/issues/issue-4517.stderr
index 1ae97b69c6c..70b4ca5ec49 100644
--- a/src/test/ui/issues/issue-4517.stderr
+++ b/src/test/ui/issues/issue-4517.stderr
@@ -2,7 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/issue-4517.rs:5:9
    |
 LL |     bar(foo);
-   |         ^^^ expected `usize`, found array `[u8; 4]`
+   |     --- ^^^ expected `usize`, found array `[u8; 4]`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/issue-4517.rs:1:4
+   |
+LL | fn bar(int_param: usize) {}
+   |    ^^^ ----------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
index 2d666e2b66c..e874ded8ec5 100644
--- a/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
+++ b/src/test/ui/issues/issue-46756-consider-borrowing-cast-or-binexpr.stderr
@@ -2,19 +2,33 @@ error[E0308]: mismatched types
   --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:12:42
    |
 LL |     light_flows_our_war_of_mocking_words(behold as usize);
-   |                                          ^^^^^^^^^^^^^^^
-   |                                          |
-   |                                          expected `&usize`, found `usize`
-   |                                          help: consider borrowing here: `&(behold as usize)`
+   |     ------------------------------------ ^^^^^^^^^^^^^^^
+   |     |                                    |
+   |     |                                    expected `&usize`, found `usize`
+   |     |                                    help: consider borrowing here: `&(behold as usize)`
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:5:4
+   |
+LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:14:42
    |
 LL |     light_flows_our_war_of_mocking_words(with_tears + 4);
-   |                                          ^^^^^^^^^^^^^^
-   |                                          |
-   |                                          expected `&usize`, found `usize`
-   |                                          help: consider borrowing here: `&(with_tears + 4)`
+   |     ------------------------------------ ^^^^^^^^^^^^^^
+   |     |                                    |
+   |     |                                    expected `&usize`, found `usize`
+   |     |                                    help: consider borrowing here: `&(with_tears + 4)`
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/issue-46756-consider-borrowing-cast-or-binexpr.rs:5:4
+   |
+LL | fn light_flows_our_war_of_mocking_words(and_yet: &usize) -> usize {
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-48364.stderr b/src/test/ui/issues/issue-48364.stderr
index 37a42d2382d..7fd36676df8 100644
--- a/src/test/ui/issues/issue-48364.stderr
+++ b/src/test/ui/issues/issue-48364.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-48364.rs:2:21
    |
 LL |     b"".starts_with(stringify!(foo))
-   |                     ^^^^^^^^^^^^^^^ expected slice `[u8]`, found `str`
+   |         ----------- ^^^^^^^^^^^^^^^ expected slice `[u8]`, found `str`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected reference `&[u8]`
               found reference `&'static str`
+note: associated function defined here
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
+   |
+LL |     pub fn starts_with(&self, needle: &[T]) -> bool
+   |            ^^^^^^^^^^^
    = note: this error originates in the macro `stringify` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-4935.stderr b/src/test/ui/issues/issue-4935.stderr
index 03b9b91edef..b4cebe2a68b 100644
--- a/src/test/ui/issues/issue-4935.stderr
+++ b/src/test/ui/issues/issue-4935.stderr
@@ -2,15 +2,17 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/issue-4935.rs:5:13
    |
 LL | fn main() { foo(5, 6) }
-   |             ^^^ -  - supplied 2 arguments
-   |             |
-   |             expected 1 argument
+   |             ^^^    - argument unexpected
    |
 note: function defined here
   --> $DIR/issue-4935.rs:3:4
    |
 LL | fn foo(a: usize) {}
    |    ^^^ --------
+help: remove the extra argument
+   |
+LL | fn main() { foo(5) }
+   |             ~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-51154.stderr b/src/test/ui/issues/issue-51154.stderr
index 3c3428f3096..f2cbc3e6feb 100644
--- a/src/test/ui/issues/issue-51154.stderr
+++ b/src/test/ui/issues/issue-51154.stderr
@@ -4,11 +4,18 @@ error[E0308]: mismatched types
 LL | fn foo<F: FnMut()>() {
    |        - this type parameter
 LL |     let _: Box<F> = Box::new(|| ());
-   |                              ^^^^^ expected type parameter `F`, found closure
+   |                     -------- ^^^^^ expected type parameter `F`, found closure
+   |                     |
+   |                     arguments to this function are incorrect
    |
    = note: expected type parameter `F`
                      found closure `[closure@$DIR/issue-51154.rs:2:30: 2:35]`
    = help: every closure has a distinct type and so could not always match the caller-chosen type of parameter `F`
+note: associated function defined here
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   |
+LL |     pub fn new(x: T) -> Self {
+   |            ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-5216.stderr b/src/test/ui/issues/issue-5216.stderr
index 29c95e4fb62..1afff28f0b4 100644
--- a/src/test/ui/issues/issue-5216.stderr
+++ b/src/test/ui/issues/issue-5216.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-5216.rs:3:21
    |
 LL | pub static C: S = S(f);
-   |                     ^ expected struct `Box`, found fn item
+   |                   - ^ expected struct `Box`, found fn item
+   |                   |
+   |                   arguments to this struct are incorrect
    |
    = note: expected struct `Box<(dyn FnMut() + Sync + 'static)>`
              found fn item `fn() {f}`
+note: tuple struct defined here
+  --> $DIR/issue-5216.rs:2:8
+   |
+LL | struct S(Box<dyn FnMut() + Sync>);
+   |        ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-5216.rs:8:19
diff --git a/src/test/ui/issues/issue-61106.stderr b/src/test/ui/issues/issue-61106.stderr
index 2d841d28ee2..2bc09234116 100644
--- a/src/test/ui/issues/issue-61106.stderr
+++ b/src/test/ui/issues/issue-61106.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-61106.rs:3:9
    |
 LL |     foo(x.clone());
-   |         ^^^^^^^^^
-   |         |
-   |         expected `&str`, found struct `String`
-   |         help: consider borrowing here: `&x`
+   |     --- ^^^^^^^^^
+   |     |   |
+   |     |   expected `&str`, found struct `String`
+   |     |   help: consider borrowing here: `&x`
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/issue-61106.rs:6:4
+   |
+LL | fn foo(_: &str) {}
+   |    ^^^ -------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-69306.stderr b/src/test/ui/issues/issue-69306.stderr
index 58e85ec700d..61ec5d3180c 100644
--- a/src/test/ui/issues/issue-69306.stderr
+++ b/src/test/ui/issues/issue-69306.stderr
@@ -4,10 +4,17 @@ error[E0308]: mismatched types
 LL | impl<T> S0<T> {
    |      - this type parameter
 LL |     const C: S0<u8> = Self(0);
-   |                            ^ expected type parameter `T`, found integer
+   |                       ---- ^ expected type parameter `T`, found integer
+   |                       |
+   |                       arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                         found type `{integer}`
+note: tuple struct defined here
+  --> $DIR/issue-69306.rs:3:8
+   |
+LL | struct S0<T>(T);
+   |        ^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-69306.rs:5:23
@@ -27,10 +34,17 @@ LL | impl<T> S0<T> {
    |      - this type parameter
 ...
 LL |         Self(0);
-   |              ^ expected type parameter `T`, found integer
+   |         ---- ^ expected type parameter `T`, found integer
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                         found type `{integer}`
+note: tuple struct defined here
+  --> $DIR/issue-69306.rs:3:8
+   |
+LL | struct S0<T>(T);
+   |        ^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-69306.rs:27:14
@@ -39,10 +53,17 @@ LL | impl<T> Foo<T> for <S0<T> as Fun>::Out {
    |      - this type parameter
 LL |     fn foo() {
 LL |         Self(0);
-   |              ^ expected type parameter `T`, found integer
+   |         ---- ^ expected type parameter `T`, found integer
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                         found type `{integer}`
+note: tuple struct defined here
+  --> $DIR/issue-69306.rs:3:8
+   |
+LL | struct S0<T>(T);
+   |        ^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-69306.rs:33:32
@@ -50,10 +71,17 @@ error[E0308]: mismatched types
 LL | impl<T> S1<T, u8> {
    |      - this type parameter
 LL |     const C: S1<u8, u8> = Self(0, 1);
-   |                                ^ expected type parameter `T`, found integer
+   |                           ---- ^ expected type parameter `T`, found integer
+   |                           |
+   |                           arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                         found type `{integer}`
+note: tuple struct defined here
+  --> $DIR/issue-69306.rs:31:8
+   |
+LL | struct S1<T, U>(T, U);
+   |        ^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-69306.rs:33:27
@@ -74,12 +102,19 @@ LL | impl<T> S2<T> {
 LL |     fn map<U>(x: U) -> S2<U> {
    |            - found type parameter
 LL |         Self(x)
-   |              ^ expected type parameter `T`, found type parameter `U`
+   |         ---- ^ expected type parameter `T`, found type parameter `U`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `T`
               found type parameter `U`
    = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
    = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
+note: tuple struct defined here
+  --> $DIR/issue-69306.rs:38:8
+   |
+LL | struct S2<T>(T);
+   |        ^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-69306.rs:41:9
diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr
index 53c9380fb7e..ed5dd2ec011 100644
--- a/src/test/ui/lint/unaligned_references.stderr
+++ b/src/test/ui/lint/unaligned_references.stderr
@@ -82,3 +82,122 @@ LL |         let _ = &packed2.x;
 
 error: aborting due to 7 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:22:17
+   |
+LL |         let _ = &good.ptr;
+   |                 ^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:24:17
+   |
+LL |         let _ = &good.data;
+   |                 ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:27:17
+   |
+LL |         let _ = &good.data as *const _;
+   |                 ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:29:27
+   |
+LL |         let _: *const _ = &good.data;
+   |                           ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:32:17
+   |
+LL |         let _ = good.data.clone();
+   |                 ^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:35:17
+   |
+LL |         let _ = &good.data2[0];
+   |                 ^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references.rs:45:17
+   |
+LL |         let _ = &packed2.x;
+   |                 ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references.rs:1:9
+   |
+LL | #![deny(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
diff --git a/src/test/ui/lint/unaligned_references_external_macro.stderr b/src/test/ui/lint/unaligned_references_external_macro.stderr
index 01e2395049d..1262c21ee78 100644
--- a/src/test/ui/lint/unaligned_references_external_macro.stderr
+++ b/src/test/ui/lint/unaligned_references_external_macro.stderr
@@ -29,3 +29,33 @@ LL | | }
 
 error: aborting due to previous error
 
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/unaligned_references_external_macro.rs:5:1
+   |
+LL | / unaligned_references_external_crate::mac! {
+LL | |
+LL | |     #[repr(packed)]
+LL | |     pub struct X {
+LL | |         pub field: u16
+LL | |     }
+LL | | }
+   | |_^
+   |
+note: the lint level is defined here
+  --> $DIR/unaligned_references_external_macro.rs:5:1
+   |
+LL | / unaligned_references_external_crate::mac! {
+LL | |
+LL | |     #[repr(packed)]
+LL | |     pub struct X {
+LL | |         pub field: u16
+LL | |     }
+LL | | }
+   | |_^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+   = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
diff --git a/src/test/ui/macros/issue-29084.stderr b/src/test/ui/macros/issue-29084.stderr
index a973e23e29e..f83e192130b 100644
--- a/src/test/ui/macros/issue-29084.stderr
+++ b/src/test/ui/macros/issue-29084.stderr
@@ -2,11 +2,21 @@ error[E0308]: mismatched types
   --> $DIR/issue-29084.rs:4:13
    |
 LL |         bar(&mut $d);
-   |             ^^^^^^^ expected `u8`, found `&mut u8`
+   |         --- ^^^^^^^ expected `u8`, found `&mut u8`
+   |         |
+   |         arguments to this function are incorrect
 ...
 LL |     foo!(0u8);
    |     --------- in this macro invocation
    |
+note: function defined here
+  --> $DIR/issue-29084.rs:3:12
+   |
+LL |         fn bar(d: u8) { }
+   |            ^^^ -----
+...
+LL |     foo!(0u8);
+   |     --------- in this macro invocation
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs
index 98f64aa6f80..e7a01f105de 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.rs
+++ b/src/test/ui/macros/macros-nonfatal-errors.rs
@@ -5,7 +5,6 @@
 
 #![feature(trace_macros, concat_idents)]
 #![feature(stmt_expr_attributes, arbitrary_enum_discriminant)]
-#![feature(derive_default_enum)]
 
 use std::arch::asm;
 
diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr
index 79e8db9c1d4..b3c6d07f967 100644
--- a/src/test/ui/macros/macros-nonfatal-errors.stderr
+++ b/src/test/ui/macros/macros-nonfatal-errors.stderr
@@ -1,41 +1,41 @@
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:14:5
+  --> $DIR/macros-nonfatal-errors.rs:13:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:19:36
+  --> $DIR/macros-nonfatal-errors.rs:18:36
    |
 LL | struct DefaultInnerAttrTupleStruct(#[default] ());
    |                                    ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:23:1
+  --> $DIR/macros-nonfatal-errors.rs:22:1
    |
 LL | #[default]
    | ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:27:1
+  --> $DIR/macros-nonfatal-errors.rs:26:1
    |
 LL | #[default]
    | ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:37:11
+  --> $DIR/macros-nonfatal-errors.rs:36:11
    |
 LL |     Foo = #[default] 0,
    |           ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:38:14
+  --> $DIR/macros-nonfatal-errors.rs:37:14
    |
 LL |     Bar([u8; #[default] 1]),
    |              ^^^^^^^^^^
 
 error: no default declared
-  --> $DIR/macros-nonfatal-errors.rs:43:10
+  --> $DIR/macros-nonfatal-errors.rs:42:10
    |
 LL | #[derive(Default)]
    |          ^^^^^^^
@@ -44,7 +44,7 @@ LL | #[derive(Default)]
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: multiple declared defaults
-  --> $DIR/macros-nonfatal-errors.rs:49:10
+  --> $DIR/macros-nonfatal-errors.rs:48:10
    |
 LL | #[derive(Default)]
    |          ^^^^^^^
@@ -62,7 +62,7 @@ LL |     Baz,
    = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `#[default]` attribute does not accept a value
-  --> $DIR/macros-nonfatal-errors.rs:61:5
+  --> $DIR/macros-nonfatal-errors.rs:60:5
    |
 LL |     #[default = 1]
    |     ^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     #[default = 1]
    = help: try using `#[default]`
 
 error: multiple `#[default]` attributes
-  --> $DIR/macros-nonfatal-errors.rs:69:5
+  --> $DIR/macros-nonfatal-errors.rs:68:5
    |
 LL |     #[default]
    |     ---------- `#[default]` used here
@@ -81,13 +81,13 @@ LL |     Foo,
    |
    = note: only one `#[default]` attribute is needed
 help: try removing this
-  --> $DIR/macros-nonfatal-errors.rs:68:5
+  --> $DIR/macros-nonfatal-errors.rs:67:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
 
 error: multiple `#[default]` attributes
-  --> $DIR/macros-nonfatal-errors.rs:79:5
+  --> $DIR/macros-nonfatal-errors.rs:78:5
    |
 LL |     #[default]
    |     ---------- `#[default]` used here
@@ -99,7 +99,7 @@ LL |     Foo,
    |
    = note: only one `#[default]` attribute is needed
 help: try removing these
-  --> $DIR/macros-nonfatal-errors.rs:76:5
+  --> $DIR/macros-nonfatal-errors.rs:75:5
    |
 LL |     #[default]
    |     ^^^^^^^^^^
@@ -109,7 +109,7 @@ LL |     #[default]
    |     ^^^^^^^^^^
 
 error: the `#[default]` attribute may only be used on unit enum variants
-  --> $DIR/macros-nonfatal-errors.rs:86:5
+  --> $DIR/macros-nonfatal-errors.rs:85:5
    |
 LL |     Foo {},
    |     ^^^
@@ -117,7 +117,7 @@ LL |     Foo {},
    = help: consider a manual implementation of `Default`
 
 error: default variant must be exhaustive
-  --> $DIR/macros-nonfatal-errors.rs:94:5
+  --> $DIR/macros-nonfatal-errors.rs:93:5
    |
 LL |     #[non_exhaustive]
    |     ----------------- declared `#[non_exhaustive]` here
@@ -127,37 +127,37 @@ LL |     Foo,
    = help: consider a manual implementation of `Default`
 
 error: asm template must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:99:10
+  --> $DIR/macros-nonfatal-errors.rs:98:10
    |
 LL |     asm!(invalid);
    |          ^^^^^^^
 
 error: concat_idents! requires ident args
-  --> $DIR/macros-nonfatal-errors.rs:102:5
+  --> $DIR/macros-nonfatal-errors.rs:101:5
    |
 LL |     concat_idents!("not", "idents");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:104:17
+  --> $DIR/macros-nonfatal-errors.rs:103:17
    |
 LL |     option_env!(invalid);
    |                 ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:105:10
+  --> $DIR/macros-nonfatal-errors.rs:104:10
    |
 LL |     env!(invalid);
    |          ^^^^^^^
 
 error: expected string literal
-  --> $DIR/macros-nonfatal-errors.rs:106:10
+  --> $DIR/macros-nonfatal-errors.rs:105:10
    |
 LL |     env!(foo, abr, baz);
    |          ^^^
 
 error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
-  --> $DIR/macros-nonfatal-errors.rs:107:5
+  --> $DIR/macros-nonfatal-errors.rs:106:5
    |
 LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |     env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST");
    = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: format argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:109:13
+  --> $DIR/macros-nonfatal-errors.rs:108:13
    |
 LL |     format!(invalid);
    |             ^^^^^^^
@@ -176,19 +176,19 @@ LL |     format!("{}", invalid);
    |             +++++
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:111:14
+  --> $DIR/macros-nonfatal-errors.rs:110:14
    |
 LL |     include!(invalid);
    |              ^^^^^^^
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:113:18
+  --> $DIR/macros-nonfatal-errors.rs:112:18
    |
 LL |     include_str!(invalid);
    |                  ^^^^^^^
 
 error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:114:5
+  --> $DIR/macros-nonfatal-errors.rs:113:5
    |
 LL |     include_str!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,13 +196,13 @@ LL |     include_str!("i'd be quite surprised if a file with this name existed")
    = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: argument must be a string literal
-  --> $DIR/macros-nonfatal-errors.rs:115:20
+  --> $DIR/macros-nonfatal-errors.rs:114:20
    |
 LL |     include_bytes!(invalid);
    |                    ^^^^^^^
 
 error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: $FILE_NOT_FOUND_MSG (os error 2)
-  --> $DIR/macros-nonfatal-errors.rs:116:5
+  --> $DIR/macros-nonfatal-errors.rs:115:5
    |
 LL |     include_bytes!("i'd be quite surprised if a file with this name existed");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,13 +210,13 @@ LL |     include_bytes!("i'd be quite surprised if a file with this name existed
    = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: trace_macros! accepts only `true` or `false`
-  --> $DIR/macros-nonfatal-errors.rs:118:5
+  --> $DIR/macros-nonfatal-errors.rs:117:5
    |
 LL |     trace_macros!(invalid);
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find macro `llvm_asm` in this scope
-  --> $DIR/macros-nonfatal-errors.rs:100:5
+  --> $DIR/macros-nonfatal-errors.rs:99:5
    |
 LL |     llvm_asm!(invalid);
    |     ^^^^^^^^
diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr
index c410e076dde..53e582f7f13 100644
--- a/src/test/ui/methods/method-call-err-msg.stderr
+++ b/src/test/ui/methods/method-call-err-msg.stderr
@@ -2,43 +2,49 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/method-call-err-msg.rs:13:7
    |
 LL |     x.zero(0)
-   |       ^^^^ - supplied 1 argument
-   |       |
-   |       expected 0 arguments
+   |       ^^^^ - argument unexpected
    |
 note: associated function defined here
   --> $DIR/method-call-err-msg.rs:5:8
    |
 LL |     fn zero(self) -> Foo { self }
    |        ^^^^ ----
+help: remove the extra argument
+   |
+LL |     x.zero()
+   |       ~~~~~~
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/method-call-err-msg.rs:14:7
    |
 LL |      .one()
-   |       ^^^- supplied 0 arguments
-   |       |
-   |       expected 1 argument
+   |       ^^^-- an argument of type `isize` is missing
    |
 note: associated function defined here
   --> $DIR/method-call-err-msg.rs:6:8
    |
 LL |     fn one(self, _: isize) -> Foo { self }
    |        ^^^ ----  --------
+help: provide the argument
+   |
+LL |      .one({isize})
+   |       ~~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/method-call-err-msg.rs:15:7
    |
 LL |      .two(0);
-   |       ^^^ - supplied 1 argument
-   |       |
-   |       expected 2 arguments
+   |       ^^^--- an argument of type `isize` is missing
    |
 note: associated function defined here
   --> $DIR/method-call-err-msg.rs:7:8
    |
 LL |     fn two(self, _: isize, _: isize) -> Foo { self }
    |        ^^^ ----  --------  --------
+help: provide the argument
+   |
+LL |      .two(0, {isize});
+   |       ~~~~~~~~~~~~~~~
 
 error[E0599]: `Foo` is not an iterator
   --> $DIR/method-call-err-msg.rs:19:7
@@ -74,15 +80,17 @@ error[E0061]: this function takes 3 arguments but 0 arguments were supplied
   --> $DIR/method-call-err-msg.rs:21:7
    |
 LL |     y.three::<usize>();
-   |       ^^^^^--------- supplied 0 arguments
-   |       |
-   |       expected 3 arguments
+   |       ^^^^^^^^^^^^^^-- three arguments of type `usize`, `usize`, and `usize` are missing
    |
 note: associated function defined here
   --> $DIR/method-call-err-msg.rs:8:8
    |
 LL |     fn three<T>(self, _: T, _: T, _: T) -> Foo { self }
    |        ^^^^^    ----  ----  ----  ----
+help: provide the arguments
+   |
+LL |     y.three::<usize>({usize}, {usize}, {usize});
+   |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/methods/method-self-arg-1.stderr b/src/test/ui/methods/method-self-arg-1.stderr
index 17ea61fc4bd..01fec6fcaae 100644
--- a/src/test/ui/methods/method-self-arg-1.stderr
+++ b/src/test/ui/methods/method-self-arg-1.stderr
@@ -2,19 +2,33 @@ error[E0308]: mismatched types
   --> $DIR/method-self-arg-1.rs:11:14
    |
 LL |     Foo::bar(x);
-   |              ^
-   |              |
-   |              expected `&Foo`, found struct `Foo`
-   |              help: consider borrowing here: `&x`
+   |     -------- ^
+   |     |        |
+   |     |        expected `&Foo`, found struct `Foo`
+   |     |        help: consider borrowing here: `&x`
+   |     arguments to this function are incorrect
+   |
+note: associated function defined here
+  --> $DIR/method-self-arg-1.rs:6:8
+   |
+LL |     fn bar(&self) {}
+   |        ^^^ -----
 
 error[E0308]: mismatched types
   --> $DIR/method-self-arg-1.rs:13:14
    |
 LL |     Foo::bar(&42);
-   |              ^^^ expected struct `Foo`, found integer
+   |     -------- ^^^ expected struct `Foo`, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo`
               found reference `&{integer}`
+note: associated function defined here
+  --> $DIR/method-self-arg-1.rs:6:8
+   |
+LL |     fn bar(&self) {}
+   |        ^^^ -----
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs
new file mode 100644
index 00000000000..d2bbb4f1101
--- /dev/null
+++ b/src/test/ui/mir/issue-92893.rs
@@ -0,0 +1,7 @@
+struct Bug<A = [(); (let a = (), 1).1]> {
+    //~^ `let` expressions are not supported here
+    //~^^ `let` expressions in this position are unstable [E0658]
+    a: A
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr
new file mode 100644
index 00000000000..063b5d66feb
--- /dev/null
+++ b/src/test/ui/mir/issue-92893.stderr
@@ -0,0 +1,20 @@
+error: `let` expressions are not supported here
+  --> $DIR/issue-92893.rs:1:22
+   |
+LL | struct Bug<A = [(); (let a = (), 1).1]> {
+   |                      ^^^^^^^^^^
+   |
+   = note: only supported directly in conditions of `if` and `while` expressions
+
+error[E0658]: `let` expressions in this position are unstable
+  --> $DIR/issue-92893.rs:1:22
+   |
+LL | struct Bug<A = [(); (let a = (), 1).1]> {
+   |                      ^^^^^^^^^^
+   |
+   = note: see issue #53667 <https://github.com/rust-lang/rust/issues/53667> for more information
+   = help: add `#![feature(let_chains)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs b/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs
new file mode 100644
index 00000000000..cd6c5bf2719
--- /dev/null
+++ b/src/test/ui/mir/issue-95978-validator-lifetime-comparison.rs
@@ -0,0 +1,10 @@
+// check-pass
+// compile-flags: -Zvalidate-mir
+
+fn foo(_a: &str) {}
+
+fn main() {
+    let x = foo as fn(&'static str);
+
+    let _ = x == foo;
+}
diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr
index da8a976daaf..579a5b7ecb9 100644
--- a/src/test/ui/mismatched_types/issue-26480.stderr
+++ b/src/test/ui/mismatched_types/issue-26480.stderr
@@ -1,17 +1,20 @@
 error[E0308]: mismatched types
   --> $DIR/issue-26480.rs:16:19
    |
+LL |             write(stdout, $arr.as_ptr() as *const i8,
+   |             ----- arguments to this function are incorrect
 LL |                   $arr.len() * size_of($arr[0]));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `usize`
 ...
 LL |     write!(hello);
    |     ------------- in this macro invocation
    |
-   = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit
+note: function defined here
+  --> $DIR/issue-26480.rs:2:8
    |
-LL |                   ($arr.len() * size_of($arr[0])).try_into().unwrap());
-   |                   +                             +++++++++++++++++++++
+LL |     fn write(fildes: i32, buf: *const i8, nbyte: u64) -> i64;
+   |        ^^^^^
+   = note: this error originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0605]: non-primitive cast: `{integer}` as `()`
   --> $DIR/issue-26480.rs:22:19
diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr
index 9f4e4398984..f0dea75001c 100644
--- a/src/test/ui/mismatched_types/issue-35030.stderr
+++ b/src/test/ui/mismatched_types/issue-35030.stderr
@@ -5,7 +5,9 @@ LL | impl<bool> Parser<bool> for bool {
    |      ---- this type parameter
 LL |     fn parse(text: &str) -> Option<bool> {
 LL |         Some(true)
-   |              ^^^^ expected type parameter `bool`, found `bool`
+   |         ---- ^^^^ expected type parameter `bool`, found `bool`
+   |         |
+   |         arguments to this enum variant are incorrect
    |
    = note: expected type parameter `bool` (type parameter `bool`)
                         found type `bool` (`bool`)
diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.stderr b/src/test/ui/mismatched_types/numeric-literal-cast.stderr
index 55e45a8f162..fcf3eccbcba 100644
--- a/src/test/ui/mismatched_types/numeric-literal-cast.stderr
+++ b/src/test/ui/mismatched_types/numeric-literal-cast.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-literal-cast.rs:6:9
    |
 LL |     foo(1u8);
-   |         ^^^ expected `u16`, found `u8`
+   |     --- ^^^ expected `u16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-literal-cast.rs:1:4
+   |
+LL | fn foo(_: u16) {}
+   |    ^^^ ------
 help: change the type of the numeric literal from `u8` to `u16`
    |
 LL |     foo(1u16);
@@ -13,8 +20,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-literal-cast.rs:8:10
    |
 LL |     foo1(2f32);
-   |          ^^^^ expected `f64`, found `f32`
+   |     ---- ^^^^ expected `f64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-literal-cast.rs:2:4
    |
+LL | fn foo1(_: f64) {}
+   |    ^^^^ ------
 help: change the type of the numeric literal from `f32` to `f64`
    |
 LL |     foo1(2f64);
@@ -24,8 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-literal-cast.rs:10:10
    |
 LL |     foo2(3i16);
-   |          ^^^^ expected `i32`, found `i16`
+   |     ---- ^^^^ expected `i32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-literal-cast.rs:3:4
    |
+LL | fn foo2(_: i32) {}
+   |    ^^^^ ------
 help: change the type of the numeric literal from `i16` to `i32`
    |
 LL |     foo2(3i32);
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.rs b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
index d62625faaaa..902a6ec81d6 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.rs
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.rs
@@ -30,5 +30,4 @@ fn main() {
     //~^ ERROR this function takes 1 argument but 0 arguments were supplied
     let ans = s("burma", "shave");
     //~^ ERROR this function takes 1 argument but 2 arguments were supplied
-    //~| ERROR mismatched types
 }
diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
index 9ae9c474162..a5742d6fe8c 100644
--- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
+++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr
@@ -2,43 +2,51 @@ error[E0308]: mismatched types
   --> $DIR/overloaded-calls-bad.rs:28:17
    |
 LL |     let ans = s("what");
-   |                 ^^^^^^ expected `isize`, found `&str`
+   |               - ^^^^^^ expected `isize`, found `&str`
+   |               |
+   |               arguments to this function are incorrect
+   |
+note: associated function defined here
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+   |                           ^^^^^^^^
 
 error[E0057]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/overloaded-calls-bad.rs:29:15
    |
 LL |     let ans = s();
-   |               ^-- supplied 0 arguments
-   |               |
-   |               expected 1 argument
+   |               ^-- an argument of type `isize` is missing
    |
 note: associated function defined here
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
 LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
    |                           ^^^^^^^^
-
-error[E0308]: mismatched types
-  --> $DIR/overloaded-calls-bad.rs:31:17
+help: provide the argument
    |
-LL |     let ans = s("burma", "shave");
-   |                 ^^^^^^^ expected `isize`, found `&str`
+LL |     let ans = s({isize});
+   |               ~~~~~~~~~~
 
 error[E0057]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/overloaded-calls-bad.rs:31:15
    |
 LL |     let ans = s("burma", "shave");
-   |               ^ -------  ------- supplied 2 arguments
-   |               |
-   |               expected 1 argument
+   |               ^ -------  ------- argument unexpected
+   |                 |
+   |                 expected `isize`, found `&str`
    |
 note: associated function defined here
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
    |
 LL |     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
    |                           ^^^^^^^^
+help: remove the extra argument
+   |
+LL |     let ans = s({isize});
+   |               ~~~~~~~~~~
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0057, E0308.
 For more information about an error, try `rustc --explain E0057`.
diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
index 485fae6d4d9..80aef7fcbe8 100644
--- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
+++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-bounds-cant-coerce.rs:13:7
    |
 LL |     a(x);
-   |       ^ expected trait `Foo + Send`, found trait `Foo`
+   |     - ^ expected trait `Foo + Send`, found trait `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Box<(dyn Foo + Send + 'static)>`
               found struct `Box<(dyn Foo + 'static)>`
+note: function defined here
+  --> $DIR/trait-bounds-cant-coerce.rs:5:4
+   |
+LL | fn a(_x: Box<dyn Foo + Send>) {
+   |    ^ -----------------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mut/mut-cross-borrowing.stderr b/src/test/ui/mut/mut-cross-borrowing.stderr
index b77813f8af0..ee739d6286a 100644
--- a/src/test/ui/mut/mut-cross-borrowing.stderr
+++ b/src/test/ui/mut/mut-cross-borrowing.stderr
@@ -2,13 +2,19 @@ error[E0308]: mismatched types
   --> $DIR/mut-cross-borrowing.rs:7:7
    |
 LL |     f(x)
-   |       ^
-   |       |
-   |       expected `&mut isize`, found struct `Box`
-   |       help: consider mutably borrowing here: `&mut x`
+   |     - ^
+   |     | |
+   |     | expected `&mut isize`, found struct `Box`
+   |     | help: consider mutably borrowing here: `&mut x`
+   |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut isize`
                          found struct `Box<{integer}>`
+note: function defined here
+  --> $DIR/mut-cross-borrowing.rs:1:4
+   |
+LL | fn f(_: &mut isize) {}
+   |    ^ -------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr b/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr
index eacef1dc330..fa3db33c960 100644
--- a/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr
+++ b/src/test/ui/never_type/call-fn-never-arg-wrong-type.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/call-fn-never-arg-wrong-type.rs:10:9
    |
 LL |     foo("wow");
-   |         ^^^^^ expected `!`, found `&str`
+   |     --- ^^^^^ expected `!`, found `&str`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:   expected type `!`
            found reference `&'static str`
+note: function defined here
+  --> $DIR/call-fn-never-arg-wrong-type.rs:5:4
+   |
+LL | fn foo(x: !) -> ! {
+   |    ^^^ ----
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/not-enough-arguments.stderr b/src/test/ui/not-enough-arguments.stderr
index df957837241..4f502acc95c 100644
--- a/src/test/ui/not-enough-arguments.stderr
+++ b/src/test/ui/not-enough-arguments.stderr
@@ -2,23 +2,23 @@ error[E0061]: this function takes 4 arguments but 3 arguments were supplied
   --> $DIR/not-enough-arguments.rs:27:3
    |
 LL |   foo(1, 2, 3);
-   |   ^^^ -  -  - supplied 3 arguments
-   |   |
-   |   expected 4 arguments
+   |   ^^^--------- an argument of type `isize` is missing
    |
 note: function defined here
   --> $DIR/not-enough-arguments.rs:5:4
    |
 LL | fn foo(a: isize, b: isize, c: isize, d:isize) {
    |    ^^^ --------  --------  --------  -------
+help: provide the argument
+   |
+LL |   foo(1, 2, 3, {isize});
+   |   ~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 6 arguments but 3 arguments were supplied
   --> $DIR/not-enough-arguments.rs:29:3
    |
 LL |   bar(1, 2, 3);
-   |   ^^^ -  -  - supplied 3 arguments
-   |   |
-   |   expected 6 arguments
+   |   ^^^--------- three arguments of type `i32`, `i32`, and `i32` are missing
    |
 note: function defined here
   --> $DIR/not-enough-arguments.rs:10:4
@@ -37,6 +37,10 @@ LL |     e: i32,
    |     ------
 LL |     f: i32,
    |     ------
+help: provide the arguments
+   |
+LL |   bar(1, 2, 3, {i32}, {i32}, {i32});
+   |   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/numeric/integer-literal-suffix-inference.stderr b/src/test/ui/numeric/integer-literal-suffix-inference.stderr
index 4c29c4a1cb0..5045f584c89 100644
--- a/src/test/ui/numeric/integer-literal-suffix-inference.stderr
+++ b/src/test/ui/numeric/integer-literal-suffix-inference.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:38:11
    |
 LL |     id_i8(a16);
-   |           ^^^ expected `i8`, found `i16`
+   |     ----- ^^^ expected `i8`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
+   |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `i16` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(a16.try_into().unwrap());
@@ -13,8 +20,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:41:11
    |
 LL |     id_i8(a32);
-   |           ^^^ expected `i8`, found `i32`
+   |     ----- ^^^ expected `i8`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
    |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `i32` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(a32.try_into().unwrap());
@@ -24,8 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:44:11
    |
 LL |     id_i8(a64);
-   |           ^^^ expected `i8`, found `i64`
+   |     ----- ^^^ expected `i8`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
+   |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `i64` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(a64.try_into().unwrap());
@@ -35,8 +56,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:47:11
    |
 LL |     id_i8(asize);
-   |           ^^^^^ expected `i8`, found `isize`
+   |     ----- ^^^^^ expected `i8`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
    |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `isize` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(asize.try_into().unwrap());
@@ -46,8 +74,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:51:12
    |
 LL |     id_i16(a8);
-   |            ^^ expected `i16`, found `i8`
+   |     ------ ^^ expected `i16`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
+   |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i8` to an `i16`
    |
 LL |     id_i16(a8.into());
@@ -57,8 +92,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:55:12
    |
 LL |     id_i16(a32);
-   |            ^^^ expected `i16`, found `i32`
+   |     ------ ^^^ expected `i16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
    |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i32` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     id_i16(a32.try_into().unwrap());
@@ -68,8 +110,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:58:12
    |
 LL |     id_i16(a64);
-   |            ^^^ expected `i16`, found `i64`
+   |     ------ ^^^ expected `i16`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
    |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i64` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     id_i16(a64.try_into().unwrap());
@@ -79,8 +128,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:61:12
    |
 LL |     id_i16(asize);
-   |            ^^^^^ expected `i16`, found `isize`
+   |     ------ ^^^^^ expected `i16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
+   |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     id_i16(asize.try_into().unwrap());
@@ -90,8 +146,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:65:12
    |
 LL |     id_i32(a8);
-   |            ^^ expected `i32`, found `i8`
+   |     ------ ^^ expected `i32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
    |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i8` to an `i32`
    |
 LL |     id_i32(a8.into());
@@ -101,8 +164,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:68:12
    |
 LL |     id_i32(a16);
-   |            ^^^ expected `i32`, found `i16`
+   |     ------ ^^^ expected `i32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
    |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i16` to an `i32`
    |
 LL |     id_i32(a16.into());
@@ -112,8 +182,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:72:12
    |
 LL |     id_i32(a64);
-   |            ^^^ expected `i32`, found `i64`
+   |     ------ ^^^ expected `i32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
+   |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     id_i32(a64.try_into().unwrap());
@@ -123,8 +200,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:75:12
    |
 LL |     id_i32(asize);
-   |            ^^^^^ expected `i32`, found `isize`
+   |     ------ ^^^^^ expected `i32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
    |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `isize` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     id_i32(asize.try_into().unwrap());
@@ -134,8 +218,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:79:12
    |
 LL |     id_i64(a8);
-   |            ^^ expected `i64`, found `i8`
+   |     ------ ^^ expected `i64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
    |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i8` to an `i64`
    |
 LL |     id_i64(a8.into());
@@ -145,8 +236,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:82:12
    |
 LL |     id_i64(a16);
-   |            ^^^ expected `i64`, found `i16`
+   |     ------ ^^^ expected `i64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
+   |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i16` to an `i64`
    |
 LL |     id_i64(a16.into());
@@ -156,8 +254,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:85:12
    |
 LL |     id_i64(a32);
-   |            ^^^ expected `i64`, found `i32`
+   |     ------ ^^^ expected `i64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
    |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i32` to an `i64`
    |
 LL |     id_i64(a32.into());
@@ -167,8 +272,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:89:12
    |
 LL |     id_i64(asize);
-   |            ^^^^^ expected `i64`, found `isize`
+   |     ------ ^^^^^ expected `i64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
+   |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `isize` to an `i64` and panic if the converted value doesn't fit
    |
 LL |     id_i64(asize.try_into().unwrap());
@@ -178,8 +290,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:93:14
    |
 LL |     id_isize(a8);
-   |              ^^ expected `isize`, found `i8`
+   |     -------- ^^ expected `isize`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:19:8
    |
+LL |     fn id_isize(n: isize) -> isize { n }
+   |        ^^^^^^^^ --------
 help: you can convert an `i8` to an `isize`
    |
 LL |     id_isize(a8.into());
@@ -189,8 +308,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:96:14
    |
 LL |     id_isize(a16);
-   |              ^^^ expected `isize`, found `i16`
+   |     -------- ^^^ expected `isize`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:19:8
+   |
+LL |     fn id_isize(n: isize) -> isize { n }
+   |        ^^^^^^^^ --------
 help: you can convert an `i16` to an `isize`
    |
 LL |     id_isize(a16.into());
@@ -200,8 +326,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:99:14
    |
 LL |     id_isize(a32);
-   |              ^^^ expected `isize`, found `i32`
+   |     -------- ^^^ expected `isize`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:19:8
    |
+LL |     fn id_isize(n: isize) -> isize { n }
+   |        ^^^^^^^^ --------
 help: you can convert an `i32` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     id_isize(a32.try_into().unwrap());
@@ -211,8 +344,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:102:14
    |
 LL |     id_isize(a64);
-   |              ^^^ expected `isize`, found `i64`
+   |     -------- ^^^ expected `isize`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:19:8
    |
+LL |     fn id_isize(n: isize) -> isize { n }
+   |        ^^^^^^^^ --------
 help: you can convert an `i64` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     id_isize(a64.try_into().unwrap());
@@ -222,8 +362,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:108:11
    |
 LL |     id_i8(c16);
-   |           ^^^ expected `i8`, found `i16`
+   |     ----- ^^^ expected `i8`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
+   |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `i16` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(c16.try_into().unwrap());
@@ -233,8 +380,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:111:11
    |
 LL |     id_i8(c32);
-   |           ^^^ expected `i8`, found `i32`
+   |     ----- ^^^ expected `i8`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
    |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `i32` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(c32.try_into().unwrap());
@@ -244,8 +398,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:114:11
    |
 LL |     id_i8(c64);
-   |           ^^^ expected `i8`, found `i64`
+   |     ----- ^^^ expected `i8`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:15:8
    |
+LL |     fn id_i8(n: i8) -> i8 { n }
+   |        ^^^^^ -----
 help: you can convert an `i64` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     id_i8(c64.try_into().unwrap());
@@ -255,8 +416,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:118:12
    |
 LL |     id_i16(c8);
-   |            ^^ expected `i16`, found `i8`
+   |     ------ ^^ expected `i16`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
+   |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i8` to an `i16`
    |
 LL |     id_i16(c8.into());
@@ -266,8 +434,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:122:12
    |
 LL |     id_i16(c32);
-   |            ^^^ expected `i16`, found `i32`
+   |     ------ ^^^ expected `i16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
    |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i32` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     id_i16(c32.try_into().unwrap());
@@ -277,8 +452,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:125:12
    |
 LL |     id_i16(c64);
-   |            ^^^ expected `i16`, found `i64`
+   |     ------ ^^^ expected `i16`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:16:8
    |
+LL |     fn id_i16(n: i16) -> i16 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i64` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     id_i16(c64.try_into().unwrap());
@@ -288,8 +470,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:129:12
    |
 LL |     id_i32(c8);
-   |            ^^ expected `i32`, found `i8`
+   |     ------ ^^ expected `i32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
+   |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i8` to an `i32`
    |
 LL |     id_i32(c8.into());
@@ -299,8 +488,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:132:12
    |
 LL |     id_i32(c16);
-   |            ^^^ expected `i32`, found `i16`
+   |     ------ ^^^ expected `i32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
    |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i16` to an `i32`
    |
 LL |     id_i32(c16.into());
@@ -310,8 +506,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:136:12
    |
 LL |     id_i32(c64);
-   |            ^^^ expected `i32`, found `i64`
+   |     ------ ^^^ expected `i32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:17:8
+   |
+LL |     fn id_i32(n: i32) -> i32 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     id_i32(c64.try_into().unwrap());
@@ -321,8 +524,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:140:12
    |
 LL |     id_i64(a8);
-   |            ^^ expected `i64`, found `i8`
+   |     ------ ^^ expected `i64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
    |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i8` to an `i64`
    |
 LL |     id_i64(a8.into());
@@ -332,8 +542,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:143:12
    |
 LL |     id_i64(a16);
-   |            ^^^ expected `i64`, found `i16`
+   |     ------ ^^^ expected `i64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
+   |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i16` to an `i64`
    |
 LL |     id_i64(a16.into());
@@ -343,8 +560,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:146:12
    |
 LL |     id_i64(a32);
-   |            ^^^ expected `i64`, found `i32`
+   |     ------ ^^^ expected `i64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:18:8
    |
+LL |     fn id_i64(n: i64) -> i64 { n }
+   |        ^^^^^^ ------
 help: you can convert an `i32` to an `i64`
    |
 LL |     id_i64(a32.into());
@@ -354,8 +578,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:152:11
    |
 LL |     id_u8(b16);
-   |           ^^^ expected `u8`, found `u16`
+   |     ----- ^^^ expected `u8`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:27:8
    |
+LL |     fn id_u8(n: u8) -> u8 { n }
+   |        ^^^^^ -----
 help: you can convert a `u16` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     id_u8(b16.try_into().unwrap());
@@ -365,8 +596,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:155:11
    |
 LL |     id_u8(b32);
-   |           ^^^ expected `u8`, found `u32`
+   |     ----- ^^^ expected `u8`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:27:8
+   |
+LL |     fn id_u8(n: u8) -> u8 { n }
+   |        ^^^^^ -----
 help: you can convert a `u32` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     id_u8(b32.try_into().unwrap());
@@ -376,8 +614,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:158:11
    |
 LL |     id_u8(b64);
-   |           ^^^ expected `u8`, found `u64`
+   |     ----- ^^^ expected `u8`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:27:8
    |
+LL |     fn id_u8(n: u8) -> u8 { n }
+   |        ^^^^^ -----
 help: you can convert a `u64` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     id_u8(b64.try_into().unwrap());
@@ -387,8 +632,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:161:11
    |
 LL |     id_u8(bsize);
-   |           ^^^^^ expected `u8`, found `usize`
+   |     ----- ^^^^^ expected `u8`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:27:8
    |
+LL |     fn id_u8(n: u8) -> u8 { n }
+   |        ^^^^^ -----
 help: you can convert a `usize` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     id_u8(bsize.try_into().unwrap());
@@ -398,8 +650,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:165:12
    |
 LL |     id_u16(b8);
-   |            ^^ expected `u16`, found `u8`
+   |     ------ ^^ expected `u16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:28:8
+   |
+LL |     fn id_u16(n: u16) -> u16 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u8` to a `u16`
    |
 LL |     id_u16(b8.into());
@@ -409,8 +668,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:169:12
    |
 LL |     id_u16(b32);
-   |            ^^^ expected `u16`, found `u32`
+   |     ------ ^^^ expected `u16`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:28:8
    |
+LL |     fn id_u16(n: u16) -> u16 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u32` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     id_u16(b32.try_into().unwrap());
@@ -420,8 +686,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:172:12
    |
 LL |     id_u16(b64);
-   |            ^^^ expected `u16`, found `u64`
+   |     ------ ^^^ expected `u16`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:28:8
    |
+LL |     fn id_u16(n: u16) -> u16 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u64` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     id_u16(b64.try_into().unwrap());
@@ -431,8 +704,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:175:12
    |
 LL |     id_u16(bsize);
-   |            ^^^^^ expected `u16`, found `usize`
+   |     ------ ^^^^^ expected `u16`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:28:8
+   |
+LL |     fn id_u16(n: u16) -> u16 { n }
+   |        ^^^^^^ ------
 help: you can convert a `usize` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     id_u16(bsize.try_into().unwrap());
@@ -442,8 +722,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:179:12
    |
 LL |     id_u32(b8);
-   |            ^^ expected `u32`, found `u8`
+   |     ------ ^^ expected `u32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:29:8
    |
+LL |     fn id_u32(n: u32) -> u32 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u8` to a `u32`
    |
 LL |     id_u32(b8.into());
@@ -453,8 +740,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:182:12
    |
 LL |     id_u32(b16);
-   |            ^^^ expected `u32`, found `u16`
+   |     ------ ^^^ expected `u32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:29:8
+   |
+LL |     fn id_u32(n: u32) -> u32 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u16` to a `u32`
    |
 LL |     id_u32(b16.into());
@@ -464,8 +758,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:186:12
    |
 LL |     id_u32(b64);
-   |            ^^^ expected `u32`, found `u64`
+   |     ------ ^^^ expected `u32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:29:8
    |
+LL |     fn id_u32(n: u32) -> u32 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u64` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     id_u32(b64.try_into().unwrap());
@@ -475,8 +776,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:189:12
    |
 LL |     id_u32(bsize);
-   |            ^^^^^ expected `u32`, found `usize`
+   |     ------ ^^^^^ expected `u32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:29:8
+   |
+LL |     fn id_u32(n: u32) -> u32 { n }
+   |        ^^^^^^ ------
 help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     id_u32(bsize.try_into().unwrap());
@@ -486,8 +794,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:193:12
    |
 LL |     id_u64(b8);
-   |            ^^ expected `u64`, found `u8`
+   |     ------ ^^ expected `u64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:30:8
    |
+LL |     fn id_u64(n: u64) -> u64 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u8` to a `u64`
    |
 LL |     id_u64(b8.into());
@@ -497,8 +812,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:196:12
    |
 LL |     id_u64(b16);
-   |            ^^^ expected `u64`, found `u16`
+   |     ------ ^^^ expected `u64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:30:8
    |
+LL |     fn id_u64(n: u64) -> u64 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u16` to a `u64`
    |
 LL |     id_u64(b16.into());
@@ -508,8 +830,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:199:12
    |
 LL |     id_u64(b32);
-   |            ^^^ expected `u64`, found `u32`
+   |     ------ ^^^ expected `u64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:30:8
+   |
+LL |     fn id_u64(n: u64) -> u64 { n }
+   |        ^^^^^^ ------
 help: you can convert a `u32` to a `u64`
    |
 LL |     id_u64(b32.into());
@@ -519,8 +848,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:203:12
    |
 LL |     id_u64(bsize);
-   |            ^^^^^ expected `u64`, found `usize`
+   |     ------ ^^^^^ expected `u64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:30:8
    |
+LL |     fn id_u64(n: u64) -> u64 { n }
+   |        ^^^^^^ ------
 help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     id_u64(bsize.try_into().unwrap());
@@ -530,8 +866,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:207:14
    |
 LL |     id_usize(b8);
-   |              ^^ expected `usize`, found `u8`
+   |     -------- ^^ expected `usize`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:31:8
    |
+LL |     fn id_usize(n: usize) -> usize { n }
+   |        ^^^^^^^^ --------
 help: you can convert a `u8` to a `usize`
    |
 LL |     id_usize(b8.into());
@@ -541,8 +884,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:210:14
    |
 LL |     id_usize(b16);
-   |              ^^^ expected `usize`, found `u16`
+   |     -------- ^^^ expected `usize`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:31:8
+   |
+LL |     fn id_usize(n: usize) -> usize { n }
+   |        ^^^^^^^^ --------
 help: you can convert a `u16` to a `usize`
    |
 LL |     id_usize(b16.into());
@@ -552,8 +902,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:213:14
    |
 LL |     id_usize(b32);
-   |              ^^^ expected `usize`, found `u32`
+   |     -------- ^^^ expected `usize`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:31:8
    |
+LL |     fn id_usize(n: usize) -> usize { n }
+   |        ^^^^^^^^ --------
 help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     id_usize(b32.try_into().unwrap());
@@ -563,8 +920,15 @@ error[E0308]: mismatched types
   --> $DIR/integer-literal-suffix-inference.rs:216:14
    |
 LL |     id_usize(b64);
-   |              ^^^ expected `usize`, found `u64`
+   |     -------- ^^^ expected `usize`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/integer-literal-suffix-inference.rs:31:8
    |
+LL |     fn id_usize(n: usize) -> usize { n }
+   |        ^^^^^^^^ --------
 help: you can convert a `u64` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     id_usize(b64.try_into().unwrap());
diff --git a/src/test/ui/numeric/len.stderr b/src/test/ui/numeric/len.stderr
index 6319c1ead24..55a61b5e443 100644
--- a/src/test/ui/numeric/len.stderr
+++ b/src/test/ui/numeric/len.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/len.rs:3:10
    |
 LL |     test(array.len());
-   |          ^^^^^^^^^^^ expected `u32`, found `usize`
+   |     ---- ^^^^^^^^^^^ expected `u32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/len.rs:6:4
+   |
+LL | fn test(length: u32) {
+   |    ^^^^ -----------
 help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     test(array.len().try_into().unwrap());
diff --git a/src/test/ui/numeric/numeric-cast-without-suggestion.stderr b/src/test/ui/numeric/numeric-cast-without-suggestion.stderr
index a96518a3434..581b548abca 100644
--- a/src/test/ui/numeric/numeric-cast-without-suggestion.stderr
+++ b/src/test/ui/numeric/numeric-cast-without-suggestion.stderr
@@ -2,127 +2,295 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:17:18
    |
 LL |     foo::<usize>(x_f64);
-   |                  ^^^^^ expected `usize`, found `f64`
+   |     ------------ ^^^^^ expected `usize`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:18:18
    |
 LL |     foo::<usize>(x_f32);
-   |                  ^^^^^ expected `usize`, found `f32`
+   |     ------------ ^^^^^ expected `usize`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:19:18
    |
 LL |     foo::<isize>(x_f64);
-   |                  ^^^^^ expected `isize`, found `f64`
+   |     ------------ ^^^^^ expected `isize`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:20:18
    |
 LL |     foo::<isize>(x_f32);
-   |                  ^^^^^ expected `isize`, found `f32`
+   |     ------------ ^^^^^ expected `isize`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:21:16
    |
 LL |     foo::<u64>(x_f64);
-   |                ^^^^^ expected `u64`, found `f64`
+   |     ---------- ^^^^^ expected `u64`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:22:16
    |
 LL |     foo::<u64>(x_f32);
-   |                ^^^^^ expected `u64`, found `f32`
+   |     ---------- ^^^^^ expected `u64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:23:16
    |
 LL |     foo::<i64>(x_f64);
-   |                ^^^^^ expected `i64`, found `f64`
+   |     ---------- ^^^^^ expected `i64`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:24:16
    |
 LL |     foo::<i64>(x_f32);
-   |                ^^^^^ expected `i64`, found `f32`
+   |     ---------- ^^^^^ expected `i64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:25:16
    |
 LL |     foo::<u32>(x_f64);
-   |                ^^^^^ expected `u32`, found `f64`
+   |     ---------- ^^^^^ expected `u32`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:26:16
    |
 LL |     foo::<u32>(x_f32);
-   |                ^^^^^ expected `u32`, found `f32`
+   |     ---------- ^^^^^ expected `u32`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:27:16
    |
 LL |     foo::<i32>(x_f64);
-   |                ^^^^^ expected `i32`, found `f64`
+   |     ---------- ^^^^^ expected `i32`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:28:16
    |
 LL |     foo::<i32>(x_f32);
-   |                ^^^^^ expected `i32`, found `f32`
+   |     ---------- ^^^^^ expected `i32`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:29:16
    |
 LL |     foo::<u16>(x_f64);
-   |                ^^^^^ expected `u16`, found `f64`
+   |     ---------- ^^^^^ expected `u16`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:30:16
    |
 LL |     foo::<u16>(x_f32);
-   |                ^^^^^ expected `u16`, found `f32`
+   |     ---------- ^^^^^ expected `u16`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:31:16
    |
 LL |     foo::<i16>(x_f64);
-   |                ^^^^^ expected `i16`, found `f64`
+   |     ---------- ^^^^^ expected `i16`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:32:16
    |
 LL |     foo::<i16>(x_f32);
-   |                ^^^^^ expected `i16`, found `f32`
+   |     ---------- ^^^^^ expected `i16`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:33:15
    |
 LL |     foo::<u8>(x_f64);
-   |               ^^^^^ expected `u8`, found `f64`
+   |     --------- ^^^^^ expected `u8`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:34:15
    |
 LL |     foo::<u8>(x_f32);
-   |               ^^^^^ expected `u8`, found `f32`
+   |     --------- ^^^^^ expected `u8`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:35:15
    |
 LL |     foo::<i8>(x_f64);
-   |               ^^^^^ expected `i8`, found `f64`
+   |     --------- ^^^^^ expected `i8`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:36:15
    |
 LL |     foo::<i8>(x_f32);
-   |               ^^^^^ expected `i8`, found `f32`
+   |     --------- ^^^^^ expected `i8`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error[E0308]: mismatched types
   --> $DIR/numeric-cast-without-suggestion.rs:37:16
    |
 LL |     foo::<f32>(x_f64);
-   |                ^^^^^ expected `f32`, found `f64`
+   |     ---------- ^^^^^ expected `f32`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast-without-suggestion.rs:1:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 
 error: aborting due to 21 previous errors
 
diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr
index b8f2d88ab49..d347875d5a9 100644
--- a/src/test/ui/numeric/numeric-cast.stderr
+++ b/src/test/ui/numeric/numeric-cast.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:23:18
    |
 LL |     foo::<usize>(x_u64);
-   |                  ^^^^^ expected `usize`, found `u64`
+   |     ------------ ^^^^^ expected `usize`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_u64.try_into().unwrap());
@@ -13,8 +20,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:25:18
    |
 LL |     foo::<usize>(x_u32);
-   |                  ^^^^^ expected `usize`, found `u32`
+   |     ------------ ^^^^^ expected `usize`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_u32.try_into().unwrap());
@@ -24,8 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:27:18
    |
 LL |     foo::<usize>(x_u16);
-   |                  ^^^^^ expected `usize`, found `u16`
+   |     ------------ ^^^^^ expected `usize`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to a `usize`
    |
 LL |     foo::<usize>(x_u16.into());
@@ -35,8 +56,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:29:18
    |
 LL |     foo::<usize>(x_u8);
-   |                  ^^^^ expected `usize`, found `u8`
+   |     ------------ ^^^^ expected `usize`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to a `usize`
    |
 LL |     foo::<usize>(x_u8.into());
@@ -46,8 +74,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:31:18
    |
 LL |     foo::<usize>(x_isize);
-   |                  ^^^^^^^ expected `usize`, found `isize`
+   |     ------------ ^^^^^^^ expected `usize`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_isize.try_into().unwrap());
@@ -57,8 +92,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:33:18
    |
 LL |     foo::<usize>(x_i64);
-   |                  ^^^^^ expected `usize`, found `i64`
+   |     ------------ ^^^^^ expected `usize`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_i64.try_into().unwrap());
@@ -68,8 +110,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:35:18
    |
 LL |     foo::<usize>(x_i32);
-   |                  ^^^^^ expected `usize`, found `i32`
+   |     ------------ ^^^^^ expected `usize`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_i32.try_into().unwrap());
@@ -79,8 +128,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:37:18
    |
 LL |     foo::<usize>(x_i16);
-   |                  ^^^^^ expected `usize`, found `i16`
+   |     ------------ ^^^^^ expected `usize`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_i16.try_into().unwrap());
@@ -90,8 +146,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:39:18
    |
 LL |     foo::<usize>(x_i8);
-   |                  ^^^^ expected `usize`, found `i8`
+   |     ------------ ^^^^ expected `usize`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to a `usize` and panic if the converted value doesn't fit
    |
 LL |     foo::<usize>(x_i8.try_into().unwrap());
@@ -101,8 +164,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:44:18
    |
 LL |     foo::<isize>(x_usize);
-   |                  ^^^^^^^ expected `isize`, found `usize`
+   |     ------------ ^^^^^^^ expected `isize`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     foo::<isize>(x_usize.try_into().unwrap());
@@ -112,8 +182,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:46:18
    |
 LL |     foo::<isize>(x_u64);
-   |                  ^^^^^ expected `isize`, found `u64`
+   |     ------------ ^^^^^ expected `isize`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     foo::<isize>(x_u64.try_into().unwrap());
@@ -123,8 +200,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:48:18
    |
 LL |     foo::<isize>(x_u32);
-   |                  ^^^^^ expected `isize`, found `u32`
+   |     ------------ ^^^^^ expected `isize`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     foo::<isize>(x_u32.try_into().unwrap());
@@ -134,8 +218,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:50:18
    |
 LL |     foo::<isize>(x_u16);
-   |                  ^^^^^ expected `isize`, found `u16`
+   |     ------------ ^^^^^ expected `isize`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     foo::<isize>(x_u16.try_into().unwrap());
@@ -145,8 +236,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:52:18
    |
 LL |     foo::<isize>(x_u8);
-   |                  ^^^^ expected `isize`, found `u8`
+   |     ------------ ^^^^ expected `isize`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `isize`
    |
 LL |     foo::<isize>(x_u8.into());
@@ -156,8 +254,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:55:18
    |
 LL |     foo::<isize>(x_i64);
-   |                  ^^^^^ expected `isize`, found `i64`
+   |     ------------ ^^^^^ expected `isize`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     foo::<isize>(x_i64.try_into().unwrap());
@@ -167,8 +272,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:57:18
    |
 LL |     foo::<isize>(x_i32);
-   |                  ^^^^^ expected `isize`, found `i32`
+   |     ------------ ^^^^^ expected `isize`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to an `isize` and panic if the converted value doesn't fit
    |
 LL |     foo::<isize>(x_i32.try_into().unwrap());
@@ -178,8 +290,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:59:18
    |
 LL |     foo::<isize>(x_i16);
-   |                  ^^^^^ expected `isize`, found `i16`
+   |     ------------ ^^^^^ expected `isize`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to an `isize`
    |
 LL |     foo::<isize>(x_i16.into());
@@ -189,8 +308,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:61:18
    |
 LL |     foo::<isize>(x_i8);
-   |                  ^^^^ expected `isize`, found `i8`
+   |     ------------ ^^^^ expected `isize`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `isize`
    |
 LL |     foo::<isize>(x_i8.into());
@@ -200,8 +326,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:66:16
    |
 LL |     foo::<u64>(x_usize);
-   |                ^^^^^^^ expected `u64`, found `usize`
+   |     ---------- ^^^^^^^ expected `u64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     foo::<u64>(x_usize.try_into().unwrap());
@@ -211,8 +344,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:69:16
    |
 LL |     foo::<u64>(x_u32);
-   |                ^^^^^ expected `u64`, found `u32`
+   |     ---------- ^^^^^ expected `u64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to a `u64`
    |
 LL |     foo::<u64>(x_u32.into());
@@ -222,8 +362,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:71:16
    |
 LL |     foo::<u64>(x_u16);
-   |                ^^^^^ expected `u64`, found `u16`
+   |     ---------- ^^^^^ expected `u64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to a `u64`
    |
 LL |     foo::<u64>(x_u16.into());
@@ -233,8 +380,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:73:16
    |
 LL |     foo::<u64>(x_u8);
-   |                ^^^^ expected `u64`, found `u8`
+   |     ---------- ^^^^ expected `u64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to a `u64`
    |
 LL |     foo::<u64>(x_u8.into());
@@ -244,8 +398,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:75:16
    |
 LL |     foo::<u64>(x_isize);
-   |                ^^^^^^^ expected `u64`, found `isize`
+   |     ---------- ^^^^^^^ expected `u64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     foo::<u64>(x_isize.try_into().unwrap());
@@ -255,8 +416,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:77:16
    |
 LL |     foo::<u64>(x_i64);
-   |                ^^^^^ expected `u64`, found `i64`
+   |     ---------- ^^^^^ expected `u64`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     foo::<u64>(x_i64.try_into().unwrap());
@@ -266,8 +434,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:79:16
    |
 LL |     foo::<u64>(x_i32);
-   |                ^^^^^ expected `u64`, found `i32`
+   |     ---------- ^^^^^ expected `u64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     foo::<u64>(x_i32.try_into().unwrap());
@@ -277,8 +452,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:81:16
    |
 LL |     foo::<u64>(x_i16);
-   |                ^^^^^ expected `u64`, found `i16`
+   |     ---------- ^^^^^ expected `u64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     foo::<u64>(x_i16.try_into().unwrap());
@@ -288,8 +470,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:83:16
    |
 LL |     foo::<u64>(x_i8);
-   |                ^^^^ expected `u64`, found `i8`
+   |     ---------- ^^^^ expected `u64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to a `u64` and panic if the converted value doesn't fit
    |
 LL |     foo::<u64>(x_i8.try_into().unwrap());
@@ -299,8 +488,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:88:16
    |
 LL |     foo::<i64>(x_usize);
-   |                ^^^^^^^ expected `i64`, found `usize`
+   |     ---------- ^^^^^^^ expected `i64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to an `i64` and panic if the converted value doesn't fit
    |
 LL |     foo::<i64>(x_usize.try_into().unwrap());
@@ -310,8 +506,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:90:16
    |
 LL |     foo::<i64>(x_u64);
-   |                ^^^^^ expected `i64`, found `u64`
+   |     ---------- ^^^^^ expected `i64`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to an `i64` and panic if the converted value doesn't fit
    |
 LL |     foo::<i64>(x_u64.try_into().unwrap());
@@ -321,8 +524,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:92:16
    |
 LL |     foo::<i64>(x_u32);
-   |                ^^^^^ expected `i64`, found `u32`
+   |     ---------- ^^^^^ expected `i64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to an `i64`
    |
 LL |     foo::<i64>(x_u32.into());
@@ -332,8 +542,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:94:16
    |
 LL |     foo::<i64>(x_u16);
-   |                ^^^^^ expected `i64`, found `u16`
+   |     ---------- ^^^^^ expected `i64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `i64`
    |
 LL |     foo::<i64>(x_u16.into());
@@ -343,8 +560,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:96:16
    |
 LL |     foo::<i64>(x_u8);
-   |                ^^^^ expected `i64`, found `u8`
+   |     ---------- ^^^^ expected `i64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `i64`
    |
 LL |     foo::<i64>(x_u8.into());
@@ -354,8 +578,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:98:16
    |
 LL |     foo::<i64>(x_isize);
-   |                ^^^^^^^ expected `i64`, found `isize`
+   |     ---------- ^^^^^^^ expected `i64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to an `i64` and panic if the converted value doesn't fit
    |
 LL |     foo::<i64>(x_isize.try_into().unwrap());
@@ -365,8 +596,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:101:16
    |
 LL |     foo::<i64>(x_i32);
-   |                ^^^^^ expected `i64`, found `i32`
+   |     ---------- ^^^^^ expected `i64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to an `i64`
    |
 LL |     foo::<i64>(x_i32.into());
@@ -376,8 +614,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:103:16
    |
 LL |     foo::<i64>(x_i16);
-   |                ^^^^^ expected `i64`, found `i16`
+   |     ---------- ^^^^^ expected `i64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to an `i64`
    |
 LL |     foo::<i64>(x_i16.into());
@@ -387,8 +632,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:105:16
    |
 LL |     foo::<i64>(x_i8);
-   |                ^^^^ expected `i64`, found `i8`
+   |     ---------- ^^^^ expected `i64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `i64`
    |
 LL |     foo::<i64>(x_i8.into());
@@ -398,8 +650,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:110:16
    |
 LL |     foo::<u32>(x_usize);
-   |                ^^^^^^^ expected `u32`, found `usize`
+   |     ---------- ^^^^^^^ expected `u32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_usize.try_into().unwrap());
@@ -409,8 +668,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:112:16
    |
 LL |     foo::<u32>(x_u64);
-   |                ^^^^^ expected `u32`, found `u64`
+   |     ---------- ^^^^^ expected `u32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_u64.try_into().unwrap());
@@ -420,8 +686,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:115:16
    |
 LL |     foo::<u32>(x_u16);
-   |                ^^^^^ expected `u32`, found `u16`
+   |     ---------- ^^^^^ expected `u32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to a `u32`
    |
 LL |     foo::<u32>(x_u16.into());
@@ -431,8 +704,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:117:16
    |
 LL |     foo::<u32>(x_u8);
-   |                ^^^^ expected `u32`, found `u8`
+   |     ---------- ^^^^ expected `u32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to a `u32`
    |
 LL |     foo::<u32>(x_u8.into());
@@ -442,8 +722,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:119:16
    |
 LL |     foo::<u32>(x_isize);
-   |                ^^^^^^^ expected `u32`, found `isize`
+   |     ---------- ^^^^^^^ expected `u32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_isize.try_into().unwrap());
@@ -453,8 +740,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:121:16
    |
 LL |     foo::<u32>(x_i64);
-   |                ^^^^^ expected `u32`, found `i64`
+   |     ---------- ^^^^^ expected `u32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_i64.try_into().unwrap());
@@ -464,8 +758,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:123:16
    |
 LL |     foo::<u32>(x_i32);
-   |                ^^^^^ expected `u32`, found `i32`
+   |     ---------- ^^^^^ expected `u32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_i32.try_into().unwrap());
@@ -475,8 +776,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:125:16
    |
 LL |     foo::<u32>(x_i16);
-   |                ^^^^^ expected `u32`, found `i16`
+   |     ---------- ^^^^^ expected `u32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_i16.try_into().unwrap());
@@ -486,8 +794,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:127:16
    |
 LL |     foo::<u32>(x_i8);
-   |                ^^^^ expected `u32`, found `i8`
+   |     ---------- ^^^^ expected `u32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to a `u32` and panic if the converted value doesn't fit
    |
 LL |     foo::<u32>(x_i8.try_into().unwrap());
@@ -497,8 +812,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:132:16
    |
 LL |     foo::<i32>(x_usize);
-   |                ^^^^^^^ expected `i32`, found `usize`
+   |     ---------- ^^^^^^^ expected `i32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     foo::<i32>(x_usize.try_into().unwrap());
@@ -508,8 +830,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:134:16
    |
 LL |     foo::<i32>(x_u64);
-   |                ^^^^^ expected `i32`, found `u64`
+   |     ---------- ^^^^^ expected `i32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     foo::<i32>(x_u64.try_into().unwrap());
@@ -519,8 +848,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:136:16
    |
 LL |     foo::<i32>(x_u32);
-   |                ^^^^^ expected `i32`, found `u32`
+   |     ---------- ^^^^^ expected `i32`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     foo::<i32>(x_u32.try_into().unwrap());
@@ -530,8 +866,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:138:16
    |
 LL |     foo::<i32>(x_u16);
-   |                ^^^^^ expected `i32`, found `u16`
+   |     ---------- ^^^^^ expected `i32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `i32`
    |
 LL |     foo::<i32>(x_u16.into());
@@ -541,8 +884,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:140:16
    |
 LL |     foo::<i32>(x_u8);
-   |                ^^^^ expected `i32`, found `u8`
+   |     ---------- ^^^^ expected `i32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `i32`
    |
 LL |     foo::<i32>(x_u8.into());
@@ -552,8 +902,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:142:16
    |
 LL |     foo::<i32>(x_isize);
-   |                ^^^^^^^ expected `i32`, found `isize`
+   |     ---------- ^^^^^^^ expected `i32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     foo::<i32>(x_isize.try_into().unwrap());
@@ -563,8 +920,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:144:16
    |
 LL |     foo::<i32>(x_i64);
-   |                ^^^^^ expected `i32`, found `i64`
+   |     ---------- ^^^^^ expected `i32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to an `i32` and panic if the converted value doesn't fit
    |
 LL |     foo::<i32>(x_i64.try_into().unwrap());
@@ -574,8 +938,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:147:16
    |
 LL |     foo::<i32>(x_i16);
-   |                ^^^^^ expected `i32`, found `i16`
+   |     ---------- ^^^^^ expected `i32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to an `i32`
    |
 LL |     foo::<i32>(x_i16.into());
@@ -585,8 +956,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:149:16
    |
 LL |     foo::<i32>(x_i8);
-   |                ^^^^ expected `i32`, found `i8`
+   |     ---------- ^^^^ expected `i32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `i32`
    |
 LL |     foo::<i32>(x_i8.into());
@@ -596,8 +974,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:154:16
    |
 LL |     foo::<u16>(x_usize);
-   |                ^^^^^^^ expected `u16`, found `usize`
+   |     ---------- ^^^^^^^ expected `u16`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_usize.try_into().unwrap());
@@ -607,8 +992,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:156:16
    |
 LL |     foo::<u16>(x_u64);
-   |                ^^^^^ expected `u16`, found `u64`
+   |     ---------- ^^^^^ expected `u16`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_u64.try_into().unwrap());
@@ -618,8 +1010,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:158:16
    |
 LL |     foo::<u16>(x_u32);
-   |                ^^^^^ expected `u16`, found `u32`
+   |     ---------- ^^^^^ expected `u16`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_u32.try_into().unwrap());
@@ -629,8 +1028,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:161:16
    |
 LL |     foo::<u16>(x_u8);
-   |                ^^^^ expected `u16`, found `u8`
+   |     ---------- ^^^^ expected `u16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to a `u16`
    |
 LL |     foo::<u16>(x_u8.into());
@@ -640,8 +1046,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:163:16
    |
 LL |     foo::<u16>(x_isize);
-   |                ^^^^^^^ expected `u16`, found `isize`
+   |     ---------- ^^^^^^^ expected `u16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_isize.try_into().unwrap());
@@ -651,8 +1064,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:165:16
    |
 LL |     foo::<u16>(x_i64);
-   |                ^^^^^ expected `u16`, found `i64`
+   |     ---------- ^^^^^ expected `u16`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_i64.try_into().unwrap());
@@ -662,8 +1082,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:167:16
    |
 LL |     foo::<u16>(x_i32);
-   |                ^^^^^ expected `u16`, found `i32`
+   |     ---------- ^^^^^ expected `u16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_i32.try_into().unwrap());
@@ -673,8 +1100,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:169:16
    |
 LL |     foo::<u16>(x_i16);
-   |                ^^^^^ expected `u16`, found `i16`
+   |     ---------- ^^^^^ expected `u16`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_i16.try_into().unwrap());
@@ -684,8 +1118,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:171:16
    |
 LL |     foo::<u16>(x_i8);
-   |                ^^^^ expected `u16`, found `i8`
+   |     ---------- ^^^^ expected `u16`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to a `u16` and panic if the converted value doesn't fit
    |
 LL |     foo::<u16>(x_i8.try_into().unwrap());
@@ -695,8 +1136,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:176:16
    |
 LL |     foo::<i16>(x_usize);
-   |                ^^^^^^^ expected `i16`, found `usize`
+   |     ---------- ^^^^^^^ expected `i16`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_usize.try_into().unwrap());
@@ -706,8 +1154,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:178:16
    |
 LL |     foo::<i16>(x_u64);
-   |                ^^^^^ expected `i16`, found `u64`
+   |     ---------- ^^^^^ expected `i16`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_u64.try_into().unwrap());
@@ -717,8 +1172,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:180:16
    |
 LL |     foo::<i16>(x_u32);
-   |                ^^^^^ expected `i16`, found `u32`
+   |     ---------- ^^^^^ expected `i16`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_u32.try_into().unwrap());
@@ -728,8 +1190,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:182:16
    |
 LL |     foo::<i16>(x_u16);
-   |                ^^^^^ expected `i16`, found `u16`
+   |     ---------- ^^^^^ expected `i16`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_u16.try_into().unwrap());
@@ -739,8 +1208,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:184:16
    |
 LL |     foo::<i16>(x_u8);
-   |                ^^^^ expected `i16`, found `u8`
+   |     ---------- ^^^^ expected `i16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `i16`
    |
 LL |     foo::<i16>(x_u8.into());
@@ -750,8 +1226,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:186:16
    |
 LL |     foo::<i16>(x_isize);
-   |                ^^^^^^^ expected `i16`, found `isize`
+   |     ---------- ^^^^^^^ expected `i16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_isize.try_into().unwrap());
@@ -761,8 +1244,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:188:16
    |
 LL |     foo::<i16>(x_i64);
-   |                ^^^^^ expected `i16`, found `i64`
+   |     ---------- ^^^^^ expected `i16`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_i64.try_into().unwrap());
@@ -772,8 +1262,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:190:16
    |
 LL |     foo::<i16>(x_i32);
-   |                ^^^^^ expected `i16`, found `i32`
+   |     ---------- ^^^^^ expected `i16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to an `i16` and panic if the converted value doesn't fit
    |
 LL |     foo::<i16>(x_i32.try_into().unwrap());
@@ -783,8 +1280,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:193:16
    |
 LL |     foo::<i16>(x_i8);
-   |                ^^^^ expected `i16`, found `i8`
+   |     ---------- ^^^^ expected `i16`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `i16`
    |
 LL |     foo::<i16>(x_i8.into());
@@ -794,8 +1298,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:198:15
    |
 LL |     foo::<u8>(x_usize);
-   |               ^^^^^^^ expected `u8`, found `usize`
+   |     --------- ^^^^^^^ expected `u8`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_usize.try_into().unwrap());
@@ -805,8 +1316,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:200:15
    |
 LL |     foo::<u8>(x_u64);
-   |               ^^^^^ expected `u8`, found `u64`
+   |     --------- ^^^^^ expected `u8`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_u64.try_into().unwrap());
@@ -816,8 +1334,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:202:15
    |
 LL |     foo::<u8>(x_u32);
-   |               ^^^^^ expected `u8`, found `u32`
+   |     --------- ^^^^^ expected `u8`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_u32.try_into().unwrap());
@@ -827,8 +1352,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:204:15
    |
 LL |     foo::<u8>(x_u16);
-   |               ^^^^^ expected `u8`, found `u16`
+   |     --------- ^^^^^ expected `u8`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_u16.try_into().unwrap());
@@ -838,8 +1370,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:207:15
    |
 LL |     foo::<u8>(x_isize);
-   |               ^^^^^^^ expected `u8`, found `isize`
+   |     --------- ^^^^^^^ expected `u8`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_isize.try_into().unwrap());
@@ -849,8 +1388,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:209:15
    |
 LL |     foo::<u8>(x_i64);
-   |               ^^^^^ expected `u8`, found `i64`
+   |     --------- ^^^^^ expected `u8`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_i64.try_into().unwrap());
@@ -860,8 +1406,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:211:15
    |
 LL |     foo::<u8>(x_i32);
-   |               ^^^^^ expected `u8`, found `i32`
+   |     --------- ^^^^^ expected `u8`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_i32.try_into().unwrap());
@@ -871,8 +1424,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:213:15
    |
 LL |     foo::<u8>(x_i16);
-   |               ^^^^^ expected `u8`, found `i16`
+   |     --------- ^^^^^ expected `u8`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_i16.try_into().unwrap());
@@ -882,8 +1442,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:215:15
    |
 LL |     foo::<u8>(x_i8);
-   |               ^^^^ expected `u8`, found `i8`
+   |     --------- ^^^^ expected `u8`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to a `u8` and panic if the converted value doesn't fit
    |
 LL |     foo::<u8>(x_i8.try_into().unwrap());
@@ -893,8 +1460,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:220:15
    |
 LL |     foo::<i8>(x_usize);
-   |               ^^^^^^^ expected `i8`, found `usize`
+   |     --------- ^^^^^^^ expected `i8`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `usize` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_usize.try_into().unwrap());
@@ -904,8 +1478,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:222:15
    |
 LL |     foo::<i8>(x_u64);
-   |               ^^^^^ expected `i8`, found `u64`
+   |     --------- ^^^^^ expected `i8`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u64` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_u64.try_into().unwrap());
@@ -915,8 +1496,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:224:15
    |
 LL |     foo::<i8>(x_u32);
-   |               ^^^^^ expected `i8`, found `u32`
+   |     --------- ^^^^^ expected `i8`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_u32.try_into().unwrap());
@@ -926,8 +1514,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:226:15
    |
 LL |     foo::<i8>(x_u16);
-   |               ^^^^^ expected `i8`, found `u16`
+   |     --------- ^^^^^ expected `i8`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_u16.try_into().unwrap());
@@ -937,8 +1532,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:228:15
    |
 LL |     foo::<i8>(x_u8);
-   |               ^^^^ expected `i8`, found `u8`
+   |     --------- ^^^^ expected `i8`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_u8.try_into().unwrap());
@@ -948,8 +1550,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:230:15
    |
 LL |     foo::<i8>(x_isize);
-   |               ^^^^^^^ expected `i8`, found `isize`
+   |     --------- ^^^^^^^ expected `i8`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_isize.try_into().unwrap());
@@ -959,8 +1568,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:232:15
    |
 LL |     foo::<i8>(x_i64);
-   |               ^^^^^ expected `i8`, found `i64`
+   |     --------- ^^^^^ expected `i8`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_i64.try_into().unwrap());
@@ -970,8 +1586,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:234:15
    |
 LL |     foo::<i8>(x_i32);
-   |               ^^^^^ expected `i8`, found `i32`
+   |     --------- ^^^^^ expected `i8`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_i32.try_into().unwrap());
@@ -981,8 +1604,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:236:15
    |
 LL |     foo::<i8>(x_i16);
-   |               ^^^^^ expected `i8`, found `i16`
+   |     --------- ^^^^^ expected `i8`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to an `i8` and panic if the converted value doesn't fit
    |
 LL |     foo::<i8>(x_i16.try_into().unwrap());
@@ -992,8 +1622,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:242:16
    |
 LL |     foo::<f64>(x_usize);
-   |                ^^^^^^^ expected `f64`, found `usize`
+   |     ---------- ^^^^^^^ expected `f64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can cast a `usize` to an `f64`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f64>(x_usize as f64);
@@ -1003,8 +1640,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:244:16
    |
 LL |     foo::<f64>(x_u64);
-   |                ^^^^^ expected `f64`, found `u64`
+   |     ---------- ^^^^^ expected `f64`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can cast a `u64` to an `f64`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f64>(x_u64 as f64);
@@ -1014,8 +1658,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:246:16
    |
 LL |     foo::<f64>(x_u32);
-   |                ^^^^^ expected `f64`, found `u32`
+   |     ---------- ^^^^^ expected `f64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u32` to an `f64`, producing the floating point representation of the integer
    |
 LL |     foo::<f64>(x_u32.into());
@@ -1025,8 +1676,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:248:16
    |
 LL |     foo::<f64>(x_u16);
-   |                ^^^^^ expected `f64`, found `u16`
+   |     ---------- ^^^^^ expected `f64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `f64`, producing the floating point representation of the integer
    |
 LL |     foo::<f64>(x_u16.into());
@@ -1036,8 +1694,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:250:16
    |
 LL |     foo::<f64>(x_u8);
-   |                ^^^^ expected `f64`, found `u8`
+   |     ---------- ^^^^ expected `f64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `f64`, producing the floating point representation of the integer
    |
 LL |     foo::<f64>(x_u8.into());
@@ -1047,8 +1712,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:252:16
    |
 LL |     foo::<f64>(x_isize);
-   |                ^^^^^^^ expected `f64`, found `isize`
+   |     ---------- ^^^^^^^ expected `f64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to an `f64`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f64>(x_isize as f64);
@@ -1058,8 +1730,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:254:16
    |
 LL |     foo::<f64>(x_i64);
-   |                ^^^^^ expected `f64`, found `i64`
+   |     ---------- ^^^^^ expected `f64`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to an `f64`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f64>(x_i64 as f64);
@@ -1069,8 +1748,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:256:16
    |
 LL |     foo::<f64>(x_i32);
-   |                ^^^^^ expected `f64`, found `i32`
+   |     ---------- ^^^^^ expected `f64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to an `f64`, producing the floating point representation of the integer
    |
 LL |     foo::<f64>(x_i32.into());
@@ -1080,8 +1766,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:258:16
    |
 LL |     foo::<f64>(x_i16);
-   |                ^^^^^ expected `f64`, found `i16`
+   |     ---------- ^^^^^ expected `f64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to an `f64`, producing the floating point representation of the integer
    |
 LL |     foo::<f64>(x_i16.into());
@@ -1091,8 +1784,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:260:16
    |
 LL |     foo::<f64>(x_i8);
-   |                ^^^^ expected `f64`, found `i8`
+   |     ---------- ^^^^ expected `f64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `f64`, producing the floating point representation of the integer
    |
 LL |     foo::<f64>(x_i8.into());
@@ -1102,8 +1802,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:263:16
    |
 LL |     foo::<f64>(x_f32);
-   |                ^^^^^ expected `f64`, found `f32`
+   |     ---------- ^^^^^ expected `f64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `f32` to an `f64`
    |
 LL |     foo::<f64>(x_f32.into());
@@ -1113,8 +1820,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:266:16
    |
 LL |     foo::<f32>(x_usize);
-   |                ^^^^^^^ expected `f32`, found `usize`
+   |     ---------- ^^^^^^^ expected `f32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can cast a `usize` to an `f32`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f32>(x_usize as f32);
@@ -1124,8 +1838,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:268:16
    |
 LL |     foo::<f32>(x_u64);
-   |                ^^^^^ expected `f32`, found `u64`
+   |     ---------- ^^^^^ expected `f32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can cast a `u64` to an `f32`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f32>(x_u64 as f32);
@@ -1135,8 +1856,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:270:16
    |
 LL |     foo::<f32>(x_u32);
-   |                ^^^^^ expected `f32`, found `u32`
+   |     ---------- ^^^^^ expected `f32`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can cast a `u32` to an `f32`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f32>(x_u32 as f32);
@@ -1146,8 +1874,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:272:16
    |
 LL |     foo::<f32>(x_u16);
-   |                ^^^^^ expected `f32`, found `u16`
+   |     ---------- ^^^^^ expected `f32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to an `f32`, producing the floating point representation of the integer
    |
 LL |     foo::<f32>(x_u16.into());
@@ -1157,8 +1892,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:274:16
    |
 LL |     foo::<f32>(x_u8);
-   |                ^^^^ expected `f32`, found `u8`
+   |     ---------- ^^^^ expected `f32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u8` to an `f32`, producing the floating point representation of the integer
    |
 LL |     foo::<f32>(x_u8.into());
@@ -1168,8 +1910,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:276:16
    |
 LL |     foo::<f32>(x_isize);
-   |                ^^^^^^^ expected `f32`, found `isize`
+   |     ---------- ^^^^^^^ expected `f32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `isize` to an `f32`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f32>(x_isize as f32);
@@ -1179,8 +1928,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:278:16
    |
 LL |     foo::<f32>(x_i64);
-   |                ^^^^^ expected `f32`, found `i64`
+   |     ---------- ^^^^^ expected `f32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i64` to an `f32`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f32>(x_i64 as f32);
@@ -1190,8 +1946,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:280:16
    |
 LL |     foo::<f32>(x_i32);
-   |                ^^^^^ expected `f32`, found `i32`
+   |     ---------- ^^^^^ expected `f32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i32` to an `f32`, producing the floating point representation of the integer, rounded if necessary
    |
 LL |     foo::<f32>(x_i32 as f32);
@@ -1201,8 +1964,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:282:16
    |
 LL |     foo::<f32>(x_i16);
-   |                ^^^^^ expected `f32`, found `i16`
+   |     ---------- ^^^^^ expected `f32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i16` to an `f32`, producing the floating point representation of the integer
    |
 LL |     foo::<f32>(x_i16.into());
@@ -1212,8 +1982,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:284:16
    |
 LL |     foo::<f32>(x_i8);
-   |                ^^^^ expected `f32`, found `i8`
+   |     ---------- ^^^^ expected `f32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `f32`, producing the floating point representation of the integer
    |
 LL |     foo::<f32>(x_i8.into());
@@ -1223,8 +2000,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:289:16
    |
 LL |     foo::<u32>(x_u8 as u16);
-   |                ^^^^^^^^^^^ expected `u32`, found `u16`
+   |     ---------- ^^^^^^^^^^^ expected `u32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert a `u16` to a `u32`
    |
 LL |     foo::<u32>((x_u8 as u16).into());
@@ -1234,8 +2018,15 @@ error[E0308]: mismatched types
   --> $DIR/numeric-cast.rs:291:16
    |
 LL |     foo::<i32>(-x_i8);
-   |                ^^^^^ expected `i32`, found `i8`
+   |     ---------- ^^^^^ expected `i32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-cast.rs:6:4
    |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
 help: you can convert an `i8` to an `i32`
    |
 LL |     foo::<i32>((-x_i8).into());
diff --git a/src/test/ui/numeric/numeric-suffix.fixed b/src/test/ui/numeric/numeric-suffix.fixed
deleted file mode 100644
index 53c5fe0f435..00000000000
--- a/src/test/ui/numeric/numeric-suffix.fixed
+++ /dev/null
@@ -1,298 +0,0 @@
-// run-rustfix
-
-fn foo<N>(_x: N) {}
-
-fn main() {
-    foo::<usize>(42_usize);
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42usize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42usize);
-    //~^ ERROR mismatched types
-
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42isize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42isize);
-    //~^ ERROR mismatched types
-
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42u64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42u64);
-    //~^ ERROR mismatched types
-
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42i64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42i64);
-    //~^ ERROR mismatched types
-
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42u32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42u32);
-    //~^ ERROR mismatched types
-
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42i32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42i32);
-    //~^ ERROR mismatched types
-
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42u16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42u16);
-    //~^ ERROR mismatched types
-
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    foo::<i16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42i16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42i16);
-    //~^ ERROR mismatched types
-
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42u8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42u8);
-    //~^ ERROR mismatched types
-
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    foo::<i8>(42i8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42i8);
-    //~^ ERROR mismatched types
-
-    foo::<f64>(42_f64);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_f64);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u32.into());
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u16.into());
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u8.into());
-    //~^ ERROR mismatched types
-    foo::<f64>(42_f64);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_f64);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i32.into());
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i16.into());
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i8.into());
-    //~^ ERROR mismatched types
-    foo::<f64>(42.0_f64);
-    foo::<f64>(42.0_f64);
-    //~^ ERROR mismatched types
-
-    foo::<f32>(42_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_u16.into());
-    //~^ ERROR mismatched types
-    foo::<f32>(42_u8.into());
-    //~^ ERROR mismatched types
-    foo::<f32>(42_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_i16.into());
-    //~^ ERROR mismatched types
-    foo::<f32>(42_i8.into());
-    //~^ ERROR mismatched types
-    foo::<f32>(42.0_f32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42.0_f32);
-
-    foo::<u32>((42_u8 as u16).into());
-    //~^ ERROR mismatched types
-    foo::<i32>((-42_i8).into());
-    //~^ ERROR mismatched types
-}
diff --git a/src/test/ui/numeric/numeric-suffix.rs b/src/test/ui/numeric/numeric-suffix.rs
deleted file mode 100644
index ca38ed82220..00000000000
--- a/src/test/ui/numeric/numeric-suffix.rs
+++ /dev/null
@@ -1,298 +0,0 @@
-// run-rustfix
-
-fn foo<N>(_x: N) {}
-
-fn main() {
-    foo::<usize>(42_usize);
-    foo::<usize>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<usize>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<usize>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<usize>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<isize>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_isize);
-    foo::<isize>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<isize>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<isize>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<isize>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<u64>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u64);
-    foo::<u64>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<u64>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<u64>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<u64>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<i64>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i64);
-    foo::<i64>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i64>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i64>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<i64>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<u32>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u32);
-    foo::<u32>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<u32>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<u32>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<u32>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<i32>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i32);
-    foo::<i32>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i32>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i32>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<i32>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<u16>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_u16);
-    foo::<u16>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<u16>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<u16>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<u16>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<i16>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i16>(42_i16);
-    foo::<i16>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<i16>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<i16>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<u8>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_u8);
-    foo::<u8>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<u8>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<u8>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<u8>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<i8>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<i8>(42_i8);
-    foo::<i8>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<i8>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<f64>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<f64>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<f64>(42.0_f64);
-    foo::<f64>(42.0_f32);
-    //~^ ERROR mismatched types
-
-    foo::<f32>(42_usize);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_u64);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_u32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_u16);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_u8);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_isize);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_i64);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_i32);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_i16);
-    //~^ ERROR mismatched types
-    foo::<f32>(42_i8);
-    //~^ ERROR mismatched types
-    foo::<f32>(42.0_f64);
-    //~^ ERROR mismatched types
-    foo::<f32>(42.0_f32);
-
-    foo::<u32>(42_u8 as u16);
-    //~^ ERROR mismatched types
-    foo::<i32>(-42_i8);
-    //~^ ERROR mismatched types
-}
diff --git a/src/test/ui/numeric/numeric-suffix.stderr b/src/test/ui/numeric/numeric-suffix.stderr
deleted file mode 100644
index b829946e522..00000000000
--- a/src/test/ui/numeric/numeric-suffix.stderr
+++ /dev/null
@@ -1,1477 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:7:18
-   |
-LL |     foo::<usize>(42_u64);
-   |                  ^^^^^^ expected `usize`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:9:18
-   |
-LL |     foo::<usize>(42_u32);
-   |                  ^^^^^^ expected `usize`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:11:18
-   |
-LL |     foo::<usize>(42_u16);
-   |                  ^^^^^^ expected `usize`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:13:18
-   |
-LL |     foo::<usize>(42_u8);
-   |                  ^^^^^ expected `usize`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:15:18
-   |
-LL |     foo::<usize>(42_isize);
-   |                  ^^^^^^^^ expected `usize`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:17:18
-   |
-LL |     foo::<usize>(42_i64);
-   |                  ^^^^^^ expected `usize`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:19:18
-   |
-LL |     foo::<usize>(42_i32);
-   |                  ^^^^^^ expected `usize`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:21:18
-   |
-LL |     foo::<usize>(42_i16);
-   |                  ^^^^^^ expected `usize`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:23:18
-   |
-LL |     foo::<usize>(42_i8);
-   |                  ^^^^^ expected `usize`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `usize`
-   |
-LL |     foo::<usize>(42_usize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:25:18
-   |
-LL |     foo::<usize>(42.0_f64);
-   |                  ^^^^^^^^ expected `usize`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `usize`
-   |
-LL |     foo::<usize>(42usize);
-   |                    ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:27:18
-   |
-LL |     foo::<usize>(42.0_f32);
-   |                  ^^^^^^^^ expected `usize`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `usize`
-   |
-LL |     foo::<usize>(42usize);
-   |                    ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:30:18
-   |
-LL |     foo::<isize>(42_usize);
-   |                  ^^^^^^^^ expected `isize`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:32:18
-   |
-LL |     foo::<isize>(42_u64);
-   |                  ^^^^^^ expected `isize`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:34:18
-   |
-LL |     foo::<isize>(42_u32);
-   |                  ^^^^^^ expected `isize`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:36:18
-   |
-LL |     foo::<isize>(42_u16);
-   |                  ^^^^^^ expected `isize`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:38:18
-   |
-LL |     foo::<isize>(42_u8);
-   |                  ^^^^^ expected `isize`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:41:18
-   |
-LL |     foo::<isize>(42_i64);
-   |                  ^^^^^^ expected `isize`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:43:18
-   |
-LL |     foo::<isize>(42_i32);
-   |                  ^^^^^^ expected `isize`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:45:18
-   |
-LL |     foo::<isize>(42_i16);
-   |                  ^^^^^^ expected `isize`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:47:18
-   |
-LL |     foo::<isize>(42_i8);
-   |                  ^^^^^ expected `isize`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `isize`
-   |
-LL |     foo::<isize>(42_isize);
-   |                     ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:49:18
-   |
-LL |     foo::<isize>(42.0_f64);
-   |                  ^^^^^^^^ expected `isize`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `isize`
-   |
-LL |     foo::<isize>(42isize);
-   |                    ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:51:18
-   |
-LL |     foo::<isize>(42.0_f32);
-   |                  ^^^^^^^^ expected `isize`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `isize`
-   |
-LL |     foo::<isize>(42isize);
-   |                    ~~~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:54:16
-   |
-LL |     foo::<u64>(42_usize);
-   |                ^^^^^^^^ expected `u64`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:57:16
-   |
-LL |     foo::<u64>(42_u32);
-   |                ^^^^^^ expected `u64`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:59:16
-   |
-LL |     foo::<u64>(42_u16);
-   |                ^^^^^^ expected `u64`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:61:16
-   |
-LL |     foo::<u64>(42_u8);
-   |                ^^^^^ expected `u64`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:63:16
-   |
-LL |     foo::<u64>(42_isize);
-   |                ^^^^^^^^ expected `u64`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:65:16
-   |
-LL |     foo::<u64>(42_i64);
-   |                ^^^^^^ expected `u64`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:67:16
-   |
-LL |     foo::<u64>(42_i32);
-   |                ^^^^^^ expected `u64`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:69:16
-   |
-LL |     foo::<u64>(42_i16);
-   |                ^^^^^^ expected `u64`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:71:16
-   |
-LL |     foo::<u64>(42_i8);
-   |                ^^^^^ expected `u64`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `u64`
-   |
-LL |     foo::<u64>(42_u64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:73:16
-   |
-LL |     foo::<u64>(42.0_f64);
-   |                ^^^^^^^^ expected `u64`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `u64`
-   |
-LL |     foo::<u64>(42u64);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:75:16
-   |
-LL |     foo::<u64>(42.0_f32);
-   |                ^^^^^^^^ expected `u64`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `u64`
-   |
-LL |     foo::<u64>(42u64);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:78:16
-   |
-LL |     foo::<i64>(42_usize);
-   |                ^^^^^^^^ expected `i64`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:80:16
-   |
-LL |     foo::<i64>(42_u64);
-   |                ^^^^^^ expected `i64`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:82:16
-   |
-LL |     foo::<i64>(42_u32);
-   |                ^^^^^^ expected `i64`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:84:16
-   |
-LL |     foo::<i64>(42_u16);
-   |                ^^^^^^ expected `i64`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:86:16
-   |
-LL |     foo::<i64>(42_u8);
-   |                ^^^^^ expected `i64`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:88:16
-   |
-LL |     foo::<i64>(42_isize);
-   |                ^^^^^^^^ expected `i64`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:91:16
-   |
-LL |     foo::<i64>(42_i32);
-   |                ^^^^^^ expected `i64`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:93:16
-   |
-LL |     foo::<i64>(42_i16);
-   |                ^^^^^^ expected `i64`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:95:16
-   |
-LL |     foo::<i64>(42_i8);
-   |                ^^^^^ expected `i64`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `i64`
-   |
-LL |     foo::<i64>(42_i64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:97:16
-   |
-LL |     foo::<i64>(42.0_f64);
-   |                ^^^^^^^^ expected `i64`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `i64`
-   |
-LL |     foo::<i64>(42i64);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:99:16
-   |
-LL |     foo::<i64>(42.0_f32);
-   |                ^^^^^^^^ expected `i64`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `i64`
-   |
-LL |     foo::<i64>(42i64);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:102:16
-   |
-LL |     foo::<u32>(42_usize);
-   |                ^^^^^^^^ expected `u32`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:104:16
-   |
-LL |     foo::<u32>(42_u64);
-   |                ^^^^^^ expected `u32`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:107:16
-   |
-LL |     foo::<u32>(42_u16);
-   |                ^^^^^^ expected `u32`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:109:16
-   |
-LL |     foo::<u32>(42_u8);
-   |                ^^^^^ expected `u32`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:111:16
-   |
-LL |     foo::<u32>(42_isize);
-   |                ^^^^^^^^ expected `u32`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:113:16
-   |
-LL |     foo::<u32>(42_i64);
-   |                ^^^^^^ expected `u32`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:115:16
-   |
-LL |     foo::<u32>(42_i32);
-   |                ^^^^^^ expected `u32`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:117:16
-   |
-LL |     foo::<u32>(42_i16);
-   |                ^^^^^^ expected `u32`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:119:16
-   |
-LL |     foo::<u32>(42_i8);
-   |                ^^^^^ expected `u32`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `u32`
-   |
-LL |     foo::<u32>(42_u32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:121:16
-   |
-LL |     foo::<u32>(42.0_f64);
-   |                ^^^^^^^^ expected `u32`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `u32`
-   |
-LL |     foo::<u32>(42u32);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:123:16
-   |
-LL |     foo::<u32>(42.0_f32);
-   |                ^^^^^^^^ expected `u32`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `u32`
-   |
-LL |     foo::<u32>(42u32);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:126:16
-   |
-LL |     foo::<i32>(42_usize);
-   |                ^^^^^^^^ expected `i32`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:128:16
-   |
-LL |     foo::<i32>(42_u64);
-   |                ^^^^^^ expected `i32`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:130:16
-   |
-LL |     foo::<i32>(42_u32);
-   |                ^^^^^^ expected `i32`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:132:16
-   |
-LL |     foo::<i32>(42_u16);
-   |                ^^^^^^ expected `i32`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:134:16
-   |
-LL |     foo::<i32>(42_u8);
-   |                ^^^^^ expected `i32`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:136:16
-   |
-LL |     foo::<i32>(42_isize);
-   |                ^^^^^^^^ expected `i32`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:138:16
-   |
-LL |     foo::<i32>(42_i64);
-   |                ^^^^^^ expected `i32`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:141:16
-   |
-LL |     foo::<i32>(42_i16);
-   |                ^^^^^^ expected `i32`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:143:16
-   |
-LL |     foo::<i32>(42_i8);
-   |                ^^^^^ expected `i32`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `i32`
-   |
-LL |     foo::<i32>(42_i32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:145:16
-   |
-LL |     foo::<i32>(42.0_f64);
-   |                ^^^^^^^^ expected `i32`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `i32`
-   |
-LL |     foo::<i32>(42i32);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:147:16
-   |
-LL |     foo::<i32>(42.0_f32);
-   |                ^^^^^^^^ expected `i32`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `i32`
-   |
-LL |     foo::<i32>(42i32);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:150:16
-   |
-LL |     foo::<u16>(42_usize);
-   |                ^^^^^^^^ expected `u16`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:152:16
-   |
-LL |     foo::<u16>(42_u64);
-   |                ^^^^^^ expected `u16`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:154:16
-   |
-LL |     foo::<u16>(42_u32);
-   |                ^^^^^^ expected `u16`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:157:16
-   |
-LL |     foo::<u16>(42_u8);
-   |                ^^^^^ expected `u16`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:159:16
-   |
-LL |     foo::<u16>(42_isize);
-   |                ^^^^^^^^ expected `u16`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:161:16
-   |
-LL |     foo::<u16>(42_i64);
-   |                ^^^^^^ expected `u16`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:163:16
-   |
-LL |     foo::<u16>(42_i32);
-   |                ^^^^^^ expected `u16`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:165:16
-   |
-LL |     foo::<u16>(42_i16);
-   |                ^^^^^^ expected `u16`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:167:16
-   |
-LL |     foo::<u16>(42_i8);
-   |                ^^^^^ expected `u16`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `u16`
-   |
-LL |     foo::<u16>(42_u16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:169:16
-   |
-LL |     foo::<u16>(42.0_f64);
-   |                ^^^^^^^^ expected `u16`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `u16`
-   |
-LL |     foo::<u16>(42u16);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:171:16
-   |
-LL |     foo::<u16>(42.0_f32);
-   |                ^^^^^^^^ expected `u16`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `u16`
-   |
-LL |     foo::<u16>(42u16);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:174:16
-   |
-LL |     foo::<i16>(42_usize);
-   |                ^^^^^^^^ expected `i16`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:176:16
-   |
-LL |     foo::<i16>(42_u64);
-   |                ^^^^^^ expected `i16`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:178:16
-   |
-LL |     foo::<i16>(42_u32);
-   |                ^^^^^^ expected `i16`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:180:16
-   |
-LL |     foo::<i16>(42_u16);
-   |                ^^^^^^ expected `i16`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:182:16
-   |
-LL |     foo::<i16>(42_u8);
-   |                ^^^^^ expected `i16`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:184:16
-   |
-LL |     foo::<i16>(42_isize);
-   |                ^^^^^^^^ expected `i16`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:186:16
-   |
-LL |     foo::<i16>(42_i64);
-   |                ^^^^^^ expected `i16`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:188:16
-   |
-LL |     foo::<i16>(42_i32);
-   |                ^^^^^^ expected `i16`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:191:16
-   |
-LL |     foo::<i16>(42_i8);
-   |                ^^^^^ expected `i16`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `i16`
-   |
-LL |     foo::<i16>(42_i16);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:193:16
-   |
-LL |     foo::<i16>(42.0_f64);
-   |                ^^^^^^^^ expected `i16`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `i16`
-   |
-LL |     foo::<i16>(42i16);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:195:16
-   |
-LL |     foo::<i16>(42.0_f32);
-   |                ^^^^^^^^ expected `i16`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `i16`
-   |
-LL |     foo::<i16>(42i16);
-   |                  ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:198:15
-   |
-LL |     foo::<u8>(42_usize);
-   |               ^^^^^^^^ expected `u8`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:200:15
-   |
-LL |     foo::<u8>(42_u64);
-   |               ^^^^^^ expected `u8`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:202:15
-   |
-LL |     foo::<u8>(42_u32);
-   |               ^^^^^^ expected `u8`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:204:15
-   |
-LL |     foo::<u8>(42_u16);
-   |               ^^^^^^ expected `u8`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:207:15
-   |
-LL |     foo::<u8>(42_isize);
-   |               ^^^^^^^^ expected `u8`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:209:15
-   |
-LL |     foo::<u8>(42_i64);
-   |               ^^^^^^ expected `u8`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:211:15
-   |
-LL |     foo::<u8>(42_i32);
-   |               ^^^^^^ expected `u8`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:213:15
-   |
-LL |     foo::<u8>(42_i16);
-   |               ^^^^^^ expected `u8`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:215:15
-   |
-LL |     foo::<u8>(42_i8);
-   |               ^^^^^ expected `u8`, found `i8`
-   |
-help: change the type of the numeric literal from `i8` to `u8`
-   |
-LL |     foo::<u8>(42_u8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:217:15
-   |
-LL |     foo::<u8>(42.0_f64);
-   |               ^^^^^^^^ expected `u8`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `u8`
-   |
-LL |     foo::<u8>(42u8);
-   |                 ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:219:15
-   |
-LL |     foo::<u8>(42.0_f32);
-   |               ^^^^^^^^ expected `u8`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `u8`
-   |
-LL |     foo::<u8>(42u8);
-   |                 ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:222:15
-   |
-LL |     foo::<i8>(42_usize);
-   |               ^^^^^^^^ expected `i8`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:224:15
-   |
-LL |     foo::<i8>(42_u64);
-   |               ^^^^^^ expected `i8`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:226:15
-   |
-LL |     foo::<i8>(42_u32);
-   |               ^^^^^^ expected `i8`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:228:15
-   |
-LL |     foo::<i8>(42_u16);
-   |               ^^^^^^ expected `i8`, found `u16`
-   |
-help: change the type of the numeric literal from `u16` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:230:15
-   |
-LL |     foo::<i8>(42_u8);
-   |               ^^^^^ expected `i8`, found `u8`
-   |
-help: change the type of the numeric literal from `u8` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:232:15
-   |
-LL |     foo::<i8>(42_isize);
-   |               ^^^^^^^^ expected `i8`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:234:15
-   |
-LL |     foo::<i8>(42_i64);
-   |               ^^^^^^ expected `i8`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:236:15
-   |
-LL |     foo::<i8>(42_i32);
-   |               ^^^^^^ expected `i8`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:238:15
-   |
-LL |     foo::<i8>(42_i16);
-   |               ^^^^^^ expected `i8`, found `i16`
-   |
-help: change the type of the numeric literal from `i16` to `i8`
-   |
-LL |     foo::<i8>(42_i8);
-   |                  ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:241:15
-   |
-LL |     foo::<i8>(42.0_f64);
-   |               ^^^^^^^^ expected `i8`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `i8`
-   |
-LL |     foo::<i8>(42i8);
-   |                 ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:243:15
-   |
-LL |     foo::<i8>(42.0_f32);
-   |               ^^^^^^^^ expected `i8`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `i8`
-   |
-LL |     foo::<i8>(42i8);
-   |                 ~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:246:16
-   |
-LL |     foo::<f64>(42_usize);
-   |                ^^^^^^^^ expected `f64`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `f64`
-   |
-LL |     foo::<f64>(42_f64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:248:16
-   |
-LL |     foo::<f64>(42_u64);
-   |                ^^^^^^ expected `f64`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `f64`
-   |
-LL |     foo::<f64>(42_f64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:250:16
-   |
-LL |     foo::<f64>(42_u32);
-   |                ^^^^^^ expected `f64`, found `u32`
-   |
-help: you can convert a `u32` to an `f64`, producing the floating point representation of the integer
-   |
-LL |     foo::<f64>(42_u32.into());
-   |                      +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:252:16
-   |
-LL |     foo::<f64>(42_u16);
-   |                ^^^^^^ expected `f64`, found `u16`
-   |
-help: you can convert a `u16` to an `f64`, producing the floating point representation of the integer
-   |
-LL |     foo::<f64>(42_u16.into());
-   |                      +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:254:16
-   |
-LL |     foo::<f64>(42_u8);
-   |                ^^^^^ expected `f64`, found `u8`
-   |
-help: you can convert a `u8` to an `f64`, producing the floating point representation of the integer
-   |
-LL |     foo::<f64>(42_u8.into());
-   |                     +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:256:16
-   |
-LL |     foo::<f64>(42_isize);
-   |                ^^^^^^^^ expected `f64`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `f64`
-   |
-LL |     foo::<f64>(42_f64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:258:16
-   |
-LL |     foo::<f64>(42_i64);
-   |                ^^^^^^ expected `f64`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `f64`
-   |
-LL |     foo::<f64>(42_f64);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:260:16
-   |
-LL |     foo::<f64>(42_i32);
-   |                ^^^^^^ expected `f64`, found `i32`
-   |
-help: you can convert an `i32` to an `f64`, producing the floating point representation of the integer
-   |
-LL |     foo::<f64>(42_i32.into());
-   |                      +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:262:16
-   |
-LL |     foo::<f64>(42_i16);
-   |                ^^^^^^ expected `f64`, found `i16`
-   |
-help: you can convert an `i16` to an `f64`, producing the floating point representation of the integer
-   |
-LL |     foo::<f64>(42_i16.into());
-   |                      +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:264:16
-   |
-LL |     foo::<f64>(42_i8);
-   |                ^^^^^ expected `f64`, found `i8`
-   |
-help: you can convert an `i8` to an `f64`, producing the floating point representation of the integer
-   |
-LL |     foo::<f64>(42_i8.into());
-   |                     +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:267:16
-   |
-LL |     foo::<f64>(42.0_f32);
-   |                ^^^^^^^^ expected `f64`, found `f32`
-   |
-help: change the type of the numeric literal from `f32` to `f64`
-   |
-LL |     foo::<f64>(42.0_f64);
-   |                     ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:270:16
-   |
-LL |     foo::<f32>(42_usize);
-   |                ^^^^^^^^ expected `f32`, found `usize`
-   |
-help: change the type of the numeric literal from `usize` to `f32`
-   |
-LL |     foo::<f32>(42_f32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:272:16
-   |
-LL |     foo::<f32>(42_u64);
-   |                ^^^^^^ expected `f32`, found `u64`
-   |
-help: change the type of the numeric literal from `u64` to `f32`
-   |
-LL |     foo::<f32>(42_f32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:274:16
-   |
-LL |     foo::<f32>(42_u32);
-   |                ^^^^^^ expected `f32`, found `u32`
-   |
-help: change the type of the numeric literal from `u32` to `f32`
-   |
-LL |     foo::<f32>(42_f32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:276:16
-   |
-LL |     foo::<f32>(42_u16);
-   |                ^^^^^^ expected `f32`, found `u16`
-   |
-help: you can convert a `u16` to an `f32`, producing the floating point representation of the integer
-   |
-LL |     foo::<f32>(42_u16.into());
-   |                      +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:278:16
-   |
-LL |     foo::<f32>(42_u8);
-   |                ^^^^^ expected `f32`, found `u8`
-   |
-help: you can convert a `u8` to an `f32`, producing the floating point representation of the integer
-   |
-LL |     foo::<f32>(42_u8.into());
-   |                     +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:280:16
-   |
-LL |     foo::<f32>(42_isize);
-   |                ^^^^^^^^ expected `f32`, found `isize`
-   |
-help: change the type of the numeric literal from `isize` to `f32`
-   |
-LL |     foo::<f32>(42_f32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:282:16
-   |
-LL |     foo::<f32>(42_i64);
-   |                ^^^^^^ expected `f32`, found `i64`
-   |
-help: change the type of the numeric literal from `i64` to `f32`
-   |
-LL |     foo::<f32>(42_f32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:284:16
-   |
-LL |     foo::<f32>(42_i32);
-   |                ^^^^^^ expected `f32`, found `i32`
-   |
-help: change the type of the numeric literal from `i32` to `f32`
-   |
-LL |     foo::<f32>(42_f32);
-   |                   ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:286:16
-   |
-LL |     foo::<f32>(42_i16);
-   |                ^^^^^^ expected `f32`, found `i16`
-   |
-help: you can convert an `i16` to an `f32`, producing the floating point representation of the integer
-   |
-LL |     foo::<f32>(42_i16.into());
-   |                      +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:288:16
-   |
-LL |     foo::<f32>(42_i8);
-   |                ^^^^^ expected `f32`, found `i8`
-   |
-help: you can convert an `i8` to an `f32`, producing the floating point representation of the integer
-   |
-LL |     foo::<f32>(42_i8.into());
-   |                     +++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:290:16
-   |
-LL |     foo::<f32>(42.0_f64);
-   |                ^^^^^^^^ expected `f32`, found `f64`
-   |
-help: change the type of the numeric literal from `f64` to `f32`
-   |
-LL |     foo::<f32>(42.0_f32);
-   |                     ~~~
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:294:16
-   |
-LL |     foo::<u32>(42_u8 as u16);
-   |                ^^^^^^^^^^^^ expected `u32`, found `u16`
-   |
-help: you can convert a `u16` to a `u32`
-   |
-LL |     foo::<u32>((42_u8 as u16).into());
-   |                +            ++++++++
-
-error[E0308]: mismatched types
-  --> $DIR/numeric-suffix.rs:296:16
-   |
-LL |     foo::<i32>(-42_i8);
-   |                ^^^^^^ expected `i32`, found `i8`
-   |
-help: you can convert an `i8` to an `i32`
-   |
-LL |     foo::<i32>((-42_i8).into());
-   |                +      ++++++++
-
-error: aborting due to 134 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed
new file mode 100644
index 00000000000..6e8c54df4b6
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs
new file mode 100644
index 00000000000..b47b0ed02e7
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.rs
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<i32>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i32);
+    foo::<i32>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr
new file mode 100644
index 00000000000..f4fb14e7992
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i32.stderr
@@ -0,0 +1,201 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:28:16
+   |
+LL |     foo::<i32>(42_usize);
+   |     ---------- ^^^^^^^^ expected `i32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:32:16
+   |
+LL |     foo::<i32>(42_u64);
+   |     ---------- ^^^^^^ expected `i32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:36:16
+   |
+LL |     foo::<i32>(42_u32);
+   |     ---------- ^^^^^^ expected `i32`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:40:16
+   |
+LL |     foo::<i32>(42_u16);
+   |     ---------- ^^^^^^ expected `i32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:44:16
+   |
+LL |     foo::<i32>(42_u8);
+   |     ---------- ^^^^^ expected `i32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:48:16
+   |
+LL |     foo::<i32>(42_isize);
+   |     ---------- ^^^^^^^^ expected `i32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:52:16
+   |
+LL |     foo::<i32>(42_i64);
+   |     ---------- ^^^^^^ expected `i32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:57:16
+   |
+LL |     foo::<i32>(42_i16);
+   |     ---------- ^^^^^^ expected `i32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:61:16
+   |
+LL |     foo::<i32>(42_i8);
+   |     ---------- ^^^^^ expected `i32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `i32`
+   |
+LL |     foo::<i32>(42_i32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:65:16
+   |
+LL |     foo::<i32>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `i32`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `i32`
+   |
+LL |     foo::<i32>(42i32);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i32.rs:69:16
+   |
+LL |     foo::<i32>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `i32`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `i32`
+   |
+LL |     foo::<i32>(42i32);
+   |                  ~~~
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed
new file mode 100644
index 00000000000..03821cd4470
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs
new file mode 100644
index 00000000000..629fe7e742c
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.rs
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<i64>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i64);
+    foo::<i64>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i64>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr
new file mode 100644
index 00000000000..47efe9f08bb
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-i64.stderr
@@ -0,0 +1,201 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:28:16
+   |
+LL |     foo::<i64>(42_usize);
+   |     ---------- ^^^^^^^^ expected `i64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:32:16
+   |
+LL |     foo::<i64>(42_u64);
+   |     ---------- ^^^^^^ expected `i64`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:36:16
+   |
+LL |     foo::<i64>(42_u32);
+   |     ---------- ^^^^^^ expected `i64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:40:16
+   |
+LL |     foo::<i64>(42_u16);
+   |     ---------- ^^^^^^ expected `i64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:44:16
+   |
+LL |     foo::<i64>(42_u8);
+   |     ---------- ^^^^^ expected `i64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:48:16
+   |
+LL |     foo::<i64>(42_isize);
+   |     ---------- ^^^^^^^^ expected `i64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:53:16
+   |
+LL |     foo::<i64>(42_i32);
+   |     ---------- ^^^^^^ expected `i64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:57:16
+   |
+LL |     foo::<i64>(42_i16);
+   |     ---------- ^^^^^^ expected `i64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:61:16
+   |
+LL |     foo::<i64>(42_i8);
+   |     ---------- ^^^^^ expected `i64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `i64`
+   |
+LL |     foo::<i64>(42_i64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:65:16
+   |
+LL |     foo::<i64>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `i64`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `i64`
+   |
+LL |     foo::<i64>(42i64);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-i64.rs:69:16
+   |
+LL |     foo::<i64>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `i64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-i64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `i64`
+   |
+LL |     foo::<i64>(42i64);
+   |                  ~~~
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed
new file mode 100644
index 00000000000..faed65ca410
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs
new file mode 100644
index 00000000000..df0b4cb6204
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.rs
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<isize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_isize);
+    foo::<isize>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<isize>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr
new file mode 100644
index 00000000000..28b79413f68
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-isize.stderr
@@ -0,0 +1,201 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:28:18
+   |
+LL |     foo::<isize>(42_usize);
+   |     ------------ ^^^^^^^^ expected `isize`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:32:18
+   |
+LL |     foo::<isize>(42_u64);
+   |     ------------ ^^^^^^ expected `isize`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:36:18
+   |
+LL |     foo::<isize>(42_u32);
+   |     ------------ ^^^^^^ expected `isize`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:40:18
+   |
+LL |     foo::<isize>(42_u16);
+   |     ------------ ^^^^^^ expected `isize`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:44:18
+   |
+LL |     foo::<isize>(42_u8);
+   |     ------------ ^^^^^ expected `isize`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:49:18
+   |
+LL |     foo::<isize>(42_i64);
+   |     ------------ ^^^^^^ expected `isize`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:53:18
+   |
+LL |     foo::<isize>(42_i32);
+   |     ------------ ^^^^^^ expected `isize`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:57:18
+   |
+LL |     foo::<isize>(42_i16);
+   |     ------------ ^^^^^^ expected `isize`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:61:18
+   |
+LL |     foo::<isize>(42_i8);
+   |     ------------ ^^^^^ expected `isize`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `isize`
+   |
+LL |     foo::<isize>(42_isize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:65:18
+   |
+LL |     foo::<isize>(42.0_f64);
+   |     ------------ ^^^^^^^^ expected `isize`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `isize`
+   |
+LL |     foo::<isize>(42isize);
+   |                    ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-isize.rs:69:18
+   |
+LL |     foo::<isize>(42.0_f32);
+   |     ------------ ^^^^^^^^ expected `isize`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-isize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `isize`
+   |
+LL |     foo::<isize>(42isize);
+   |                    ~~~~~
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed
new file mode 100644
index 00000000000..5955829e72c
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs
new file mode 100644
index 00000000000..5c303036a79
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.rs
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<u32>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u32);
+    foo::<u32>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u32>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr
new file mode 100644
index 00000000000..d966893a83b
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u32.stderr
@@ -0,0 +1,201 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:28:16
+   |
+LL |     foo::<u32>(42_usize);
+   |     ---------- ^^^^^^^^ expected `u32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:32:16
+   |
+LL |     foo::<u32>(42_u64);
+   |     ---------- ^^^^^^ expected `u32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:37:16
+   |
+LL |     foo::<u32>(42_u16);
+   |     ---------- ^^^^^^ expected `u32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:41:16
+   |
+LL |     foo::<u32>(42_u8);
+   |     ---------- ^^^^^ expected `u32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:45:16
+   |
+LL |     foo::<u32>(42_isize);
+   |     ---------- ^^^^^^^^ expected `u32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:49:16
+   |
+LL |     foo::<u32>(42_i64);
+   |     ---------- ^^^^^^ expected `u32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:53:16
+   |
+LL |     foo::<u32>(42_i32);
+   |     ---------- ^^^^^^ expected `u32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:57:16
+   |
+LL |     foo::<u32>(42_i16);
+   |     ---------- ^^^^^^ expected `u32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:61:16
+   |
+LL |     foo::<u32>(42_i8);
+   |     ---------- ^^^^^ expected `u32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `u32`
+   |
+LL |     foo::<u32>(42_u32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:65:16
+   |
+LL |     foo::<u32>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `u32`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `u32`
+   |
+LL |     foo::<u32>(42u32);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u32.rs:69:16
+   |
+LL |     foo::<u32>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `u32`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u32.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `u32`
+   |
+LL |     foo::<u32>(42u32);
+   |                  ~~~
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed
new file mode 100644
index 00000000000..4623c211c1c
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs
new file mode 100644
index 00000000000..3e9995c7496
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.rs
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<u64>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u64);
+    foo::<u64>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u64>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr
new file mode 100644
index 00000000000..ff332fa914d
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-u64.stderr
@@ -0,0 +1,201 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:28:16
+   |
+LL |     foo::<u64>(42_usize);
+   |     ---------- ^^^^^^^^ expected `u64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:33:16
+   |
+LL |     foo::<u64>(42_u32);
+   |     ---------- ^^^^^^ expected `u64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:37:16
+   |
+LL |     foo::<u64>(42_u16);
+   |     ---------- ^^^^^^ expected `u64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:41:16
+   |
+LL |     foo::<u64>(42_u8);
+   |     ---------- ^^^^^ expected `u64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:45:16
+   |
+LL |     foo::<u64>(42_isize);
+   |     ---------- ^^^^^^^^ expected `u64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:49:16
+   |
+LL |     foo::<u64>(42_i64);
+   |     ---------- ^^^^^^ expected `u64`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:53:16
+   |
+LL |     foo::<u64>(42_i32);
+   |     ---------- ^^^^^^ expected `u64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:57:16
+   |
+LL |     foo::<u64>(42_i16);
+   |     ---------- ^^^^^^ expected `u64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:61:16
+   |
+LL |     foo::<u64>(42_i8);
+   |     ---------- ^^^^^ expected `u64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `u64`
+   |
+LL |     foo::<u64>(42_u64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:65:16
+   |
+LL |     foo::<u64>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `u64`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `u64`
+   |
+LL |     foo::<u64>(42u64);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-u64.rs:69:16
+   |
+LL |     foo::<u64>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `u64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-u64.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `u64`
+   |
+LL |     foo::<u64>(42u64);
+   |                  ~~~
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed
new file mode 100644
index 00000000000..6cb5243ca84
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.fixed
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<usize>(42_usize);
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs
new file mode 100644
index 00000000000..a2304ba26c6
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.rs
@@ -0,0 +1,73 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+fn main() {
+    foo::<usize>(42_usize);
+    foo::<usize>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<usize>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr
new file mode 100644
index 00000000000..4889abee69c
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix-usize.stderr
@@ -0,0 +1,201 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:29:18
+   |
+LL |     foo::<usize>(42_u64);
+   |     ------------ ^^^^^^ expected `usize`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:33:18
+   |
+LL |     foo::<usize>(42_u32);
+   |     ------------ ^^^^^^ expected `usize`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:37:18
+   |
+LL |     foo::<usize>(42_u16);
+   |     ------------ ^^^^^^ expected `usize`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:41:18
+   |
+LL |     foo::<usize>(42_u8);
+   |     ------------ ^^^^^ expected `usize`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:45:18
+   |
+LL |     foo::<usize>(42_isize);
+   |     ------------ ^^^^^^^^ expected `usize`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:49:18
+   |
+LL |     foo::<usize>(42_i64);
+   |     ------------ ^^^^^^ expected `usize`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:53:18
+   |
+LL |     foo::<usize>(42_i32);
+   |     ------------ ^^^^^^ expected `usize`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:57:18
+   |
+LL |     foo::<usize>(42_i16);
+   |     ------------ ^^^^^^ expected `usize`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:61:18
+   |
+LL |     foo::<usize>(42_i8);
+   |     ------------ ^^^^^ expected `usize`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `usize`
+   |
+LL |     foo::<usize>(42_usize);
+   |                     ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:65:18
+   |
+LL |     foo::<usize>(42.0_f64);
+   |     ------------ ^^^^^^^^ expected `usize`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `usize`
+   |
+LL |     foo::<usize>(42usize);
+   |                    ~~~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix-usize.rs:69:18
+   |
+LL |     foo::<usize>(42.0_f32);
+   |     ------------ ^^^^^^^^ expected `usize`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix-usize.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `usize`
+   |
+LL |     foo::<usize>(42usize);
+   |                    ~~~~~
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed b/src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed
new file mode 100644
index 00000000000..69934db217b
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix.fixed
@@ -0,0 +1,427 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+
+fn main() {
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    foo::<i16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    foo::<i8>(42i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<f64>(42_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u32.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u16.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u8.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i32.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i16.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i8.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42.0_f64);
+    foo::<f64>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<f32>(42_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_u16.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_u8.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_i16.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_i8.into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42.0_f32);
+
+    foo::<u32>((42_u8 as u16).into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>((-42_i8).into());
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix.rs b/src/test/ui/numeric/numeric-suffix/numeric-suffix.rs
new file mode 100644
index 00000000000..dabf43f8204
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix.rs
@@ -0,0 +1,427 @@
+// run-rustfix
+
+fn foo<N>(_x: N) {}
+//~^ NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE function defined here
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+//~| NOTE
+
+
+fn main() {
+    foo::<u16>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_u16);
+    foo::<u16>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u16>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<i16>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42_i16);
+    foo::<i16>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i16>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<u8>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_u8);
+    foo::<u8>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<u8>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<i8>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42_i8);
+    foo::<i8>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i8>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<f64>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f64>(42.0_f64);
+    foo::<f64>(42.0_f32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+
+    foo::<f32>(42_usize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_u64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_u32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_u8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_isize);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_i64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_i32);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_i16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42.0_f64);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<f32>(42.0_f32);
+
+    foo::<u32>(42_u8 as u16);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+    foo::<i32>(-42_i8);
+    //~^ ERROR mismatched types
+    //~| NOTE expected
+    //~| NOTE arguments
+}
diff --git a/src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr b/src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr
new file mode 100644
index 00000000000..e05913b9c62
--- /dev/null
+++ b/src/test/ui/numeric/numeric-suffix/numeric-suffix.stderr
@@ -0,0 +1,1227 @@
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:143:16
+   |
+LL |     foo::<u16>(42_usize);
+   |     ---------- ^^^^^^^^ expected `u16`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:147:16
+   |
+LL |     foo::<u16>(42_u64);
+   |     ---------- ^^^^^^ expected `u16`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:151:16
+   |
+LL |     foo::<u16>(42_u32);
+   |     ---------- ^^^^^^ expected `u16`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:156:16
+   |
+LL |     foo::<u16>(42_u8);
+   |     ---------- ^^^^^ expected `u16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:160:16
+   |
+LL |     foo::<u16>(42_isize);
+   |     ---------- ^^^^^^^^ expected `u16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:164:16
+   |
+LL |     foo::<u16>(42_i64);
+   |     ---------- ^^^^^^ expected `u16`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:168:16
+   |
+LL |     foo::<u16>(42_i32);
+   |     ---------- ^^^^^^ expected `u16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:172:16
+   |
+LL |     foo::<u16>(42_i16);
+   |     ---------- ^^^^^^ expected `u16`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:176:16
+   |
+LL |     foo::<u16>(42_i8);
+   |     ---------- ^^^^^ expected `u16`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `u16`
+   |
+LL |     foo::<u16>(42_u16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:180:16
+   |
+LL |     foo::<u16>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `u16`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `u16`
+   |
+LL |     foo::<u16>(42u16);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:184:16
+   |
+LL |     foo::<u16>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `u16`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `u16`
+   |
+LL |     foo::<u16>(42u16);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:189:16
+   |
+LL |     foo::<i16>(42_usize);
+   |     ---------- ^^^^^^^^ expected `i16`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:193:16
+   |
+LL |     foo::<i16>(42_u64);
+   |     ---------- ^^^^^^ expected `i16`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:197:16
+   |
+LL |     foo::<i16>(42_u32);
+   |     ---------- ^^^^^^ expected `i16`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:201:16
+   |
+LL |     foo::<i16>(42_u16);
+   |     ---------- ^^^^^^ expected `i16`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:205:16
+   |
+LL |     foo::<i16>(42_u8);
+   |     ---------- ^^^^^ expected `i16`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:209:16
+   |
+LL |     foo::<i16>(42_isize);
+   |     ---------- ^^^^^^^^ expected `i16`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:213:16
+   |
+LL |     foo::<i16>(42_i64);
+   |     ---------- ^^^^^^ expected `i16`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:217:16
+   |
+LL |     foo::<i16>(42_i32);
+   |     ---------- ^^^^^^ expected `i16`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:222:16
+   |
+LL |     foo::<i16>(42_i8);
+   |     ---------- ^^^^^ expected `i16`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `i16`
+   |
+LL |     foo::<i16>(42_i16);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:226:16
+   |
+LL |     foo::<i16>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `i16`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `i16`
+   |
+LL |     foo::<i16>(42i16);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:230:16
+   |
+LL |     foo::<i16>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `i16`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `i16`
+   |
+LL |     foo::<i16>(42i16);
+   |                  ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:235:15
+   |
+LL |     foo::<u8>(42_usize);
+   |     --------- ^^^^^^^^ expected `u8`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:239:15
+   |
+LL |     foo::<u8>(42_u64);
+   |     --------- ^^^^^^ expected `u8`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:243:15
+   |
+LL |     foo::<u8>(42_u32);
+   |     --------- ^^^^^^ expected `u8`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:247:15
+   |
+LL |     foo::<u8>(42_u16);
+   |     --------- ^^^^^^ expected `u8`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:252:15
+   |
+LL |     foo::<u8>(42_isize);
+   |     --------- ^^^^^^^^ expected `u8`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:256:15
+   |
+LL |     foo::<u8>(42_i64);
+   |     --------- ^^^^^^ expected `u8`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:260:15
+   |
+LL |     foo::<u8>(42_i32);
+   |     --------- ^^^^^^ expected `u8`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:264:15
+   |
+LL |     foo::<u8>(42_i16);
+   |     --------- ^^^^^^ expected `u8`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:268:15
+   |
+LL |     foo::<u8>(42_i8);
+   |     --------- ^^^^^ expected `u8`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i8` to `u8`
+   |
+LL |     foo::<u8>(42_u8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:272:15
+   |
+LL |     foo::<u8>(42.0_f64);
+   |     --------- ^^^^^^^^ expected `u8`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `u8`
+   |
+LL |     foo::<u8>(42u8);
+   |                 ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:276:15
+   |
+LL |     foo::<u8>(42.0_f32);
+   |     --------- ^^^^^^^^ expected `u8`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `u8`
+   |
+LL |     foo::<u8>(42u8);
+   |                 ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:281:15
+   |
+LL |     foo::<i8>(42_usize);
+   |     --------- ^^^^^^^^ expected `i8`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:285:15
+   |
+LL |     foo::<i8>(42_u64);
+   |     --------- ^^^^^^ expected `i8`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:289:15
+   |
+LL |     foo::<i8>(42_u32);
+   |     --------- ^^^^^^ expected `i8`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:293:15
+   |
+LL |     foo::<i8>(42_u16);
+   |     --------- ^^^^^^ expected `i8`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u16` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:297:15
+   |
+LL |     foo::<i8>(42_u8);
+   |     --------- ^^^^^ expected `i8`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u8` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:301:15
+   |
+LL |     foo::<i8>(42_isize);
+   |     --------- ^^^^^^^^ expected `i8`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:305:15
+   |
+LL |     foo::<i8>(42_i64);
+   |     --------- ^^^^^^ expected `i8`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:309:15
+   |
+LL |     foo::<i8>(42_i32);
+   |     --------- ^^^^^^ expected `i8`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:313:15
+   |
+LL |     foo::<i8>(42_i16);
+   |     --------- ^^^^^^ expected `i8`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i16` to `i8`
+   |
+LL |     foo::<i8>(42_i8);
+   |                  ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:318:15
+   |
+LL |     foo::<i8>(42.0_f64);
+   |     --------- ^^^^^^^^ expected `i8`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `i8`
+   |
+LL |     foo::<i8>(42i8);
+   |                 ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:322:15
+   |
+LL |     foo::<i8>(42.0_f32);
+   |     --------- ^^^^^^^^ expected `i8`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `i8`
+   |
+LL |     foo::<i8>(42i8);
+   |                 ~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:327:16
+   |
+LL |     foo::<f64>(42_usize);
+   |     ---------- ^^^^^^^^ expected `f64`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `f64`
+   |
+LL |     foo::<f64>(42_f64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:331:16
+   |
+LL |     foo::<f64>(42_u64);
+   |     ---------- ^^^^^^ expected `f64`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `f64`
+   |
+LL |     foo::<f64>(42_f64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:335:16
+   |
+LL |     foo::<f64>(42_u32);
+   |     ---------- ^^^^^^ expected `f64`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert a `u32` to an `f64`, producing the floating point representation of the integer
+   |
+LL |     foo::<f64>(42_u32.into());
+   |                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:339:16
+   |
+LL |     foo::<f64>(42_u16);
+   |     ---------- ^^^^^^ expected `f64`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert a `u16` to an `f64`, producing the floating point representation of the integer
+   |
+LL |     foo::<f64>(42_u16.into());
+   |                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:343:16
+   |
+LL |     foo::<f64>(42_u8);
+   |     ---------- ^^^^^ expected `f64`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert a `u8` to an `f64`, producing the floating point representation of the integer
+   |
+LL |     foo::<f64>(42_u8.into());
+   |                     +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:347:16
+   |
+LL |     foo::<f64>(42_isize);
+   |     ---------- ^^^^^^^^ expected `f64`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `f64`
+   |
+LL |     foo::<f64>(42_f64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:351:16
+   |
+LL |     foo::<f64>(42_i64);
+   |     ---------- ^^^^^^ expected `f64`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `f64`
+   |
+LL |     foo::<f64>(42_f64);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:355:16
+   |
+LL |     foo::<f64>(42_i32);
+   |     ---------- ^^^^^^ expected `f64`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert an `i32` to an `f64`, producing the floating point representation of the integer
+   |
+LL |     foo::<f64>(42_i32.into());
+   |                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:359:16
+   |
+LL |     foo::<f64>(42_i16);
+   |     ---------- ^^^^^^ expected `f64`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert an `i16` to an `f64`, producing the floating point representation of the integer
+   |
+LL |     foo::<f64>(42_i16.into());
+   |                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:363:16
+   |
+LL |     foo::<f64>(42_i8);
+   |     ---------- ^^^^^ expected `f64`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert an `i8` to an `f64`, producing the floating point representation of the integer
+   |
+LL |     foo::<f64>(42_i8.into());
+   |                     +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:368:16
+   |
+LL |     foo::<f64>(42.0_f32);
+   |     ---------- ^^^^^^^^ expected `f64`, found `f32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f32` to `f64`
+   |
+LL |     foo::<f64>(42.0_f64);
+   |                     ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:373:16
+   |
+LL |     foo::<f32>(42_usize);
+   |     ---------- ^^^^^^^^ expected `f32`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `usize` to `f32`
+   |
+LL |     foo::<f32>(42_f32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:377:16
+   |
+LL |     foo::<f32>(42_u64);
+   |     ---------- ^^^^^^ expected `f32`, found `u64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u64` to `f32`
+   |
+LL |     foo::<f32>(42_f32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:381:16
+   |
+LL |     foo::<f32>(42_u32);
+   |     ---------- ^^^^^^ expected `f32`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `u32` to `f32`
+   |
+LL |     foo::<f32>(42_f32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:385:16
+   |
+LL |     foo::<f32>(42_u16);
+   |     ---------- ^^^^^^ expected `f32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert a `u16` to an `f32`, producing the floating point representation of the integer
+   |
+LL |     foo::<f32>(42_u16.into());
+   |                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:389:16
+   |
+LL |     foo::<f32>(42_u8);
+   |     ---------- ^^^^^ expected `f32`, found `u8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert a `u8` to an `f32`, producing the floating point representation of the integer
+   |
+LL |     foo::<f32>(42_u8.into());
+   |                     +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:393:16
+   |
+LL |     foo::<f32>(42_isize);
+   |     ---------- ^^^^^^^^ expected `f32`, found `isize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `isize` to `f32`
+   |
+LL |     foo::<f32>(42_f32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:397:16
+   |
+LL |     foo::<f32>(42_i64);
+   |     ---------- ^^^^^^ expected `f32`, found `i64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i64` to `f32`
+   |
+LL |     foo::<f32>(42_f32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:401:16
+   |
+LL |     foo::<f32>(42_i32);
+   |     ---------- ^^^^^^ expected `f32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `i32` to `f32`
+   |
+LL |     foo::<f32>(42_f32);
+   |                   ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:405:16
+   |
+LL |     foo::<f32>(42_i16);
+   |     ---------- ^^^^^^ expected `f32`, found `i16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert an `i16` to an `f32`, producing the floating point representation of the integer
+   |
+LL |     foo::<f32>(42_i16.into());
+   |                      +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:409:16
+   |
+LL |     foo::<f32>(42_i8);
+   |     ---------- ^^^^^ expected `f32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert an `i8` to an `f32`, producing the floating point representation of the integer
+   |
+LL |     foo::<f32>(42_i8.into());
+   |                     +++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:413:16
+   |
+LL |     foo::<f32>(42.0_f64);
+   |     ---------- ^^^^^^^^ expected `f32`, found `f64`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: change the type of the numeric literal from `f64` to `f32`
+   |
+LL |     foo::<f32>(42.0_f32);
+   |                     ~~~
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:419:16
+   |
+LL |     foo::<u32>(42_u8 as u16);
+   |     ---------- ^^^^^^^^^^^^ expected `u32`, found `u16`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert a `u16` to a `u32`
+   |
+LL |     foo::<u32>((42_u8 as u16).into());
+   |                +            ++++++++
+
+error[E0308]: mismatched types
+  --> $DIR/numeric-suffix.rs:423:16
+   |
+LL |     foo::<i32>(-42_i8);
+   |     ---------- ^^^^^^ expected `i32`, found `i8`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/numeric-suffix.rs:3:4
+   |
+LL | fn foo<N>(_x: N) {}
+   |    ^^^    -----
+help: you can convert an `i8` to an `i32`
+   |
+LL |     foo::<i32>((-42_i8).into());
+   |                +      ++++++++
+
+error: aborting due to 68 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/packed/issue-27060-rpass.stderr b/src/test/ui/packed/issue-27060-rpass.stderr
new file mode 100644
index 00000000000..667b70afb87
--- /dev/null
+++ b/src/test/ui/packed/issue-27060-rpass.stderr
@@ -0,0 +1,68 @@
+Future incompatibility report: Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/issue-27060-rpass.rs:15:13
+   |
+LL |     let _ = &good.data; // ok
+   |             ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-27060-rpass.rs:11:9
+   |
+LL | #[allow(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/issue-27060-rpass.rs:16:13
+   |
+LL |     let _ = &good.data2[0]; // ok
+   |             ^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-27060-rpass.rs:11:9
+   |
+LL | #[allow(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/issue-27060-rpass.rs:18:13
+   |
+LL |     let _ = &good.data;
+   |             ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-27060-rpass.rs:11:9
+   |
+LL | #[allow(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/issue-27060-rpass.rs:19:13
+   |
+LL |     let _ = &good.data2[0];
+   |             ^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-27060-rpass.rs:11:9
+   |
+LL | #[allow(unaligned_references)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
diff --git a/src/test/ui/packed/issue-27060.rs b/src/test/ui/packed/issue-27060.rs
index 5317a616719..886a00239f9 100644
--- a/src/test/ui/packed/issue-27060.rs
+++ b/src/test/ui/packed/issue-27060.rs
@@ -5,7 +5,6 @@ pub struct Good {
     aligned: [u8; 32],
 }
 
-#[deny(unaligned_references)]
 fn main() {
     let good = Good {
         data: &0,
diff --git a/src/test/ui/packed/issue-27060.stderr b/src/test/ui/packed/issue-27060.stderr
index bba056d59f8..1bab16e6dda 100644
--- a/src/test/ui/packed/issue-27060.stderr
+++ b/src/test/ui/packed/issue-27060.stderr
@@ -1,21 +1,17 @@
 error: reference to packed field is unaligned
-  --> $DIR/issue-27060.rs:16:13
+  --> $DIR/issue-27060.rs:15:13
    |
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
    |
-note: the lint level is defined here
-  --> $DIR/issue-27060.rs:8:8
-   |
-LL | #[deny(unaligned_references)]
-   |        ^^^^^^^^^^^^^^^^^^^^
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error: reference to packed field is unaligned
-  --> $DIR/issue-27060.rs:18:13
+  --> $DIR/issue-27060.rs:17:13
    |
 LL |     let _ = &good.data2[0];
    |             ^^^^^^^^^^^^^^
@@ -26,7 +22,7 @@ LL |     let _ = &good.data2[0];
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error: reference to packed field is unaligned
-  --> $DIR/issue-27060.rs:21:13
+  --> $DIR/issue-27060.rs:20:13
    |
 LL |     let _ = &good.data;
    |             ^^^^^^^^^^
@@ -37,7 +33,7 @@ LL |     let _ = &good.data;
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 error: reference to packed field is unaligned
-  --> $DIR/issue-27060.rs:23:13
+  --> $DIR/issue-27060.rs:22:13
    |
 LL |     let _ = &good.data2[0];
    |             ^^^^^^^^^^^^^^
@@ -49,3 +45,55 @@ LL |     let _ = &good.data2[0];
 
 error: aborting due to 4 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-27060.rs:15:13
+   |
+LL |     let _ = &good.data;
+   |             ^^^^^^^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-27060.rs:17:13
+   |
+LL |     let _ = &good.data2[0];
+   |             ^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-27060.rs:20:13
+   |
+LL |     let _ = &good.data;
+   |             ^^^^^^^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+error: reference to packed field is unaligned
+  --> $DIR/issue-27060.rs:22:13
+   |
+LL |     let _ = &good.data2[0];
+   |             ^^^^^^^^^^^^^^
+   |
+   = note: `#[deny(unaligned_references)]` 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
diff --git a/src/test/ui/packed/packed-struct-address-of-element.rs b/src/test/ui/packed/packed-struct-address-of-element.rs
index fb3875e6804..d86698cbf38 100644
--- a/src/test/ui/packed/packed-struct-address-of-element.rs
+++ b/src/test/ui/packed/packed-struct-address-of-element.rs
@@ -1,6 +1,5 @@
 // run-pass
 #![allow(dead_code)]
-#![deny(unaligned_references)]
 #![feature(raw_ref_op)]
 // ignore-emscripten weird assertion?
 
diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.rs b/src/test/ui/packed/packed-struct-borrow-element-64bit.rs
index ad932fdcd01..00bddfe40b2 100644
--- a/src/test/ui/packed/packed-struct-borrow-element-64bit.rs
+++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.rs
@@ -9,6 +9,7 @@ struct Foo4C {
     baz: usize
 }
 
+#[warn(unaligned_references)]
 pub fn main() {
     let foo = Foo4C { bar: 1, baz: 2 };
     let brw = &foo.baz; //~WARN reference to packed field is unaligned
diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr
index 04585b49986..dcd1c19fa16 100644
--- a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr
+++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr
@@ -1,10 +1,14 @@
 warning: reference to packed field is unaligned
-  --> $DIR/packed-struct-borrow-element-64bit.rs:14:15
+  --> $DIR/packed-struct-borrow-element-64bit.rs:15:15
    |
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
-   = note: `#[warn(unaligned_references)]` on by default
+note: the lint level is defined here
+  --> $DIR/packed-struct-borrow-element-64bit.rs:12:8
+   |
+LL | #[warn(unaligned_references)]
+   |        ^^^^^^^^^^^^^^^^^^^^
    = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
@@ -12,3 +16,20 @@ LL |     let brw = &foo.baz;
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/packed-struct-borrow-element-64bit.rs:15:15
+   |
+LL |     let brw = &foo.baz;
+   |               ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/packed-struct-borrow-element-64bit.rs:12:8
+   |
+LL | #[warn(unaligned_references)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
diff --git a/src/test/ui/packed/packed-struct-borrow-element.rs b/src/test/ui/packed/packed-struct-borrow-element.rs
index fb6c9c11d56..a6ee90cef44 100644
--- a/src/test/ui/packed/packed-struct-borrow-element.rs
+++ b/src/test/ui/packed/packed-struct-borrow-element.rs
@@ -20,6 +20,7 @@ struct Foo4C {
     baz: usize
 }
 
+#[warn(unaligned_references)]
 pub fn main() {
     let foo = Foo1 { bar: 1, baz: 2 };
     let brw = &foo.baz; //~WARN reference to packed field is unaligned
diff --git a/src/test/ui/packed/packed-struct-borrow-element.stderr b/src/test/ui/packed/packed-struct-borrow-element.stderr
index a50b1302001..fb483227e20 100644
--- a/src/test/ui/packed/packed-struct-borrow-element.stderr
+++ b/src/test/ui/packed/packed-struct-borrow-element.stderr
@@ -1,17 +1,21 @@
 warning: reference to packed field is unaligned
-  --> $DIR/packed-struct-borrow-element.rs:25:15
+  --> $DIR/packed-struct-borrow-element.rs:26:15
    |
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
    |
-   = note: `#[warn(unaligned_references)]` on by default
+note: the lint level is defined here
+  --> $DIR/packed-struct-borrow-element.rs:23:8
+   |
+LL | #[warn(unaligned_references)]
+   |        ^^^^^^^^^^^^^^^^^^^^
    = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
 
 warning: reference to packed field is unaligned
-  --> $DIR/packed-struct-borrow-element.rs:30:15
+  --> $DIR/packed-struct-borrow-element.rs:31:15
    |
 LL |     let brw = &foo.baz;
    |               ^^^^^^^^
@@ -23,3 +27,37 @@ LL |     let brw = &foo.baz;
 
 warning: 2 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/packed-struct-borrow-element.rs:26:15
+   |
+LL |     let brw = &foo.baz;
+   |               ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/packed-struct-borrow-element.rs:23:8
+   |
+LL | #[warn(unaligned_references)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
+Future breakage diagnostic:
+warning: reference to packed field is unaligned
+  --> $DIR/packed-struct-borrow-element.rs:31:15
+   |
+LL |     let brw = &foo.baz;
+   |               ^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/packed-struct-borrow-element.rs:23:8
+   |
+LL | #[warn(unaligned_references)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+   = 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 #82523 <https://github.com/rust-lang/rust/issues/82523>
+   = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
+   = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
+
diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs
index 2d1554183cc..21d753ad037 100644
--- a/src/test/ui/parser/fn-arg-doc-comment.rs
+++ b/src/test/ui/parser/fn-arg-doc-comment.rs
@@ -1,26 +1,30 @@
-pub fn f(
+pub fn f( //~ NOTE function defined here
     /// Comment
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
+    //~| NOTE
     id: u8,
     /// Other
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
+    //~| NOTE
     a: u8,
 ) {}
 
 fn bar(id: #[allow(dead_code)] i32) {}
 //~^ ERROR attributes cannot be applied to a function parameter's type
 //~| NOTE attributes are not allowed here
+//~| NOTE function defined here
+//~| NOTE
 
 fn main() {
     // verify that the parser recovered and properly typechecked the args
     f("", "");
-    //~^ ERROR mismatched types
+    //~^ ERROR arguments to this function are incorrect
     //~| NOTE expected `u8`, found `&str`
-    //~| ERROR mismatched types
     //~| NOTE expected `u8`, found `&str`
     bar("");
     //~^ ERROR mismatched types
+    //~| NOTE arguments to this function are incorrect
     //~| NOTE expected `i32`, found `&str`
 }
diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr
index 41f2c080b94..c8d7e2efe79 100644
--- a/src/test/ui/parser/fn-arg-doc-comment.stderr
+++ b/src/test/ui/parser/fn-arg-doc-comment.stderr
@@ -1,5 +1,5 @@
 error: attributes cannot be applied to a function parameter's type
-  --> $DIR/fn-arg-doc-comment.rs:12:12
+  --> $DIR/fn-arg-doc-comment.rs:14:12
    |
 LL | fn bar(id: #[allow(dead_code)] i32) {}
    |            ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
@@ -11,29 +11,51 @@ LL |     /// Comment
    |     ^^^^^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/fn-arg-doc-comment.rs:6:5
+  --> $DIR/fn-arg-doc-comment.rs:7:5
    |
 LL |     /// Other
    |     ^^^^^^^^^ doc comments are not allowed here
 
-error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:18:7
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/fn-arg-doc-comment.rs:22:5
    |
 LL |     f("", "");
-   |       ^^ expected `u8`, found `&str`
-
-error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:18:11
+   |     ^ --  -- expected `u8`, found `&str`
+   |       |
+   |       expected `u8`, found `&str`
    |
-LL |     f("", "");
-   |           ^^ expected `u8`, found `&str`
+note: function defined here
+  --> $DIR/fn-arg-doc-comment.rs:1:8
+   |
+LL |   pub fn f(
+   |          ^
+LL | /     /// Comment
+LL | |
+LL | |
+LL | |
+LL | |     id: u8,
+   | |__________-
+LL | /     /// Other
+LL | |
+LL | |
+LL | |
+LL | |     a: u8,
+   | |_________-
 
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:23:9
+  --> $DIR/fn-arg-doc-comment.rs:26:9
    |
 LL |     bar("");
-   |         ^^ expected `i32`, found `&str`
+   |     --- ^^ expected `i32`, found `&str`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/fn-arg-doc-comment.rs:14:4
+   |
+LL | fn bar(id: #[allow(dead_code)] i32) {}
+   |    ^^^ ---------------------------
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index c800afdae2a..4c2eff63ab5 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -46,7 +46,15 @@ error[E0308]: mismatched types
   --> $DIR/pattern-error-continue.rs:28:7
    |
 LL |     f(true);
-   |       ^^^^ expected `char`, found `bool`
+   |     - ^^^^ expected `char`, found `bool`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/pattern-error-continue.rs:13:4
+   |
+LL | fn f(_c: char) {}
+   |    ^ --------
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/proc-macro/signature.stderr b/src/test/ui/proc-macro/signature.stderr
index 80a459c4125..262a64acc54 100644
--- a/src/test/ui/proc-macro/signature.stderr
+++ b/src/test/ui/proc-macro/signature.stderr
@@ -9,6 +9,11 @@ LL | | }
    |
    = note: expected fn pointer `fn(proc_macro::TokenStream) -> proc_macro::TokenStream`
                  found fn item `unsafe extern "C" fn(i32, u32) -> u32 {foo}`
+note: associated function defined here
+  --> $SRC_DIR/proc_macro/src/bridge/client.rs:LL:COL
+   |
+LL |     pub const fn custom_derive(
+   |                  ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/range/issue-54505-no-literals.stderr b/src/test/ui/range/issue-54505-no-literals.stderr
index 065e16a8227..4cbf8869d0c 100644
--- a/src/test/ui/range/issue-54505-no-literals.stderr
+++ b/src/test/ui/range/issue-54505-no-literals.stderr
@@ -2,145 +2,217 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:16:16
    |
 LL |     take_range(std::ops::Range { start: 0, end: 1 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `std::ops::Range`
-   |                help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `std::ops::Range`
+   |     |          help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `std::ops::Range<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:21:16
    |
 LL |     take_range(::std::ops::Range { start: 0, end: 1 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `std::ops::Range`
-   |                help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `std::ops::Range`
+   |     |          help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `std::ops::Range<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:26:16
    |
 LL |     take_range(std::ops::RangeFrom { start: 1 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeFrom`
-   |                help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFrom`
+   |     |          help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFrom<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:31:16
    |
 LL |     take_range(::std::ops::RangeFrom { start: 1 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeFrom`
-   |                help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFrom`
+   |     |          help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFrom<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:36:16
    |
 LL |     take_range(std::ops::RangeFull {});
-   |                ^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeFull`
-   |                help: consider borrowing here: `&std::ops::RangeFull {}`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFull`
+   |     |          help: consider borrowing here: `&std::ops::RangeFull {}`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFull`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:41:16
    |
 LL |     take_range(::std::ops::RangeFull {});
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeFull`
-   |                help: consider borrowing here: `&::std::ops::RangeFull {}`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFull`
+   |     |          help: consider borrowing here: `&::std::ops::RangeFull {}`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFull`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:46:16
    |
 LL |     take_range(std::ops::RangeInclusive::new(0, 1));
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeInclusive`
-   |                help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeInclusive`
+   |     |          help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:51:16
    |
 LL |     take_range(::std::ops::RangeInclusive::new(0, 1));
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeInclusive`
-   |                help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeInclusive`
+   |     |          help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:56:16
    |
 LL |     take_range(std::ops::RangeTo { end: 5 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeTo`
-   |                help: consider borrowing here: `&std::ops::RangeTo { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeTo`
+   |     |          help: consider borrowing here: `&std::ops::RangeTo { end: 5 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeTo<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:61:16
    |
 LL |     take_range(::std::ops::RangeTo { end: 5 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeTo`
-   |                help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeTo`
+   |     |          help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeTo<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:66:16
    |
 LL |     take_range(std::ops::RangeToInclusive { end: 5 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeToInclusive`
-   |                help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeToInclusive`
+   |     |          help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeToInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-literals.rs:71:16
    |
 LL |     take_range(::std::ops::RangeToInclusive { end: 5 });
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |                |
-   |                expected reference, found struct `RangeToInclusive`
-   |                help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }`
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeToInclusive`
+   |     |          help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeToInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-literals.rs:12:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/range/issue-54505-no-std.stderr b/src/test/ui/range/issue-54505-no-std.stderr
index 73507f4836b..c4e36b0b159 100644
--- a/src/test/ui/range/issue-54505-no-std.stderr
+++ b/src/test/ui/range/issue-54505-no-std.stderr
@@ -4,73 +4,109 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:27:16
    |
 LL |     take_range(0..1);
-   |                ^^^^
-   |                |
-   |                expected reference, found struct `Range`
-   |                help: consider borrowing here: `&(0..1)`
+   |     ---------- ^^^^
+   |     |          |
+   |     |          expected reference, found struct `Range`
+   |     |          help: consider borrowing here: `&(0..1)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `Range<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-std.rs:23:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:32:16
    |
 LL |     take_range(1..);
-   |                ^^^
-   |                |
-   |                expected reference, found struct `RangeFrom`
-   |                help: consider borrowing here: `&(1..)`
+   |     ---------- ^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFrom`
+   |     |          help: consider borrowing here: `&(1..)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFrom<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-std.rs:23:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:37:16
    |
 LL |     take_range(..);
-   |                ^^
-   |                |
-   |                expected reference, found struct `RangeFull`
-   |                help: consider borrowing here: `&(..)`
+   |     ---------- ^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFull`
+   |     |          help: consider borrowing here: `&(..)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFull`
+note: function defined here
+  --> $DIR/issue-54505-no-std.rs:23:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:42:16
    |
 LL |     take_range(0..=1);
-   |                ^^^^^
-   |                |
-   |                expected reference, found struct `RangeInclusive`
-   |                help: consider borrowing here: `&(0..=1)`
+   |     ---------- ^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeInclusive`
+   |     |          help: consider borrowing here: `&(0..=1)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-std.rs:23:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:47:16
    |
 LL |     take_range(..5);
-   |                ^^^
-   |                |
-   |                expected reference, found struct `RangeTo`
-   |                help: consider borrowing here: `&(..5)`
+   |     ---------- ^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeTo`
+   |     |          help: consider borrowing here: `&(..5)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeTo<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-std.rs:23:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505-no-std.rs:52:16
    |
 LL |     take_range(..=42);
-   |                ^^^^^
-   |                |
-   |                expected reference, found struct `RangeToInclusive`
-   |                help: consider borrowing here: `&(..=42)`
+   |     ---------- ^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeToInclusive`
+   |     |          help: consider borrowing here: `&(..=42)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeToInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505-no-std.rs:23:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/range/issue-54505.stderr b/src/test/ui/range/issue-54505.stderr
index 121af29834d..38df6e14496 100644
--- a/src/test/ui/range/issue-54505.stderr
+++ b/src/test/ui/range/issue-54505.stderr
@@ -2,73 +2,109 @@ error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:14:16
    |
 LL |     take_range(0..1);
-   |                ^^^^
-   |                |
-   |                expected reference, found struct `std::ops::Range`
-   |                help: consider borrowing here: `&(0..1)`
+   |     ---------- ^^^^
+   |     |          |
+   |     |          expected reference, found struct `std::ops::Range`
+   |     |          help: consider borrowing here: `&(0..1)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `std::ops::Range<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505.rs:10:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:19:16
    |
 LL |     take_range(1..);
-   |                ^^^
-   |                |
-   |                expected reference, found struct `RangeFrom`
-   |                help: consider borrowing here: `&(1..)`
+   |     ---------- ^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFrom`
+   |     |          help: consider borrowing here: `&(1..)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFrom<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505.rs:10:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:24:16
    |
 LL |     take_range(..);
-   |                ^^
-   |                |
-   |                expected reference, found struct `RangeFull`
-   |                help: consider borrowing here: `&(..)`
+   |     ---------- ^^
+   |     |          |
+   |     |          expected reference, found struct `RangeFull`
+   |     |          help: consider borrowing here: `&(..)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeFull`
+note: function defined here
+  --> $DIR/issue-54505.rs:10:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:29:16
    |
 LL |     take_range(0..=1);
-   |                ^^^^^
-   |                |
-   |                expected reference, found struct `RangeInclusive`
-   |                help: consider borrowing here: `&(0..=1)`
+   |     ---------- ^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeInclusive`
+   |     |          help: consider borrowing here: `&(0..=1)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505.rs:10:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:34:16
    |
 LL |     take_range(..5);
-   |                ^^^
-   |                |
-   |                expected reference, found struct `RangeTo`
-   |                help: consider borrowing here: `&(..5)`
+   |     ---------- ^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeTo`
+   |     |          help: consider borrowing here: `&(..5)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeTo<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505.rs:10:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error[E0308]: mismatched types
   --> $DIR/issue-54505.rs:39:16
    |
 LL |     take_range(..=42);
-   |                ^^^^^
-   |                |
-   |                expected reference, found struct `RangeToInclusive`
-   |                help: consider borrowing here: `&(..=42)`
+   |     ---------- ^^^^^
+   |     |          |
+   |     |          expected reference, found struct `RangeToInclusive`
+   |     |          help: consider borrowing here: `&(..=42)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&_`
                  found struct `RangeToInclusive<{integer}>`
+note: function defined here
+  --> $DIR/issue-54505.rs:10:4
+   |
+LL | fn take_range(_r: &impl RangeBounds<i8>) {}
+   |    ^^^^^^^^^^ -------------------------
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/range/issue-73553-misinterp-range-literal.stderr b/src/test/ui/range/issue-73553-misinterp-range-literal.stderr
index 5167b87fd27..6badd998f96 100644
--- a/src/test/ui/range/issue-73553-misinterp-range-literal.stderr
+++ b/src/test/ui/range/issue-73553-misinterp-range-literal.stderr
@@ -2,25 +2,37 @@ error[E0308]: mismatched types
   --> $DIR/issue-73553-misinterp-range-literal.rs:12:10
    |
 LL |     demo(tell(1)..tell(10));
-   |          ^^^^^^^^^^^^^^^^^
-   |          |
-   |          expected reference, found struct `std::ops::Range`
-   |          help: consider borrowing here: `&(tell(1)..tell(10))`
+   |     ---- ^^^^^^^^^^^^^^^^^
+   |     |    |
+   |     |    expected reference, found struct `std::ops::Range`
+   |     |    help: consider borrowing here: `&(tell(1)..tell(10))`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&std::ops::Range<usize>`
                  found struct `std::ops::Range<usize>`
+note: function defined here
+  --> $DIR/issue-73553-misinterp-range-literal.rs:3:4
+   |
+LL | fn demo(r: &Range) {
+   |    ^^^^ ---------
 
 error[E0308]: mismatched types
   --> $DIR/issue-73553-misinterp-range-literal.rs:14:10
    |
 LL |     demo(1..10);
-   |          ^^^^^
-   |          |
-   |          expected reference, found struct `std::ops::Range`
-   |          help: consider borrowing here: `&(1..10)`
+   |     ---- ^^^^^
+   |     |    |
+   |     |    expected reference, found struct `std::ops::Range`
+   |     |    help: consider borrowing here: `&(1..10)`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&std::ops::Range<usize>`
                  found struct `std::ops::Range<{integer}>`
+note: function defined here
+  --> $DIR/issue-73553-misinterp-range-literal.rs:3:4
+   |
+LL | fn demo(r: &Range) {
+   |    ^^^^ ---------
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/resolve/resolve-primitive-fallback.stderr b/src/test/ui/resolve/resolve-primitive-fallback.stderr
index 5af0aefe22b..44631f954df 100644
--- a/src/test/ui/resolve/resolve-primitive-fallback.stderr
+++ b/src/test/ui/resolve/resolve-primitive-fallback.stderr
@@ -19,15 +19,17 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/resolve-primitive-fallback.rs:3:5
    |
 LL |     std::mem::size_of(u16);
-   |     ^^^^^^^^^^^^^^^^^ --- supplied 1 argument
-   |     |
-   |     expected 0 arguments
+   |     ^^^^^^^^^^^^^^^^^ --- argument unexpected
    |
 note: function defined here
   --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
    |
 LL | pub const fn size_of<T>() -> usize {
    |              ^^^^^^^
+help: remove the extra argument
+   |
+LL |     std::mem::size_of();
+   |     ~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/self/issue-61882.stderr b/src/test/ui/self/issue-61882.stderr
index 09ffe8e64b1..dd7194dc2e8 100644
--- a/src/test/ui/self/issue-61882.stderr
+++ b/src/test/ui/self/issue-61882.stderr
@@ -2,7 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/issue-61882.rs:4:27
    |
 LL |     const B: A<u8> = Self(0);
-   |                           ^ expected `bool`, found integer
+   |                      ---- ^ expected `bool`, found integer
+   |                      |
+   |                      arguments to this function are incorrect
+   |
+note: tuple struct defined here
+  --> $DIR/issue-61882.rs:1:8
+   |
+LL | struct A<T>(T);
+   |        ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-61882.rs:4:22
diff --git a/src/test/ui/span/E0057.rs b/src/test/ui/span/E0057.rs
new file mode 100644
index 00000000000..83f941f65b9
--- /dev/null
+++ b/src/test/ui/span/E0057.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let f = |x| x * 3;
+    let a = f(); //~ ERROR E0057
+    let b = f(4);
+    let c = f(2, 3); //~ ERROR E0057
+}
diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr
new file mode 100644
index 00000000000..a151b20f865
--- /dev/null
+++ b/src/test/ui/span/E0057.stderr
@@ -0,0 +1,25 @@
+error[E0057]: this function takes 1 argument but 0 arguments were supplied
+  --> $DIR/E0057.rs:3:13
+   |
+LL |     let a = f();
+   |             ^-- an argument is missing
+   |
+help: provide the argument
+   |
+LL |     let a = f({_});
+   |             ~~~~~~
+
+error[E0057]: this function takes 1 argument but 2 arguments were supplied
+  --> $DIR/E0057.rs:5:13
+   |
+LL |     let c = f(2, 3);
+   |             ^    - argument unexpected
+   |
+help: remove the extra argument
+   |
+LL |     let c = f(2);
+   |             ~~~~
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0057`.
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 5a964c5d5cc..db784d5fe6c 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -20,19 +20,33 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:12:10
    |
 LL |     test(&y);
-   |          ^^ types differ in mutability
+   |     ---- ^^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut String`
                       found reference `&String`
+note: function defined here
+  --> $DIR/coerce-suggestions.rs:1:4
+   |
+LL | fn test(_x: &mut String) {}
+   |    ^^^^ ---------------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:14:11
    |
 LL |     test2(&y);
-   |           ^^ types differ in mutability
+   |     ----- ^^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut i32`
                       found reference `&String`
+note: function defined here
+  --> $DIR/coerce-suggestions.rs:3:4
+   |
+LL | fn test2(_x: &mut i32) {}
+   |    ^^^^^ ------------
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:17:9
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 8d26ca4ac7a..68da9f0dc88 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -54,35 +54,47 @@ error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:7:5
    |
 LL |     foo(Some(42), 2, "");
-   |     ^^^ --------  -  -- supplied 3 arguments
-   |     |
-   |     expected 2 arguments
+   |     ^^^              -- argument unexpected
    |
 note: function defined here
   --> $DIR/issue-34264.rs:1:4
    |
 LL | fn foo(Option<i32>, String) {}
    |    ^^^ -----------  ------
+help: remove the extra argument
+   |
+LL |     foo(Some(42), 2);
+   |     ~~~~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/issue-34264.rs:8:13
    |
 LL |     bar("", "");
-   |             ^^ expected `usize`, found `&str`
+   |     ---     ^^ expected `usize`, found `&str`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/issue-34264.rs:3:4
+   |
+LL | fn bar(x, y: usize) {}
+   |    ^^^ -  --------
 
 error[E0061]: this function takes 2 arguments but 3 arguments were supplied
   --> $DIR/issue-34264.rs:10:5
    |
 LL |     bar(1, 2, 3);
-   |     ^^^ -  -  - supplied 3 arguments
-   |     |
-   |     expected 2 arguments
+   |     ^^^       - argument unexpected
    |
 note: function defined here
   --> $DIR/issue-34264.rs:3:4
    |
 LL | fn bar(x, y: usize) {}
    |    ^^^ -  --------
+help: remove the extra argument
+   |
+LL |     bar(1, 2);
+   |     ~~~~~~~~~
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr
index 99c57322d86..c8e1a232887 100644
--- a/src/test/ui/span/missing-unit-argument.stderr
+++ b/src/test/ui/span/missing-unit-argument.stderr
@@ -2,88 +2,92 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/missing-unit-argument.rs:11:33
    |
 LL |     let _: Result<(), String> = Ok();
-   |                                 ^^-- supplied 0 arguments
+   |                                 ^^-- an argument of type `()` is missing
    |
-help: expected the unit value `()`; create it with empty parentheses
+help: provide the argument
    |
 LL |     let _: Result<(), String> = Ok(());
-   |                                    ++
+   |                                 ~~~~~~
 
 error[E0061]: this function takes 2 arguments but 0 arguments were supplied
   --> $DIR/missing-unit-argument.rs:12:5
    |
 LL |     foo();
-   |     ^^^-- supplied 0 arguments
-   |     |
-   |     expected 2 arguments
+   |     ^^^-- two arguments of type `()` and `()` are missing
    |
 note: function defined here
   --> $DIR/missing-unit-argument.rs:1:4
    |
 LL | fn foo(():(), ():()) {}
    |    ^^^ -----  -----
+help: provide the arguments
+   |
+LL |     foo((), ());
+   |     ~~~~~~~~~~~
 
 error[E0061]: this function takes 2 arguments but 1 argument was supplied
   --> $DIR/missing-unit-argument.rs:13:5
    |
 LL |     foo(());
-   |     ^^^ -- supplied 1 argument
-   |     |
-   |     expected 2 arguments
+   |     ^^^---- an argument of type `()` is missing
    |
 note: function defined here
   --> $DIR/missing-unit-argument.rs:1:4
    |
 LL | fn foo(():(), ():()) {}
    |    ^^^ -----  -----
+help: provide the argument
+   |
+LL |     foo((), ());
+   |     ~~~~~~~~~~~
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/missing-unit-argument.rs:14:5
    |
 LL |     bar();
-   |     ^^^-- supplied 0 arguments
+   |     ^^^-- an argument of type `()` is missing
    |
 note: function defined here
   --> $DIR/missing-unit-argument.rs:2:4
    |
 LL | fn bar(():()) {}
    |    ^^^ -----
-help: expected the unit value `()`; create it with empty parentheses
+help: provide the argument
    |
 LL |     bar(());
-   |         ++
+   |     ~~~~~~~
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/missing-unit-argument.rs:15:7
    |
 LL |     S.baz();
-   |       ^^^- supplied 0 arguments
+   |       ^^^-- an argument of type `()` is missing
    |
 note: associated function defined here
   --> $DIR/missing-unit-argument.rs:6:8
    |
 LL |     fn baz(self, (): ()) { }
    |        ^^^ ----  ------
-help: expected the unit value `()`; create it with empty parentheses
+help: provide the argument
    |
 LL |     S.baz(());
-   |           ++
+   |       ~~~~~~~
 
 error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/missing-unit-argument.rs:16:7
    |
 LL |     S.generic::<()>();
-   |       ^^^^^^^------ supplied 0 arguments
+   |       ^^^^^^^^^^^^^-- an argument of type `()` is missing
    |
 note: associated function defined here
   --> $DIR/missing-unit-argument.rs:7:8
    |
 LL |     fn generic<T>(self, _: T) { }
    |        ^^^^^^^    ----  ----
-help: expected the unit value `()`; create it with empty parentheses
+help: provide the argument
    |
 LL |     S.generic::<()>(());
-   |                     ++
+   |       ~~~~~~~~~~~~~~~~~
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
index ddcdfb1c3b3..991dde30629 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr
@@ -2,37 +2,55 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:6:34
    |
 LL |     let _: Option<(i32, bool)> = Some(1, 2);
-   |                                  ^^^^ -  - supplied 2 arguments
-   |                                  |
-   |                                  expected 1 argument
+   |                                  ^^^^ -  - argument unexpected
+   |                                       |
+   |                                       expected tuple, found integer
+   |
+   = note: expected tuple `(i32, bool)`
+               found type `{integer}`
+help: remove the extra argument
+   |
+LL |     let _: Option<(i32, bool)> = Some({(i32, bool)});
+   |                                  ~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:8:5
    |
 LL |     int_bool(1, 2);
-   |     ^^^^^^^^ -  - supplied 2 arguments
-   |     |
-   |     expected 1 argument
+   |     ^^^^^^^^ -  - argument unexpected
+   |              |
+   |              expected tuple, found integer
    |
+   = note: expected tuple `(i32, bool)`
+               found type `{integer}`
 note: function defined here
   --> $DIR/args-instead-of-tuple-errors.rs:21:4
    |
 LL | fn int_bool(_: (i32, bool)) {
    |    ^^^^^^^^ --------------
+help: remove the extra argument
+   |
+LL |     int_bool({(i32, bool)});
+   |     ~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/args-instead-of-tuple-errors.rs:11:28
    |
 LL |     let _: Option<(i8,)> = Some();
-   |                            ^^^^-- supplied 0 arguments
-   |                            |
-   |                            expected 1 argument
+   |                            ^^^^-- an argument of type `(i8,)` is missing
+   |
+help: provide the argument
+   |
+LL |     let _: Option<(i8,)> = Some({(i8,)});
+   |                            ~~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/args-instead-of-tuple-errors.rs:14:34
    |
 LL |     let _: Option<(i32,)> = Some(5_usize);
-   |                                  ^^^^^^^ expected tuple, found `usize`
+   |                             ---- ^^^^^^^ expected tuple, found `usize`
+   |                             |
+   |                             arguments to this enum variant are incorrect
    |
    = note: expected tuple `(i32,)`
                found type `usize`
@@ -41,7 +59,9 @@ error[E0308]: mismatched types
   --> $DIR/args-instead-of-tuple-errors.rs:17:34
    |
 LL |     let _: Option<(i32,)> = Some((5_usize));
-   |                                  ^^^^^^^^^ expected tuple, found `usize`
+   |                             ---- ^^^^^^^^^ expected tuple, found `usize`
+   |                             |
+   |                             arguments to this enum variant are incorrect
    |
    = note: expected tuple `(i32,)`
                found type `usize`
diff --git a/src/test/ui/suggestions/args-instead-of-tuple.stderr b/src/test/ui/suggestions/args-instead-of-tuple.stderr
index 6a7602c9d0f..7ec10e88142 100644
--- a/src/test/ui/suggestions/args-instead-of-tuple.stderr
+++ b/src/test/ui/suggestions/args-instead-of-tuple.stderr
@@ -2,7 +2,7 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple.rs:7:36
    |
 LL |     let _: Result<(i32, i8), ()> = Ok(1, 2);
-   |                                    ^^ -  - supplied 2 arguments
+   |                                    ^^
    |
 help: use parentheses to construct a tuple
    |
@@ -13,7 +13,7 @@ error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
   --> $DIR/args-instead-of-tuple.rs:9:46
    |
 LL |     let _: Option<(i32, i8, &'static str)> = Some(1, 2, "hi");
-   |                                              ^^^^ -  -  ---- supplied 3 arguments
+   |                                              ^^^^
    |
 help: use parentheses to construct a tuple
    |
@@ -24,18 +24,20 @@ error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/args-instead-of-tuple.rs:11:25
    |
 LL |     let _: Option<()> = Some();
-   |                         ^^^^-- supplied 0 arguments
+   |                         ^^^^-- an argument of type `()` is missing
    |
-help: expected the unit value `()`; create it with empty parentheses
+help: provide the argument
    |
 LL |     let _: Option<()> = Some(());
-   |                              ++
+   |                         ~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/args-instead-of-tuple.rs:14:34
    |
 LL |     let _: Option<(i32,)> = Some(3);
-   |                                  ^ expected tuple, found integer
+   |                             ---- ^ expected tuple, found integer
+   |                             |
+   |                             arguments to this enum variant are incorrect
    |
    = note: expected tuple `(i32,)`
                found type `{integer}`
@@ -48,7 +50,9 @@ error[E0308]: mismatched types
   --> $DIR/args-instead-of-tuple.rs:17:34
    |
 LL |     let _: Option<(i32,)> = Some((3));
-   |                                  ^^^ expected tuple, found integer
+   |                             ---- ^^^ expected tuple, found integer
+   |                             |
+   |                             arguments to this enum variant are incorrect
    |
    = note: expected tuple `(i32,)`
                found type `{integer}`
@@ -61,7 +65,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple.rs:20:5
    |
 LL |     two_ints(1, 2);
-   |     ^^^^^^^^ -  - supplied 2 arguments
+   |     ^^^^^^^^
    |
 note: function defined here
   --> $DIR/args-instead-of-tuple.rs:25:4
@@ -77,7 +81,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple.rs:22:5
    |
 LL |     with_generic(3, 4);
-   |     ^^^^^^^^^^^^ -  - supplied 2 arguments
+   |     ^^^^^^^^^^^^
    |
 note: function defined here
   --> $DIR/args-instead-of-tuple.rs:28:4
@@ -93,7 +97,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/args-instead-of-tuple.rs:31:9
    |
 LL |         with_generic(a, b);
-   |         ^^^^^^^^^^^^ -  - supplied 2 arguments
+   |         ^^^^^^^^^^^^
    |
 note: function defined here
   --> $DIR/args-instead-of-tuple.rs:28:4
diff --git a/src/test/ui/suggestions/as-ref.stderr b/src/test/ui/suggestions/as-ref.stderr
index 8d93ac50796..1efd1b317b7 100644
--- a/src/test/ui/suggestions/as-ref.stderr
+++ b/src/test/ui/suggestions/as-ref.stderr
@@ -2,33 +2,61 @@ error[E0308]: mismatched types
   --> $DIR/as-ref.rs:7:29
    |
 LL |     opt.map(|arg| takes_ref(arg));
-   |         ---                 ^^^ expected `&Foo`, found struct `Foo`
-   |         |
+   |         ---       --------- ^^^ expected `&Foo`, found struct `Foo`
+   |         |         |
+   |         |         arguments to this function are incorrect
    |         help: consider using `as_ref` instead: `as_ref().map`
+   |
+note: function defined here
+  --> $DIR/as-ref.rs:3:4
+   |
+LL | fn takes_ref(_: &Foo) {}
+   |    ^^^^^^^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:8:39
    |
 LL |     opt.and_then(|arg| Some(takes_ref(arg)));
-   |         --------                      ^^^ expected `&Foo`, found struct `Foo`
-   |         |
+   |         --------            --------- ^^^ expected `&Foo`, found struct `Foo`
+   |         |                   |
+   |         |                   arguments to this function are incorrect
    |         help: consider using `as_ref` instead: `as_ref().and_then`
+   |
+note: function defined here
+  --> $DIR/as-ref.rs:3:4
+   |
+LL | fn takes_ref(_: &Foo) {}
+   |    ^^^^^^^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:10:29
    |
 LL |     opt.map(|arg| takes_ref(arg));
-   |         ---                 ^^^ expected `&Foo`, found struct `Foo`
-   |         |
+   |         ---       --------- ^^^ expected `&Foo`, found struct `Foo`
+   |         |         |
+   |         |         arguments to this function are incorrect
    |         help: consider using `as_ref` instead: `as_ref().map`
+   |
+note: function defined here
+  --> $DIR/as-ref.rs:3:4
+   |
+LL | fn takes_ref(_: &Foo) {}
+   |    ^^^^^^^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:11:37
    |
 LL |     opt.and_then(|arg| Ok(takes_ref(arg)));
-   |         --------                    ^^^ expected `&Foo`, found struct `Foo`
-   |         |
+   |         --------          --------- ^^^ expected `&Foo`, found struct `Foo`
+   |         |                 |
+   |         |                 arguments to this function are incorrect
    |         help: consider using `as_ref` instead: `as_ref().and_then`
+   |
+note: function defined here
+  --> $DIR/as-ref.rs:3:4
+   |
+LL | fn takes_ref(_: &Foo) {}
+   |    ^^^^^^^^^ -------
 
 error[E0308]: mismatched types
   --> $DIR/as-ref.rs:13:29
diff --git a/src/test/ui/suggestions/boxed-variant-field.stderr b/src/test/ui/suggestions/boxed-variant-field.stderr
index 9a31dc89197..6dfb73480a2 100644
--- a/src/test/ui/suggestions/boxed-variant-field.stderr
+++ b/src/test/ui/suggestions/boxed-variant-field.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/boxed-variant-field.rs:9:31
    |
 LL |         Ty::List(elem) => foo(elem),
-   |                               ^^^^ expected enum `Ty`, found struct `Box`
+   |                           --- ^^^^ expected enum `Ty`, found struct `Box`
+   |                           |
+   |                           arguments to this function are incorrect
    |
    = note: expected enum `Ty`
             found struct `Box<Ty>`
+note: function defined here
+  --> $DIR/boxed-variant-field.rs:6:4
+   |
+LL | fn foo(x: Ty) -> Ty {
+   |    ^^^ -----
 help: consider unboxing the value
    |
 LL |         Ty::List(elem) => foo(*elem),
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index 7ef4895249c..71facf57e8d 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -34,10 +34,16 @@ LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static,
 LL |     Pin::new(x)
    |     -------- ^ expected struct `Box`, found type parameter `F`
    |     |
+   |     arguments to this function are incorrect
    |     help: use `Box::pin` to pin and box this expression: `Box::pin`
    |
    = note:      expected struct `Box<dyn Future<Output = i32> + Send>`
            found type parameter `F`
+note: associated function defined here
+  --> $SRC_DIR/core/src/pin.rs:LL:COL
+   |
+LL |     pub const fn new(pointer: P) -> Pin<P> {
+   |                  ^^^
 
 error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
   --> $DIR/expected-boxed-future-isnt-pinned.rs:19:5
diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
index 0016f192842..8c9a41a2027 100644
--- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
+++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr
@@ -17,10 +17,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-86100-tuple-paren-comma.rs:13:9
    |
 LL |     foo((Some(3)));
-   |         ^^^^^^^^^ expected tuple, found enum `Option`
+   |     --- ^^^^^^^^^ expected tuple, found enum `Option`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected tuple `(_,)`
                found enum `Option<{integer}>`
+note: function defined here
+  --> $DIR/issue-86100-tuple-paren-comma.rs:5:4
+   |
+LL | fn foo<T>(_t: (T,)) {}
+   |    ^^^    --------
 help: use a trailing comma to create a tuple with one element
    |
 LL |     foo((Some(3),));
diff --git a/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr b/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr
index c15b772b79c..611f7d5ddda 100644
--- a/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr
+++ b/src/test/ui/suggestions/issue-90213-expected-boxfuture-self-ice.stderr
@@ -2,11 +2,18 @@ error[E0308]: mismatched types
   --> $DIR/issue-90213-expected-boxfuture-self-ice.rs:9:19
    |
 LL |         Self::foo(None)
-   |                   ^^^^ expected struct `Box`, found enum `Option`
+   |         --------- ^^^^ expected struct `Box`, found enum `Option`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected struct `Box<Option<S>>`
                 found enum `Option<_>`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+note: associated function defined here
+  --> $DIR/issue-90213-expected-boxfuture-self-ice.rs:7:8
+   |
+LL |     fn foo(_: Box<Option<S>>) {}
+   |        ^^^ -----------------
 help: store this in the heap by calling `Box::new`
    |
 LL |         Self::foo(Box::new(None))
diff --git a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr
index aa621111c00..9588eedc98b 100644
--- a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr
+++ b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr
@@ -38,7 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/recover-from-semicolon-trailing-item.rs:14:9
    |
 LL |     foo("");
-   |         ^^ expected `usize`, found `&str`
+   |     --- ^^ expected `usize`, found `&str`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/recover-from-semicolon-trailing-item.rs:6:4
+   |
+LL | fn foo(a: usize) {};
+   |    ^^^ --------
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/suggestions/suggest-ref-macro.stderr b/src/test/ui/suggestions/suggest-ref-macro.stderr
index 5c05810e586..b0ac770c06f 100644
--- a/src/test/ui/suggestions/suggest-ref-macro.stderr
+++ b/src/test/ui/suggestions/suggest-ref-macro.stderr
@@ -2,31 +2,60 @@ error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:15:11
    |
 LL |         x(123);
-   |           ^^^
-   |           |
-   |           expected `&mut i32`, found integer
-   |           help: consider mutably borrowing here: `&mut 123`
+   |         - ^^^
+   |         | |
+   |         | expected `&mut i32`, found integer
+   |         | help: consider mutably borrowing here: `&mut 123`
+   |         arguments to this function are incorrect
 ...
 LL |     bla!();
    |     ------ in this macro invocation
    |
+note: function defined here
+  --> $DIR/suggest-ref-macro.rs:11:4
+   |
+LL | fn x(_: &mut i32) {}
+   |    ^ -----------
    = note: this error originates in the macro `bla` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:26:10
    |
+LL |         x($v)
+   |         - arguments to this function are incorrect
+...
 LL |     bla!(456);
    |          ^^^
    |          |
    |          expected `&mut i32`, found integer
    |          help: consider mutably borrowing here: `&mut 456`
+   |
+note: function defined here
+  --> $DIR/suggest-ref-macro.rs:11:4
+   |
+LL | fn x(_: &mut i32) {}
+   |    ^ -----------
 
 error[E0308]: mismatched types
   --> $DIR/suggest-ref-macro.rs:8:1
    |
 LL | #[hello]
-   | ^^^^^^^^ expected `&mut i32`, found integer
+   | ^^^^^^^^
+   | |
+   | expected `&mut i32`, found integer
+   | arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/suggest-ref-macro.rs:8:1
    |
+LL |   #[hello]
+   |  _-^^^^^^^
+LL | | fn abc() {}
+LL | |
+LL | | fn x(_: &mut i32) {}
+LL | |
+LL | | macro_rules! bla {
+   | |_____________-
    = note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr
index 19fc772544d..ac839ff7eb9 100644
--- a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr
+++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:13:13
    |
 LL |         qux(x.func())
-   |             ^^^^^^^^ expected `usize`, found associated type
+   |         --- ^^^^^^^^ expected `usize`, found associated type
+   |         |
+   |         arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<impl Trait as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize`
    |
 LL |     fn foo<'a, T: Trait + 'a>(&self, _: impl Trait, x: impl Trait<A = usize>, _: T) {
@@ -15,10 +22,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:17:13
    |
 LL |         qux(x.func())
-   |             ^^^^^^^^ expected `usize`, found associated type
+   |         --- ^^^^^^^^ expected `usize`, found associated type
+   |         |
+   |         arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait>::A` to `usize`
    |
 LL |     fn ban<T>(x: T) where T: Trait<A = usize> {
@@ -28,10 +42,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:22:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<impl Trait as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize`
    |
 LL | fn foo<'a, T: Trait + 'a>(_: impl Trait, x: impl Trait<A = usize>, _: T) {
@@ -41,10 +62,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:26:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait>::A` to `usize`
    |
 LL | fn bar<T: Trait<A = usize>>(x: T) {
@@ -54,10 +82,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:30:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<impl Trait<i32> as Trait<i32>>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<impl Trait<i32> as Trait<i32>>::A` to `usize`
    |
 LL | fn foo2(x: impl Trait<i32, A = usize>) {
@@ -67,10 +102,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:34:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait<i32>>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait<i32>>::A` to `usize`
    |
 LL | fn bar2<T: Trait<i32, A = usize>>(x: T) {
@@ -80,10 +122,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:38:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction-fixable.rs:41:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait>::A` to `usize`
    |
 LL | fn ban<T>(x: T) where T: Trait<A = usize> {
diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
index 943cbcbc81a..7583c875a1a 100644
--- a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
+++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
@@ -16,10 +16,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:14:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<impl Trait as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize`
    |
 LL | fn foo(_: impl Trait, x: impl Trait<A = usize>) {
@@ -29,10 +36,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:18:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait>::A` to `usize`
    |
 LL | fn bar<T: Trait<A = usize>>(x: T) {
@@ -42,10 +56,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:22:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<impl Trait<i32> as Trait<i32>>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<impl Trait<i32> as Trait<i32>>::A` to `usize`
    |
 LL | fn foo2(x: impl Trait<i32, A = usize>) {
@@ -55,7 +76,9 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:26:12
    |
 LL |     x.funk(3);
-   |            ^ expected associated type, found integer
+   |       ---- ^ expected associated type, found integer
+   |       |
+   |       arguments to this function are incorrect
    |
    = note: expected associated type `<T as Trait<i32>>::A`
                          found type `{integer}`
@@ -67,6 +90,11 @@ LL |     fn func(&self) -> Self::A;
 LL |     fn funk(&self, _: Self::A);
 LL |     fn funq(&self) -> Self::A {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::funq`
+note: associated function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:9:8
+   |
+LL |     fn funk(&self, _: Self::A);
+   |        ^^^^
 help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}`
    |
 LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) {
@@ -76,10 +104,17 @@ error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:27:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait<i32>>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait<i32>>::A` to `usize`
    |
 LL | fn bar2<T: Trait<i32, A = usize>>(x: T) {
@@ -91,25 +126,47 @@ error[E0308]: mismatched types
 LL | fn baz<D: std::fmt::Debug, T: Trait<A = D>>(x: T) {
    |        - this type parameter
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found type parameter `D`
+   |     --- ^^^^^^^^ expected `usize`, found type parameter `D`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:        expected type `usize`
            found type parameter `D`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 
 error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:35:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found `()`
+   |     --- ^^^^^^^^ expected `usize`, found `()`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 
 error[E0308]: mismatched types
   --> $DIR/trait-with-missing-associated-type-restriction.rs:39:9
    |
 LL |     qux(x.func())
-   |         ^^^^^^^^ expected `usize`, found associated type
+   |     --- ^^^^^^^^ expected `usize`, found associated type
+   |     |
+   |     arguments to this function are incorrect
    |
    = note:         expected type `usize`
            found associated type `<T as Trait>::A`
+note: function defined here
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:42:4
+   |
+LL | fn qux(_: usize) {}
+   |    ^^^ --------
 help: consider constraining the associated type `<T as Trait>::A` to `usize`
    |
 LL | fn ban<T>(x: T) where T: Trait<A = usize> {
diff --git a/src/test/ui/suggestions/use-placement-typeck.fixed b/src/test/ui/suggestions/use-placement-typeck.fixed
index 40c55d1dd06..37335da060e 100644
--- a/src/test/ui/suggestions/use-placement-typeck.fixed
+++ b/src/test/ui/suggestions/use-placement-typeck.fixed
@@ -7,7 +7,6 @@
 #![allow(unused)]
 
 use m::Foo;
-
 fn main() {
     let s = m::S;
     s.abc(); //~ ERROR no method named `abc`
diff --git a/src/test/ui/terminal-width/flag-json.rs b/src/test/ui/terminal-width/flag-json.rs
index eabdc59dded..3d2530e204b 100644
--- a/src/test/ui/terminal-width/flag-json.rs
+++ b/src/test/ui/terminal-width/flag-json.rs
@@ -5,5 +5,5 @@
 
 fn main() {
     let _: () = 42;
-    //~^ ERROR mismatched types
+    //~^ ERROR arguments to this function are incorrect
 }
diff --git a/src/test/ui/terr-in-field.stderr b/src/test/ui/terr-in-field.stderr
index 5c6859a0efe..d2fda09c076 100644
--- a/src/test/ui/terr-in-field.stderr
+++ b/src/test/ui/terr-in-field.stderr
@@ -2,7 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/terr-in-field.rs:13:14
    |
 LL |     want_foo(b);
-   |              ^ expected struct `Foo`, found struct `Bar`
+   |     -------- ^ expected struct `Foo`, found struct `Bar`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/terr-in-field.rs:11:4
+   |
+LL | fn want_foo(f: Foo) {}
+   |    ^^^^^^^^ ------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/terr-sorts.stderr b/src/test/ui/terr-sorts.stderr
index 34d4d9eaded..5a61a2fab12 100644
--- a/src/test/ui/terr-sorts.stderr
+++ b/src/test/ui/terr-sorts.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/terr-sorts.rs:10:14
    |
 LL |     want_foo(b);
-   |              ^ expected struct `Foo`, found struct `Box`
+   |     -------- ^ expected struct `Foo`, found struct `Box`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo`
               found struct `Box<Foo>`
+note: function defined here
+  --> $DIR/terr-sorts.rs:8:4
+   |
+LL | fn want_foo(f: Foo) {}
+   |    ^^^^^^^^ ------
 help: consider unboxing the value
    |
 LL |     want_foo(*b);
diff --git a/src/test/ui/traits/bound/sugar.stderr b/src/test/ui/traits/bound/sugar.stderr
index feb0c73a09d..b67648c7b04 100644
--- a/src/test/ui/traits/bound/sugar.stderr
+++ b/src/test/ui/traits/bound/sugar.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/sugar.rs:12:7
    |
 LL |     a(x);
-   |       ^ expected trait `Foo + Send`, found trait `Foo + Sync`
+   |     - ^ expected trait `Foo + Send`, found trait `Foo + Sync`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Box<(dyn Foo + Send + 'static)>`
               found struct `Box<(dyn Foo + Sync + 'static)>`
+note: function defined here
+  --> $DIR/sugar.rs:5:4
+   |
+LL | fn a(_x: Box<dyn Foo + Send>) {
+   |    ^ -----------------------
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/issue-52893.stderr b/src/test/ui/traits/issue-52893.stderr
index bf732e24915..f0c718c7a16 100644
--- a/src/test/ui/traits/issue-52893.stderr
+++ b/src/test/ui/traits/issue-52893.stderr
@@ -5,10 +5,17 @@ LL | impl<F, Name, P> AddClass<Name, F> for Class<P>
    |      - this type parameter
 ...
 LL |         builder.push(output);
-   |                      ^^^^^^ expected type parameter `F`, found struct `Class`
+   |                 ---- ^^^^^^ expected type parameter `F`, found struct `Class`
+   |                 |
+   |                 arguments to this function are incorrect
    |
-   = note: expected type parameter `F`
-                      found struct `Class<P>`
+   = note: expected type `F`
+            found struct `Class<P>`
+note: associated function defined here
+  --> $DIR/issue-52893.rs:11:8
+   |
+LL |     fn push(self, other: T) -> Self::PushRes;
+   |        ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/issue-95311.rs b/src/test/ui/traits/issue-95311.rs
new file mode 100644
index 00000000000..9d40d254ad9
--- /dev/null
+++ b/src/test/ui/traits/issue-95311.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+// Test to check that pointee trait doesn't let region variables escape into the cache
+
+#![feature(ptr_metadata)]
+
+trait Bar: Sized + 'static {}
+
+struct Foo<B: Bar> {
+    marker: std::marker::PhantomData<B>,
+}
+
+impl<B: Bar> Foo<B> {
+    fn foo<T: ?Sized>(value: &T) {
+        std::ptr::metadata(value);
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/multidispatch-bad.stderr b/src/test/ui/traits/multidispatch-bad.stderr
index 6caa23d8f49..8b6e610067b 100644
--- a/src/test/ui/traits/multidispatch-bad.stderr
+++ b/src/test/ui/traits/multidispatch-bad.stderr
@@ -2,8 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/multidispatch-bad.rs:19:17
    |
 LL |     test(22i32, 44i32);
-   |                 ^^^^^ expected `u32`, found `i32`
+   |     ----        ^^^^^ expected `u32`, found `i32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: function defined here
+  --> $DIR/multidispatch-bad.rs:13:4
+   |
+LL | fn test<T,U>(_: T, _: U)
+   |    ^^^^      ----  ----
 help: change the type of the numeric literal from `i32` to `u32`
    |
 LL |     test(22i32, 44u32);
diff --git a/src/test/ui/tuple/tuple-arity-mismatch.stderr b/src/test/ui/tuple/tuple-arity-mismatch.stderr
index 10bcedaf4aa..fff7be987f2 100644
--- a/src/test/ui/tuple/tuple-arity-mismatch.stderr
+++ b/src/test/ui/tuple/tuple-arity-mismatch.stderr
@@ -2,19 +2,33 @@ error[E0308]: mismatched types
   --> $DIR/tuple-arity-mismatch.rs:6:20
    |
 LL |     let y = first ((1,2.0,3));
-   |                    ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
+   |             -----  ^^^^^^^^^ expected a tuple with 2 elements, found one with 3 elements
+   |             |
+   |             arguments to this function are incorrect
    |
    = note: expected tuple `(isize, f64)`
               found tuple `(isize, f64, {integer})`
+note: function defined here
+  --> $DIR/tuple-arity-mismatch.rs:3:4
+   |
+LL | fn first((value, _): (isize, f64)) -> isize { value }
+   |    ^^^^^ ------------------------
 
 error[E0308]: mismatched types
   --> $DIR/tuple-arity-mismatch.rs:12:20
    |
 LL |     let y = first ((1,));
-   |                    ^^^^ expected a tuple with 2 elements, found one with 1 element
+   |             -----  ^^^^ expected a tuple with 2 elements, found one with 1 element
+   |             |
+   |             arguments to this function are incorrect
    |
    = note: expected tuple `(isize, f64)`
               found tuple `(isize,)`
+note: function defined here
+  --> $DIR/tuple-arity-mismatch.rs:3:4
+   |
+LL | fn first((value, _): (isize, f64)) -> isize { value }
+   |    ^^^^^ ------------------------
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/tuple/wrong_argument_ice-2.stderr b/src/test/ui/tuple/wrong_argument_ice-2.stderr
index ddafc9763e7..c704ae9934b 100644
--- a/src/test/ui/tuple/wrong_argument_ice-2.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-2.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice-2.rs:13:5
    |
 LL |     test(x.qux(), x.qux());
-   |     ^^^^ -------  ------- supplied 2 arguments
+   |     ^^^^
    |
 note: function defined here
   --> $DIR/wrong_argument_ice-2.rs:1:4
diff --git a/src/test/ui/tuple/wrong_argument_ice-3.stderr b/src/test/ui/tuple/wrong_argument_ice-3.stderr
index f0d64d2a4e1..6ea6e670fd6 100644
--- a/src/test/ui/tuple/wrong_argument_ice-3.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-3.stderr
@@ -2,15 +2,21 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice-3.rs:9:16
    |
 LL |         groups.push(new_group, vec![process]);
-   |                ^^^^ ---------  ------------- supplied 2 arguments
-   |                |
-   |                expected 1 argument
+   |                ^^^^ ---------  ------------- argument unexpected
+   |                     |
+   |                     expected tuple, found struct `Vec`
    |
+   = note: expected tuple `(Vec<String>, Vec<Process>)`
+             found struct `Vec<String>`
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
 LL |     pub fn push(&mut self, value: T) {
    |            ^^^^
+help: remove the extra argument
+   |
+LL |         groups.push({(Vec<String>, Vec<Process>)});
+   |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/tuple/wrong_argument_ice-4.stderr b/src/test/ui/tuple/wrong_argument_ice-4.stderr
index fef5dca856d..0c25b6801dc 100644
--- a/src/test/ui/tuple/wrong_argument_ice-4.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice-4.stderr
@@ -3,12 +3,15 @@ error[E0057]: this function takes 0 arguments but 1 argument was supplied
    |
 LL |       (|| {})(|| {
    |  _____^^^^^^^_-
-   | |     |
-   | |     expected 0 arguments
 LL | |
 LL | |         let b = 1;
 LL | |     });
-   | |_____- supplied 1 argument
+   | |_____- argument unexpected
+   |
+help: remove the extra argument
+   |
+LL |     (|| {})();
+   |     ~~~~~~~~~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/tuple/wrong_argument_ice.stderr b/src/test/ui/tuple/wrong_argument_ice.stderr
index e96a957350b..2b4cb669f5c 100644
--- a/src/test/ui/tuple/wrong_argument_ice.stderr
+++ b/src/test/ui/tuple/wrong_argument_ice.stderr
@@ -2,7 +2,7 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/wrong_argument_ice.rs:11:18
    |
 LL |         self.acc.push_back(self.current_provides, self.current_requires);
-   |                  ^^^^^^^^^ ---------------------  --------------------- supplied 2 arguments
+   |                  ^^^^^^^^^
    |
 note: associated function defined here
   --> $SRC_DIR/alloc/src/collections/vec_deque/mod.rs:LL:COL
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index a384d5f561c..115ecb01376 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -5,10 +5,17 @@ LL | impl<T> Enum<T> {
    |      - this type parameter
 LL |     fn ts_variant() {
 LL |         Self::TSVariant(());
-   |                         ^^ expected type parameter `T`, found `()`
+   |         --------------- ^^ expected type parameter `T`, found `()`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                    found unit type `()`
+note: tuple variant defined here
+  --> $DIR/enum-variant-generic-args.rs:7:16
+   |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+   |                ^^^^^^^^^
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:15:27
@@ -29,10 +36,17 @@ LL | impl<T> Enum<T> {
    |      - this type parameter
 ...
 LL |         Self::<()>::TSVariant(());
-   |                               ^^ expected type parameter `T`, found `()`
+   |         --------------------- ^^ expected type parameter `T`, found `()`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected type parameter `T`
                    found unit type `()`
+note: tuple variant defined here
+  --> $DIR/enum-variant-generic-args.rs:7:16
+   |
+LL | enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+   |                ^^^^^^^^^
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:20:16
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
index 37543c137f6..3fc5a3594d8 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -2,15 +2,17 @@ error[E0061]: this function takes 1 argument but 0 arguments were supplied
   --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:21:5
    |
 LL |     <E>::V();
-   |     ^^^^^^-- supplied 0 arguments
-   |     |
-   |     expected 1 argument
+   |     ^^^^^^-- an argument of type `u8` is missing
    |
 note: tuple variant defined here
   --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5
    |
 LL |     V(u8)
    |     ^
+help: provide the argument
+   |
+LL |     <E>::V({u8});
+   |     ~~~~~~~~~~~~
 
 error[E0308]: mismatched types
   --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
diff --git a/src/test/ui/type/type-ascription-instead-of-initializer.stderr b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
index e5666d4fe4f..18ed4986f89 100644
--- a/src/test/ui/type/type-ascription-instead-of-initializer.stderr
+++ b/src/test/ui/type/type-ascription-instead-of-initializer.stderr
@@ -11,15 +11,17 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
   --> $DIR/type-ascription-instead-of-initializer.rs:2:12
    |
 LL |     let x: Vec::with_capacity(10, 20);
-   |            ^^^^^^^^^^^^^^^^^^ --  -- supplied 2 arguments
-   |            |
-   |            expected 1 argument
+   |            ^^^^^^^^^^^^^^^^^^     -- argument unexpected
    |
 note: associated function defined here
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    |
 LL |     pub fn with_capacity(capacity: usize) -> Self {
    |            ^^^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL |     let x: Vec::with_capacity(10);
+   |            ~~~~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type/type-mismatch-same-crate-name.stderr b/src/test/ui/type/type-mismatch-same-crate-name.stderr
index 49d40ebed13..783f747fa6d 100644
--- a/src/test/ui/type/type-mismatch-same-crate-name.stderr
+++ b/src/test/ui/type/type-mismatch-same-crate-name.stderr
@@ -2,19 +2,33 @@ error[E0308]: mismatched types
   --> $DIR/type-mismatch-same-crate-name.rs:16:20
    |
 LL |         a::try_foo(foo2);
-   |                    ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo`
+   |         ---------- ^^^^ expected struct `main::a::Foo`, found a different struct `main::a::Foo`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: perhaps two different versions of crate `crate_a1` are being used?
+note: function defined here
+  --> $DIR/auxiliary/crate_a1.rs:10:8
+   |
+LL | pub fn try_foo(x: Foo){}
+   |        ^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch-same-crate-name.rs:20:20
    |
 LL |         a::try_bar(bar2);
-   |                    ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar`
+   |         ---------- ^^^^ expected trait `main::a::Bar`, found a different trait `main::a::Bar`
+   |         |
+   |         arguments to this function are incorrect
    |
    = note: expected struct `Box<(dyn main::a::Bar + 'static)>`
               found struct `Box<dyn main::a::Bar>`
    = note: perhaps two different versions of crate `crate_a1` are being used?
+note: function defined here
+  --> $DIR/auxiliary/crate_a1.rs:11:8
+   |
+LL | pub fn try_bar(x: Box<Bar>){}
+   |        ^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type/type-mismatch.stderr b/src/test/ui/type/type-mismatch.stderr
index 24c71c63103..6c187bad072 100644
--- a/src/test/ui/type/type-mismatch.stderr
+++ b/src/test/ui/type/type-mismatch.stderr
@@ -2,418 +2,749 @@ error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:17:17
    |
 LL |     want::<foo>(f);
-   |                 ^ expected struct `foo`, found `usize`
+   |     ----------- ^ expected struct `foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:18:17
    |
 LL |     want::<bar>(f);
-   |                 ^ expected struct `bar`, found `usize`
+   |     ----------- ^ expected struct `bar`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:19:24
    |
 LL |     want::<Foo<usize>>(f);
-   |                        ^ expected struct `Foo`, found `usize`
+   |     ------------------ ^ expected struct `Foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize>`
                 found type `usize`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:20:27
    |
 LL |     want::<Foo<usize, B>>(f);
-   |                           ^ expected struct `Foo`, found `usize`
+   |     --------------------- ^ expected struct `Foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, B>`
                 found type `usize`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:21:22
    |
 LL |     want::<Foo<foo>>(f);
-   |                      ^ expected struct `Foo`, found `usize`
+   |     ---------------- ^ expected struct `Foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<foo>`
                 found type `usize`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:22:25
    |
 LL |     want::<Foo<foo, B>>(f);
-   |                         ^ expected struct `Foo`, found `usize`
+   |     ------------------- ^ expected struct `Foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<foo, B>`
                 found type `usize`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:23:22
    |
 LL |     want::<Foo<bar>>(f);
-   |                      ^ expected struct `Foo`, found `usize`
+   |     ---------------- ^ expected struct `Foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar>`
                 found type `usize`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:24:25
    |
 LL |     want::<Foo<bar, B>>(f);
-   |                         ^ expected struct `Foo`, found `usize`
+   |     ------------------- ^ expected struct `Foo`, found `usize`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, B>`
                 found type `usize`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:28:19
    |
 LL |     want::<usize>(f);
-   |                   ^ expected `usize`, found struct `foo`
+   |     ------------- ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:29:17
    |
 LL |     want::<bar>(f);
-   |                 ^ expected struct `bar`, found struct `foo`
+   |     ----------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:30:24
    |
 LL |     want::<Foo<usize>>(f);
-   |                        ^ expected struct `Foo`, found struct `foo`
+   |     ------------------ ^ expected struct `Foo`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize>`
               found struct `foo`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:31:27
    |
 LL |     want::<Foo<usize, B>>(f);
-   |                           ^ expected struct `Foo`, found struct `foo`
+   |     --------------------- ^ expected struct `Foo`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, B>`
               found struct `foo`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:32:22
    |
 LL |     want::<Foo<foo>>(f);
-   |                      ^ expected struct `Foo`, found struct `foo`
+   |     ---------------- ^ expected struct `Foo`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<foo>`
               found struct `foo`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:33:25
    |
 LL |     want::<Foo<foo, B>>(f);
-   |                         ^ expected struct `Foo`, found struct `foo`
+   |     ------------------- ^ expected struct `Foo`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<foo, B>`
               found struct `foo`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:34:22
    |
 LL |     want::<Foo<bar>>(f);
-   |                      ^ expected struct `Foo`, found struct `foo`
+   |     ---------------- ^ expected struct `Foo`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar>`
               found struct `foo`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:35:25
    |
 LL |     want::<Foo<bar, B>>(f);
-   |                         ^ expected struct `Foo`, found struct `foo`
+   |     ------------------- ^ expected struct `Foo`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, B>`
               found struct `foo`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:39:19
    |
 LL |     want::<usize>(f);
-   |                   ^ expected `usize`, found struct `Foo`
+   |     ------------- ^ expected `usize`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `usize`
             found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:40:17
    |
 LL |     want::<foo>(f);
-   |                 ^ expected struct `foo`, found struct `Foo`
+   |     ----------- ^ expected struct `foo`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `foo`
               found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:41:17
    |
 LL |     want::<bar>(f);
-   |                 ^ expected struct `bar`, found struct `Foo`
+   |     ----------- ^ expected struct `bar`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `bar`
               found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:42:24
    |
 LL |     want::<Foo<usize>>(f);
-   |                        ^ expected `usize`, found struct `foo`
+   |     ------------------ ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize>`
               found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:43:27
    |
 LL |     want::<Foo<usize, B>>(f);
-   |                           ^ expected `usize`, found struct `foo`
+   |     --------------------- ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, B>`
               found struct `Foo<foo, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:44:25
    |
 LL |     want::<Foo<foo, B>>(f);
-   |                         ^ expected struct `B`, found struct `A`
+   |     ------------------- ^ expected struct `B`, found struct `A`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<_, B>`
               found struct `Foo<_, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:45:22
    |
 LL |     want::<Foo<bar>>(f);
-   |                      ^ expected struct `bar`, found struct `foo`
+   |     ---------------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar>`
               found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:46:25
    |
 LL |     want::<Foo<bar, B>>(f);
-   |                         ^ expected struct `bar`, found struct `foo`
+   |     ------------------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, B>`
               found struct `Foo<foo, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:47:23
    |
 LL |     want::<&Foo<foo>>(f);
-   |                       ^
-   |                       |
-   |                       expected `&Foo<foo>`, found struct `Foo`
-   |                       help: consider borrowing here: `&f`
+   |     ----------------- ^
+   |     |                 |
+   |     |                 expected `&Foo<foo>`, found struct `Foo`
+   |     |                 help: consider borrowing here: `&f`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo>`
                  found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:48:26
    |
 LL |     want::<&Foo<foo, B>>(f);
-   |                          ^ expected `&Foo<foo, B>`, found struct `Foo`
+   |     -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo, B>`
                  found struct `Foo<foo>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:52:19
    |
 LL |     want::<usize>(f);
-   |                   ^ expected `usize`, found struct `Foo`
+   |     ------------- ^ expected `usize`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `usize`
             found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:53:17
    |
 LL |     want::<foo>(f);
-   |                 ^ expected struct `foo`, found struct `Foo`
+   |     ----------- ^ expected struct `foo`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `foo`
               found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:54:17
    |
 LL |     want::<bar>(f);
-   |                 ^ expected struct `bar`, found struct `Foo`
+   |     ----------- ^ expected struct `bar`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `bar`
               found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:55:24
    |
 LL |     want::<Foo<usize>>(f);
-   |                        ^ expected `usize`, found struct `foo`
+   |     ------------------ ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, A>`
               found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:56:27
    |
 LL |     want::<Foo<usize, B>>(f);
-   |                           ^ expected `usize`, found struct `foo`
+   |     --------------------- ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, _>`
               found struct `Foo<foo, _>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:57:22
    |
 LL |     want::<Foo<foo>>(f);
-   |                      ^ expected struct `A`, found struct `B`
+   |     ---------------- ^ expected struct `A`, found struct `B`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<_, A>`
               found struct `Foo<_, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:58:22
    |
 LL |     want::<Foo<bar>>(f);
-   |                      ^ expected struct `bar`, found struct `foo`
+   |     ---------------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, A>`
               found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:59:25
    |
 LL |     want::<Foo<bar, B>>(f);
-   |                         ^ expected struct `bar`, found struct `foo`
+   |     ------------------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, _>`
               found struct `Foo<foo, _>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:60:23
    |
 LL |     want::<&Foo<foo>>(f);
-   |                       ^ expected `&Foo<foo>`, found struct `Foo`
+   |     ----------------- ^ expected `&Foo<foo>`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo>`
                  found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:61:26
    |
 LL |     want::<&Foo<foo, B>>(f);
-   |                          ^
-   |                          |
-   |                          expected `&Foo<foo, B>`, found struct `Foo`
-   |                          help: consider borrowing here: `&f`
+   |     -------------------- ^
+   |     |                    |
+   |     |                    expected `&Foo<foo, B>`, found struct `Foo`
+   |     |                    help: consider borrowing here: `&f`
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo, B>`
                  found struct `Foo<foo, B>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:65:19
    |
 LL |     want::<usize>(f);
-   |                   ^ expected `usize`, found struct `Foo`
+   |     ------------- ^ expected `usize`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected type `usize`
             found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:66:17
    |
 LL |     want::<foo>(f);
-   |                 ^ expected struct `foo`, found struct `Foo`
+   |     ----------- ^ expected struct `foo`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `foo`
               found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:67:17
    |
 LL |     want::<bar>(f);
-   |                 ^ expected struct `bar`, found struct `Foo`
+   |     ----------- ^ expected struct `bar`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `bar`
               found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:68:24
    |
 LL |     want::<Foo<usize>>(f);
-   |                        ^ expected `usize`, found struct `foo`
+   |     ------------------ ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, A, B>`
               found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:69:27
    |
 LL |     want::<Foo<usize, B>>(f);
-   |                           ^ expected `usize`, found struct `foo`
+   |     --------------------- ^ expected `usize`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<usize, _, B>`
               found struct `Foo<foo, _, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:70:22
    |
 LL |     want::<Foo<foo>>(f);
-   |                      ^ expected struct `A`, found struct `B`
+   |     ---------------- ^ expected struct `A`, found struct `B`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<_, A, B>`
               found struct `Foo<_, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:71:25
    |
 LL |     want::<Foo<foo, B>>(f);
-   |                         ^ expected struct `B`, found struct `A`
+   |     ------------------- ^ expected struct `B`, found struct `A`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<_, _, B>`
               found struct `Foo<_, _, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:72:22
    |
 LL |     want::<Foo<bar>>(f);
-   |                      ^ expected struct `bar`, found struct `foo`
+   |     ---------------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, A, B>`
               found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:73:25
    |
 LL |     want::<Foo<bar, B>>(f);
-   |                         ^ expected struct `bar`, found struct `foo`
+   |     ------------------- ^ expected struct `bar`, found struct `foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected struct `Foo<bar, _, B>`
               found struct `Foo<foo, _, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:74:23
    |
 LL |     want::<&Foo<foo>>(f);
-   |                       ^ expected `&Foo<foo>`, found struct `Foo`
+   |     ----------------- ^ expected `&Foo<foo>`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo>`
                  found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error[E0308]: mismatched types
   --> $DIR/type-mismatch.rs:75:26
    |
 LL |     want::<&Foo<foo, B>>(f);
-   |                          ^ expected `&Foo<foo, B>`, found struct `Foo`
+   |     -------------------- ^ expected `&Foo<foo, B>`, found struct `Foo`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected reference `&Foo<foo, B>`
                  found struct `Foo<foo, B, A>`
+note: function defined here
+  --> $DIR/type-mismatch.rs:14:4
+   |
+LL | fn want<T>(t: T) {}
+   |    ^^^^    ----
 
 error: aborting due to 47 previous errors
 
diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.rs b/src/test/ui/typeck/autoderef-with-param-env-error.rs
new file mode 100644
index 00000000000..ec96c61c63e
--- /dev/null
+++ b/src/test/ui/typeck/autoderef-with-param-env-error.rs
@@ -0,0 +1,9 @@
+fn foo()
+where
+    T: Send,
+    //~^ cannot find type `T` in this scope
+{
+    let s = "abc".to_string();
+}
+
+fn main() {}
diff --git a/src/test/ui/typeck/autoderef-with-param-env-error.stderr b/src/test/ui/typeck/autoderef-with-param-env-error.stderr
new file mode 100644
index 00000000000..cde800336dd
--- /dev/null
+++ b/src/test/ui/typeck/autoderef-with-param-env-error.stderr
@@ -0,0 +1,12 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/autoderef-with-param-env-error.rs:3:5
+   |
+LL | fn foo()
+   |       - help: you might be missing a type parameter: `<T>`
+LL | where
+LL |     T: Send,
+   |     ^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/typeck/issue-46112.stderr b/src/test/ui/typeck/issue-46112.stderr
index 39bff88e7f8..93461507501 100644
--- a/src/test/ui/typeck/issue-46112.stderr
+++ b/src/test/ui/typeck/issue-46112.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/issue-46112.rs:9:21
    |
 LL | fn main() { test(Ok(())); }
-   |                     ^^ expected enum `Option`, found `()`
+   |                  -- ^^ expected enum `Option`, found `()`
+   |                  |
+   |                  arguments to this enum variant are incorrect
    |
    = note:   expected enum `Option<()>`
            found unit type `()`
diff --git a/src/test/ui/typeck/issue-84768.stderr b/src/test/ui/typeck/issue-84768.stderr
index 0a79d539ea9..04dc0e36520 100644
--- a/src/test/ui/typeck/issue-84768.stderr
+++ b/src/test/ui/typeck/issue-84768.stderr
@@ -8,10 +8,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-84768.rs:7:42
    |
 LL |     <F as FnOnce(&mut u8)>::call_once(f, 1)
-   |                                          ^ expected tuple, found integer
+   |     ---------------------------------    ^ expected tuple, found integer
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected tuple `(&mut u8,)`
                found type `{integer}`
+note: associated function defined here
+  --> $SRC_DIR/core/src/ops/function.rs:LL:COL
+   |
+LL |     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+   |                           ^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/typeck/issue-89856.stderr b/src/test/ui/typeck/issue-89856.stderr
index 4cb46a34a07..5fa1ae1a54f 100644
--- a/src/test/ui/typeck/issue-89856.stderr
+++ b/src/test/ui/typeck/issue-89856.stderr
@@ -2,10 +2,17 @@ error[E0308]: mismatched types
   --> $DIR/issue-89856.rs:6:20
    |
 LL |     take_str_maybe(option);
-   |                    ^^^^^^ expected `str`, found struct `String`
+   |     -------------- ^^^^^^ expected `str`, found struct `String`
+   |     |
+   |     arguments to this function are incorrect
    |
    = note: expected enum `Option<&str>`
               found enum `Option<&String>`
+note: function defined here
+  --> $DIR/issue-89856.rs:1:4
+   |
+LL | fn take_str_maybe(x: Option<&str>) -> Option<&str> { None }
+   |    ^^^^^^^^^^^^^^ ---------------
 help: try converting the passed type into a `&str`
    |
 LL |     take_str_maybe(option.map(|x| &**x));
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr
index 6e99feed33f..721b2c821ef 100644
--- a/src/test/ui/typeck/struct-enum-wrong-args.stderr
+++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr
@@ -2,95 +2,116 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:6:13
    |
 LL |     let _ = Some(3, 2);
-   |             ^^^^ -  - supplied 2 arguments
-   |             |
-   |             expected 1 argument
+   |             ^^^^    - argument unexpected
+   |
+help: remove the extra argument
+   |
+LL |     let _ = Some(3);
+   |             ~~~~~~~
 
 error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:7:13
    |
 LL |     let _ = Ok(3, 6, 2);
-   |             ^^ -  -  - supplied 3 arguments
-   |             |
-   |             expected 1 argument
+   |             ^^    -  - argument unexpected
+   |                   |
+   |                   argument unexpected
+   |
+help: remove the extra arguments
+   |
+LL |     let _ = Ok(3);
+   |             ~~~~~
 
 error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:8:13
    |
 LL |     let _ = Ok();
-   |             ^^-- supplied 0 arguments
-   |             |
-   |             expected 1 argument
+   |             ^^-- an argument is missing
+   |
+help: provide the argument
+   |
+LL |     let _ = Ok({_});
+   |             ~~~~~~~
 
 error[E0061]: this struct takes 1 argument but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:9:13
    |
 LL |     let _ = Wrapper();
-   |             ^^^^^^^-- supplied 0 arguments
-   |             |
-   |             expected 1 argument
+   |             ^^^^^^^-- an argument of type `i32` is missing
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:2:8
    |
 LL | struct Wrapper(i32);
    |        ^^^^^^^
+help: provide the argument
+   |
+LL |     let _ = Wrapper({i32});
+   |             ~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:10:13
    |
 LL |     let _ = Wrapper(5, 2);
-   |             ^^^^^^^ -  - supplied 2 arguments
-   |             |
-   |             expected 1 argument
+   |             ^^^^^^^    - argument unexpected
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:2:8
    |
 LL | struct Wrapper(i32);
    |        ^^^^^^^
+help: remove the extra argument
+   |
+LL |     let _ = Wrapper(5);
+   |             ~~~~~~~~~~
 
 error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:11:13
    |
 LL |     let _ = DoubleWrapper();
-   |             ^^^^^^^^^^^^^-- supplied 0 arguments
-   |             |
-   |             expected 2 arguments
+   |             ^^^^^^^^^^^^^-- two arguments of type `i32` and `i32` are missing
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:3:8
    |
 LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
+help: provide the arguments
+   |
+LL |     let _ = DoubleWrapper({i32}, {i32});
+   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 2 arguments but 1 argument was supplied
   --> $DIR/struct-enum-wrong-args.rs:12:13
    |
 LL |     let _ = DoubleWrapper(5);
-   |             ^^^^^^^^^^^^^ - supplied 1 argument
-   |             |
-   |             expected 2 arguments
+   |             ^^^^^^^^^^^^^--- an argument of type `i32` is missing
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:3:8
    |
 LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
+help: provide the argument
+   |
+LL |     let _ = DoubleWrapper(5, {i32});
+   |             ~~~~~~~~~~~~~~~~~~~~~~~
 
 error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:13:13
    |
 LL |     let _ = DoubleWrapper(5, 2, 7);
-   |             ^^^^^^^^^^^^^ -  -  - supplied 3 arguments
-   |             |
-   |             expected 2 arguments
+   |             ^^^^^^^^^^^^^       - argument unexpected
    |
 note: tuple struct defined here
   --> $DIR/struct-enum-wrong-args.rs:3:8
    |
 LL | struct DoubleWrapper(i32, i32);
    |        ^^^^^^^^^^^^^
+help: remove the extra argument
+   |
+LL |     let _ = DoubleWrapper(5, 2);
+   |             ~~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index 74766d9fdd1..c6f9b3661a2 100644
--- a/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/src/test/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -20,8 +20,15 @@ error[E0308]: mismatched types
   --> $DIR/ufcs-qpath-self-mismatch.rs:6:28
    |
 LL |     <i32 as Add<i32>>::add(1u32, 2);
-   |                            ^^^^ expected `i32`, found `u32`
+   |     ---------------------- ^^^^ expected `i32`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
    |
+note: associated function defined here
+  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+   |
+LL |     fn add(self, rhs: Rhs) -> Self::Output;
+   |        ^^^
 help: change the type of the numeric literal from `u32` to `i32`
    |
 LL |     <i32 as Add<i32>>::add(1i32, 2);
@@ -31,8 +38,15 @@ error[E0308]: mismatched types
   --> $DIR/ufcs-qpath-self-mismatch.rs:8:31
    |
 LL |     <i32 as Add<i32>>::add(1, 2u32);
-   |                               ^^^^ expected `i32`, found `u32`
+   |     ----------------------    ^^^^ expected `i32`, found `u32`
+   |     |
+   |     arguments to this function are incorrect
+   |
+note: associated function defined here
+  --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
    |
+LL |     fn add(self, rhs: Rhs) -> Self::Output;
+   |        ^^^
 help: change the type of the numeric literal from `u32` to `i32`
    |
 LL |     <i32 as Add<i32>>::add(1, 2i32);
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
index f791ea62ceb..ea1ca380b1c 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-type-mismatch.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/unboxed-closures-type-mismatch.rs:5:15
    |
 LL |     let z = f(1_usize, 2);
-   |               ^^^^^^^ expected `isize`, found `usize`
+   |             - ^^^^^^^ expected `isize`, found `usize`
+   |             |
+   |             arguments to this function are incorrect
    |
 help: change the type of the numeric literal from `usize` to `isize`
    |
diff --git a/src/test/ui/unterminated-nested-comment.rs b/src/test/ui/unterminated-nested-comment.rs
new file mode 100644
index 00000000000..db5f2f3ba13
--- /dev/null
+++ b/src/test/ui/unterminated-nested-comment.rs
@@ -0,0 +1,4 @@
+/* //~ ERROR E0758
+/* */
+/*
+*/
diff --git a/src/test/ui/unterminated-nested-comment.stderr b/src/test/ui/unterminated-nested-comment.stderr
new file mode 100644
index 00000000000..3653e76c9cb
--- /dev/null
+++ b/src/test/ui/unterminated-nested-comment.stderr
@@ -0,0 +1,21 @@
+error[E0758]: unterminated block comment
+  --> $DIR/unterminated-nested-comment.rs:1:1
+   |
+LL |   /*
+   |   ^-
+   |   |
+   |  _unterminated block comment
+   | |
+LL | | /* */
+LL | | /*
+   | | --
+   | | |
+   | | ...as last nested comment starts here, maybe you want to close this instead?
+LL | | */
+   | |_--^
+   |   |
+   |   ...and last nested comment terminates here.
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0758`.
diff --git a/src/test/ui/use/use-super-global-path.rs b/src/test/ui/use/use-super-global-path.rs
index 27a4a653b49..64bfd14b7e7 100644
--- a/src/test/ui/use/use-super-global-path.rs
+++ b/src/test/ui/use/use-super-global-path.rs
@@ -9,7 +9,7 @@ mod foo {
 
     pub fn g() {
         use ::super::main; //~ ERROR global paths cannot start with `super`
-        main(); //~ ERROR cannot find function `main` in this scope
+        main();
     }
 }
 
diff --git a/src/test/ui/use/use-super-global-path.stderr b/src/test/ui/use/use-super-global-path.stderr
index edde26c1fc1..7014a12e9dd 100644
--- a/src/test/ui/use/use-super-global-path.stderr
+++ b/src/test/ui/use/use-super-global-path.stderr
@@ -16,18 +16,6 @@ error[E0433]: failed to resolve: global paths cannot start with `super`
 LL |         use ::super::main;
    |               ^^^^^ global paths cannot start with `super`
 
-error[E0425]: cannot find function `main` in this scope
-  --> $DIR/use-super-global-path.rs:12:9
-   |
-LL |         main();
-   |         ^^^^ not found in this scope
-   |
-help: consider importing this function
-   |
-LL |     use main;
-   |
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0425, E0433.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject e2e2dddebe66dfc1403a312653557e332445308
+Subproject dba5baf4345858c591517b24801902a062c399f
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 72e86804ed2..6ed141fa4a5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -59,7 +59,7 @@ pub(super) fn check<'tcx>(
                 if let Some(indexed_extent) = indexed_extent {
                     let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id);
                     let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id);
-                    let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id);
+                    let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
                     if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) {
                         return;
                     }
@@ -262,7 +262,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
                 match res {
                     Res::Local(hir_id) => {
                         let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
-                        let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id);
+                        let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id).unwrap();
                         if index_used_directly {
                             self.indexed_directly.insert(
                                 seqvar.segments[0].ident.name,
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index a0b2302662e..9ba9642fcc8 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -169,13 +169,14 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
             .iter()
             .map(|(o, _)| match o {
                 InlineAsmOperand::In { expr, .. }
-                | InlineAsmOperand::InOut { expr, .. }
-                | InlineAsmOperand::Sym { expr } => never_loop_expr(expr, main_loop_id),
+                | InlineAsmOperand::InOut { expr, .. } => never_loop_expr(expr, main_loop_id),
                 InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id),
                 InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                     never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id)
                 },
-                InlineAsmOperand::Const { .. } => NeverLoopResult::Otherwise,
+                InlineAsmOperand::Const { .. }
+                | InlineAsmOperand::SymFn { .. }
+                | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
             })
             .fold(NeverLoopResult::Otherwise, combine_both),
         ExprKind::Struct(_, _, None)
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs
index 11882585044..1ab7f52110c 100644
--- a/src/tools/clippy/clippy_lints/src/shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -160,8 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
 
 fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
     let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());
-    let first_scope = scope_tree.var_scope(first);
-    let second_scope = scope_tree.var_scope(second);
+    let first_scope = scope_tree.var_scope(first).unwrap();
+    let second_scope = scope_tree.var_scope(second).unwrap();
     scope_tree.is_subscope_of(second_scope, first_scope)
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
index dc48ea3f4f9..a04288e0a41 100644
--- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
@@ -281,8 +281,9 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) {
             for (op, _op_sp) in asm.operands {
                 match op {
                     hir::InlineAsmOperand::In { expr, .. }
-                    | hir::InlineAsmOperand::InOut { expr, .. }
-                    | hir::InlineAsmOperand::Sym { expr } => print_expr(cx, expr, indent + 1),
+                    | hir::InlineAsmOperand::InOut { expr, .. } => {
+                        print_expr(cx, expr, indent + 1);
+                    }
                     hir::InlineAsmOperand::Out { expr, .. } => {
                         if let Some(expr) = expr {
                             print_expr(cx, expr, indent + 1);
@@ -294,10 +295,26 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) {
                             print_expr(cx, out_expr, indent + 1);
                         }
                     },
-                    hir::InlineAsmOperand::Const { anon_const } => {
+                    hir::InlineAsmOperand::Const { anon_const }
+                    | hir::InlineAsmOperand::SymFn { anon_const } => {
                         println!("{}anon_const:", ind);
                         print_expr(cx, &cx.tcx.hir().body(anon_const.body).value, indent + 1);
                     },
+                    hir::InlineAsmOperand::SymStatic { path, .. } => {
+                        match path {
+                            hir::QPath::Resolved(ref ty, path) => {
+                                println!("{}Resolved Path, {:?}", ind, ty);
+                                println!("{}path: {:?}", ind, path);
+                            },
+                            hir::QPath::TypeRelative(ty, seg) => {
+                                println!("{}Relative Path, {:?}", ind, ty);
+                                println!("{}seg: {:?}", ind, seg);
+                            },
+                            hir::QPath::LangItem(lang_item, ..) => {
+                                println!("{}Lang Item Path, {:?}", ind, lang_item.name());
+                            },
+                        }
+                    }
                 }
             }
         },
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 00594f4d42a..c05317f59b7 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -675,7 +675,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                             }
                         },
                         InlineAsmOperand::Const { anon_const } => self.hash_body(anon_const.body),
-                        InlineAsmOperand::Sym { expr } => self.hash_expr(expr),
+                        InlineAsmOperand::SymFn { anon_const } => self.hash_body(anon_const.body),
+                        InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path),
                     }
                 }
             },
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 79e6e92dc0a..e5fa6deefc5 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -23,7 +23,7 @@ pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "
 pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
 pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
 pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
-pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
+pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"];
 pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
 pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
 /// Preferably use the diagnostic item `sym::deref_method` where possible
diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs
index ad10b9ede60..8e871e61f26 100644
--- a/src/tools/rustfmt/src/bin/main.rs
+++ b/src/tools/rustfmt/src/bin/main.rs
@@ -693,6 +693,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result<Edition> {
         "2015" => Ok(Edition::Edition2015),
         "2018" => Ok(Edition::Edition2018),
         "2021" => Ok(Edition::Edition2021),
+        "2024" => Ok(Edition::Edition2024),
         _ => Err(format_err!("Invalid value for `--edition`")),
     }
 }
diff --git a/src/tools/rustfmt/src/config/options.rs b/src/tools/rustfmt/src/config/options.rs
index d857c29be29..257a17b2703 100644
--- a/src/tools/rustfmt/src/config/options.rs
+++ b/src/tools/rustfmt/src/config/options.rs
@@ -423,6 +423,10 @@ pub enum Edition {
     #[doc_hint = "2021"]
     /// Edition 2021.
     Edition2021,
+    #[value = "2024"]
+    #[doc_hint = "2024"]
+    /// Edition 2024.
+    Edition2024,
 }
 
 impl Default for Edition {
@@ -437,6 +441,7 @@ impl From<Edition> for rustc_span::edition::Edition {
             Edition::Edition2015 => Self::Edition2015,
             Edition::Edition2018 => Self::Edition2018,
             Edition::Edition2021 => Self::Edition2021,
+            Edition::Edition2024 => Self::Edition2024,
         }
     }
 }