about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--Cargo.lock5
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs20
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs38
-rw-r--r--compiler/rustc_attr/src/session_diagnostics.rs47
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs8
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs64
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs80
-rw-r--r--compiler/rustc_const_eval/src/errors.rs52
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs14
-rw-r--r--compiler/rustc_driver_impl/Cargo.toml1
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs58
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs658
-rw-r--r--compiler/rustc_error_codes/src/lib.rs678
-rw-r--r--compiler/rustc_errors/Cargo.toml2
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs7
-rw-r--r--compiler/rustc_errors/src/codes.rs39
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs17
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs13
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs3
-rw-r--r--compiler/rustc_errors/src/emitter.rs12
-rw-r--r--compiler/rustc_errors/src/json.rs4
-rw-r--r--compiler/rustc_errors/src/lib.rs31
-rw-r--r--compiler/rustc_errors/src/registry.rs9
-rw-r--r--compiler/rustc_expand/src/errors.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/object_safety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/dropck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs140
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs34
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs54
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs14
-rw-r--r--compiler/rustc_index/src/interval.rs6
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs66
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs12
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs4
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_lint/src/errors.rs14
-rw-r--r--compiler/rustc_lint/src/lints.rs6
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs4
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs2
-rw-r--r--compiler/rustc_metadata/src/errors.rs28
-rw-r--r--compiler/rustc_middle/src/error.rs4
-rw-r--r--compiler/rustc_middle/src/values.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs37
-rw-r--r--compiler/rustc_mir_build/src/errors.rs64
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs4
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs6
-rw-r--r--compiler/rustc_parse/messages.ftl14
-rw-r--r--compiler/rustc_parse/src/errors.rs30
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs16
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs13
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs1
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs155
-rw-r--r--compiler/rustc_passes/src/entry.rs6
-rw-r--r--compiler/rustc_passes/src/errors.rs94
-rw-r--r--compiler/rustc_pattern_analysis/Cargo.toml1
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs98
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs20
-rw-r--r--compiler/rustc_pattern_analysis/src/pat.rs31
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs8
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs58
-rw-r--r--compiler/rustc_privacy/src/errors.rs6
-rw-r--r--compiler/rustc_query_system/src/error.rs3
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs4
-rw-r--r--compiler/rustc_resolve/src/errors.rs66
-rw-r--r--compiler/rustc_resolve/src/imports.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs54
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs14
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--compiler/rustc_resolve/src/macros.rs2
-rw-r--r--compiler/rustc_session/src/errors.rs6
-rw-r--r--compiler/rustc_session/src/session.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs12
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs4
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs3
-rw-r--r--library/alloc/src/rc.rs7
-rw-r--r--library/alloc/src/sync.rs10
-rw-r--r--library/core/src/num/mod.rs10
-rw-r--r--library/core/src/num/nonzero.rs50
-rw-r--r--library/core/src/primitive_docs.rs24
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/num.rs10
-rw-r--r--library/std/src/sys/pal/windows/fs.rs34
-rwxr-xr-xsrc/ci/docker/run.sh116
-rw-r--r--src/ci/github-actions/ci.yml2
-rw-r--r--src/etc/natvis/libcore.natvis35
-rw-r--r--src/librustdoc/clean/mod.rs5
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs51
-rw-r--r--src/tools/error_index_generator/Cargo.toml1
-rw-r--r--src/tools/error_index_generator/main.rs8
-rw-r--r--src/tools/miri/.github/workflows/sysroots.yml6
-rw-r--r--src/tools/miri/Cargo.lock4
-rw-r--r--src/tools/miri/README.md1
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs9
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/helpers.rs19
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--src/tools/miri/src/machine.rs95
-rw-r--r--src/tools/miri/src/operator.rs2
-rw-r--r--src/tools/miri/src/shims/extern_static.rs79
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs3
-rw-r--r--src/tools/miri/src/shims/mod.rs42
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs11
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/foreign_items.rs28
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs89
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs15
-rw-r--r--src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs1
-rw-r--r--src/tools/tidy/src/error_codes.rs34
-rw-r--r--tests/debuginfo/msvc-pretty-enums.rs8
-rw-r--r--tests/debuginfo/numeric-types.rs46
-rw-r--r--tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff4
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs166
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr268
-rw-r--r--tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs2
-rw-r--r--tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr2
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.rs8
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.stderr73
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.rs8
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.stderr75
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime-err.rs25
-rw-r--r--tests/ui/inline-const/const-match-pat-lifetime-err.stderr28
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.rs2
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.stderr19
-rw-r--r--tests/ui/inline-const/pat-unsafe.rs1
-rw-r--r--tests/ui/inline-const/pat-unsafe.stderr20
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.stderr2
-rw-r--r--tests/ui/lint/clashing-extern-fn.rs2
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr6
-rw-r--r--tests/ui/lint/invalid_value.stderr16
-rw-r--r--tests/ui/lint/lint-ctypes-enum.stderr6
-rw-r--r--tests/ui/mismatched_types/non_zero_assigned_something.stderr8
-rw-r--r--tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr2
-rw-r--r--tests/ui/parser/issues/issue-24197.rs2
-rw-r--r--tests/ui/parser/issues/issue-24197.stderr6
-rw-r--r--tests/ui/parser/issues/issue-24375.rs2
-rw-r--r--tests/ui/parser/issues/issue-24375.stderr6
-rw-r--r--tests/ui/parser/pat-lt-bracket-5.rs4
-rw-r--r--tests/ui/parser/pat-lt-bracket-5.stderr15
-rw-r--r--tests/ui/parser/pat-lt-bracket-6.rs3
-rw-r--r--tests/ui/parser/pat-lt-bracket-6.stderr30
-rw-r--r--tests/ui/parser/pat-ranges-3.rs6
-rw-r--r--tests/ui/parser/pat-ranges-3.stderr14
-rw-r--r--tests/ui/parser/pat-ranges-4.rs6
-rw-r--r--tests/ui/parser/pat-ranges-4.stderr8
-rw-r--r--tests/ui/parser/pat-recover-exprs.rs28
-rw-r--r--tests/ui/parser/pat-recover-exprs.stderr76
-rw-r--r--tests/ui/parser/pat-recover-methodcalls.rs37
-rw-r--r--tests/ui/parser/pat-recover-methodcalls.stderr35
-rw-r--r--tests/ui/parser/pat-recover-ranges.rs16
-rw-r--r--tests/ui/parser/pat-recover-ranges.stderr84
-rw-r--r--tests/ui/parser/pat-recover-wildcards.rs61
-rw-r--r--tests/ui/parser/pat-recover-wildcards.stderr77
-rw-r--r--tests/ui/print_type_sizes/niche-filling.stdout16
-rw-r--r--tests/ui/traits/issue-77982.stderr2
-rw-r--r--tests/ui/try-trait/bad-interconversion.stderr2
-rw-r--r--triagebot.toml2
199 files changed, 3392 insertions, 2115 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index caf97abf78d..853f43e15e3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,6 +28,7 @@ name: CI
       - "**"
 permissions:
   contents: read
+  packages: write
 defaults:
   run:
     shell: bash
@@ -42,6 +43,7 @@ jobs:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
+      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
       CACHE_DOMAIN: ci-caches.rust-lang.org
@@ -172,6 +174,7 @@ jobs:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
+      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       DEPLOY_BUCKET: rust-lang-ci2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
@@ -554,6 +557,7 @@ jobs:
       CI_JOB_NAME: "${{ matrix.name }}"
       CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
       HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
+      DOCKER_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
       SCCACHE_BUCKET: rust-lang-ci-sccache2
       DEPLOY_BUCKET: rust-lang-ci2
       TOOLSTATE_REPO: "https://github.com/rust-lang-nursery/rust-toolstate"
diff --git a/Cargo.lock b/Cargo.lock
index 454ec90b9af..cab14a7a202 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1268,7 +1268,6 @@ name = "error_index_generator"
 version = "0.0.0"
 dependencies = [
  "mdbook",
- "rustc_error_codes",
 ]
 
 [[package]]
@@ -3701,7 +3700,6 @@ dependencies = [
  "rustc_codegen_ssa",
  "rustc_const_eval",
  "rustc_data_structures",
- "rustc_error_codes",
  "rustc_errors",
  "rustc_expand",
  "rustc_feature",
@@ -3774,9 +3772,11 @@ dependencies = [
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_data_structures",
+ "rustc_error_codes",
  "rustc_error_messages",
  "rustc_fluent_macro",
  "rustc_hir",
+ "rustc_index",
  "rustc_lint_defs",
  "rustc_macros",
  "rustc_serialize",
@@ -4342,7 +4342,6 @@ dependencies = [
 name = "rustc_pattern_analysis"
 version = "0.0.0"
 dependencies = [
- "derivative",
  "rustc-hash",
  "rustc_apfloat",
  "rustc_arena",
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index 4843d36372d..51bb8a96fad 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -1,9 +1,9 @@
-use rustc_errors::DiagnosticArgFromDisplay;
+use rustc_errors::{codes::*, DiagnosticArgFromDisplay};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_generic_type_with_parentheses, code = "E0214")]
+#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
 pub struct GenericTypeWithParentheses {
     #[primary_span]
     #[label]
@@ -22,7 +22,7 @@ pub struct UseAngleBrackets {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_lowering_invalid_abi, code = "E0703")]
+#[diag(ast_lowering_invalid_abi, code = E0703)]
 #[note]
 pub struct InvalidAbi {
     #[primary_span]
@@ -89,7 +89,7 @@ pub enum AssocTyParenthesesSub {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_lowering_misplaced_impl_trait, code = "E0562")]
+#[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
 #[note]
 pub struct MisplacedImplTrait<'a> {
     #[primary_span]
@@ -114,7 +114,7 @@ pub struct UnderscoreExprLhsAssign {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_base_expression_double_dot, code = "E0797")]
+#[diag(ast_lowering_base_expression_double_dot, code = E0797)]
 pub struct BaseExpressionDoubleDot {
     #[primary_span]
     #[suggestion(code = "/* expr */", applicability = "has-placeholders", style = "verbose")]
@@ -122,7 +122,7 @@ pub struct BaseExpressionDoubleDot {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = "E0728")]
+#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
 pub struct AwaitOnlyInAsyncFnAndBlocks {
     #[primary_span]
     #[label]
@@ -132,14 +132,14 @@ pub struct AwaitOnlyInAsyncFnAndBlocks {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_coroutine_too_many_parameters, code = "E0628")]
+#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
 pub struct CoroutineTooManyParameters {
     #[primary_span]
     pub fn_decl_span: Span,
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_closure_cannot_be_static, code = "E0697")]
+#[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
 pub struct ClosureCannotBeStatic {
     #[primary_span]
     pub fn_decl_span: Span,
@@ -154,14 +154,14 @@ pub struct FunctionalRecordUpdateDestructuringAssignment {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_async_coroutines_not_supported, code = "E0727")]
+#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
 pub struct AsyncCoroutinesNotSupported {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_inline_asm_unsupported_target, code = "E0472")]
+#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
 pub struct InlineAsmUnsupportedTarget {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index e2b8e64b115..5f54a0ddf8c 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1,7 +1,7 @@
 //! Errors emitted by ast_passes.
 
 use rustc_ast::ParamKindOrd;
-use rustc_errors::{AddToDiagnostic, Applicability};
+use rustc_errors::{codes::*, AddToDiagnostic, Applicability};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
@@ -23,7 +23,7 @@ pub struct InvalidLabel {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_visibility_not_permitted, code = "E0449")]
+#[diag(ast_passes_visibility_not_permitted, code = E0449)]
 pub struct VisibilityNotPermitted {
     #[primary_span]
     pub span: Span,
@@ -44,7 +44,7 @@ pub enum VisibilityNotPermittedNote {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_trait_fn_const, code = "E0379")]
+#[diag(ast_passes_trait_fn_const, code = E0379)]
 pub struct TraitFnConst {
     #[primary_span]
     #[label]
@@ -302,14 +302,14 @@ pub struct ItemUnderscore<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_nomangle_ascii, code = "E0754")]
+#[diag(ast_passes_nomangle_ascii, code = E0754)]
 pub struct NoMangleAscii {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_module_nonascii, code = "E0754")]
+#[diag(ast_passes_module_nonascii, code = E0754)]
 #[help]
 pub struct ModuleNonAscii {
     #[primary_span]
@@ -318,7 +318,7 @@ pub struct ModuleNonAscii {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_auto_generic, code = "E0567")]
+#[diag(ast_passes_auto_generic, code = E0567)]
 pub struct AutoTraitGeneric {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
@@ -328,7 +328,7 @@ pub struct AutoTraitGeneric {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_auto_super_lifetime, code = "E0568")]
+#[diag(ast_passes_auto_super_lifetime, code = E0568)]
 pub struct AutoTraitBounds {
     #[primary_span]
     #[suggestion(code = "", applicability = "machine-applicable")]
@@ -338,7 +338,7 @@ pub struct AutoTraitBounds {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_auto_items, code = "E0380")]
+#[diag(ast_passes_auto_items, code = E0380)]
 pub struct AutoTraitItems {
     #[primary_span]
     pub spans: Vec<Span>,
@@ -384,28 +384,28 @@ impl AddToDiagnostic for EmptyLabelManySpans {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_fn_pointer, code = "E0561")]
+#[diag(ast_passes_pattern_in_fn_pointer, code = E0561)]
 pub struct PatternFnPointer {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_trait_object_single_bound, code = "E0226")]
+#[diag(ast_passes_trait_object_single_bound, code = E0226)]
 pub struct TraitObjectBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_impl_trait_path, code = "E0667")]
+#[diag(ast_passes_impl_trait_path, code = E0667)]
 pub struct ImplTraitPath {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_nested_impl_trait, code = "E0666")]
+#[diag(ast_passes_nested_impl_trait, code = E0666)]
 pub struct NestedImplTrait {
     #[primary_span]
     pub span: Span,
@@ -443,7 +443,7 @@ pub struct ObsoleteAuto {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_unsafe_negative_impl, code = "E0198")]
+#[diag(ast_passes_unsafe_negative_impl, code = E0198)]
 pub struct UnsafeNegativeImpl {
     #[primary_span]
     pub span: Span,
@@ -468,7 +468,7 @@ pub struct InherentImplCannot<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_inherent_cannot_be, code = "E0197")]
+#[diag(ast_passes_inherent_cannot_be, code = E0197)]
 pub struct InherentImplCannotUnsafe<'a> {
     #[primary_span]
     pub span: Span,
@@ -536,7 +536,7 @@ pub struct GenericDefaultTrailing {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_nested_lifetimes, code = "E0316")]
+#[diag(ast_passes_nested_lifetimes, code = E0316)]
 pub struct NestedLifetimes {
     #[primary_span]
     pub span: Span,
@@ -655,7 +655,7 @@ pub struct ConstAndCVariadic {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_foreign, code = "E0130")]
+#[diag(ast_passes_pattern_in_foreign, code = E0130)]
 pub struct PatternInForeign {
     #[primary_span]
     #[label]
@@ -663,7 +663,7 @@ pub struct PatternInForeign {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_pattern_in_bodiless, code = "E0642")]
+#[diag(ast_passes_pattern_in_bodiless, code = E0642)]
 pub struct PatternInBodiless {
     #[primary_span]
     #[label]
@@ -711,14 +711,14 @@ pub struct AssociatedSuggestion2 {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_stability_outside_std, code = "E0734")]
+#[diag(ast_passes_stability_outside_std, code = E0734)]
 pub struct StabilityOutsideStd {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_feature_on_non_nightly, code = "E0554")]
+#[diag(ast_passes_feature_on_non_nightly, code = E0554)]
 pub struct FeatureOnNonNightly {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs
index 315a00c8d2f..79370602842 100644
--- a/compiler/rustc_attr/src/session_diagnostics.rs
+++ b/compiler/rustc_attr/src/session_diagnostics.rs
@@ -2,8 +2,7 @@ use std::num::IntErrorKind;
 
 use rustc_ast as ast;
 use rustc_errors::{
-    error_code, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
-    Level,
+    codes::*, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
@@ -12,14 +11,14 @@ use crate::fluent_generated as fluent;
 use crate::UnsupportedLiteralReason;
 
 #[derive(Diagnostic)]
-#[diag(attr_expected_one_cfg_pattern, code = "E0536")]
+#[diag(attr_expected_one_cfg_pattern, code = E0536)]
 pub(crate) struct ExpectedOneCfgPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_predicate, code = "E0537")]
+#[diag(attr_invalid_predicate, code = E0537)]
 pub(crate) struct InvalidPredicate {
     #[primary_span]
     pub span: Span,
@@ -28,7 +27,7 @@ pub(crate) struct InvalidPredicate {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_multiple_item, code = "E0538")]
+#[diag(attr_multiple_item, code = E0538)]
 pub(crate) struct MultipleItem {
     #[primary_span]
     pub span: Span,
@@ -37,7 +36,7 @@ pub(crate) struct MultipleItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_meta_item, code = "E0539")]
+#[diag(attr_incorrect_meta_item, code = E0539)]
 pub(crate) struct IncorrectMetaItem {
     #[primary_span]
     pub span: Span,
@@ -56,7 +55,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> {
         let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
         DiagnosticBuilder::new(dcx, level, fluent::attr_unknown_meta_item)
             .with_span(self.span)
-            .with_code(error_code!(E0541))
+            .with_code(E0541)
             .with_arg("item", self.item)
             .with_arg("expected", expected.join(", "))
             .with_span_label(self.span, fluent::attr_label)
@@ -64,28 +63,28 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnknownMetaItem<'_> {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_since, code = "E0542")]
+#[diag(attr_missing_since, code = E0542)]
 pub(crate) struct MissingSince {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_note, code = "E0543")]
+#[diag(attr_missing_note, code = E0543)]
 pub(crate) struct MissingNote {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_multiple_stability_levels, code = "E0544")]
+#[diag(attr_multiple_stability_levels, code = E0544)]
 pub(crate) struct MultipleStabilityLevels {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_issue_string, code = "E0545")]
+#[diag(attr_invalid_issue_string, code = E0545)]
 pub(crate) struct InvalidIssueString {
     #[primary_span]
     pub span: Span,
@@ -143,21 +142,21 @@ impl InvalidIssueStringCause {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_feature, code = "E0546")]
+#[diag(attr_missing_feature, code = E0546)]
 pub(crate) struct MissingFeature {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_non_ident_feature, code = "E0546")]
+#[diag(attr_non_ident_feature, code = E0546)]
 pub(crate) struct NonIdentFeature {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_missing_issue, code = "E0547")]
+#[diag(attr_missing_issue, code = E0547)]
 pub(crate) struct MissingIssue {
     #[primary_span]
     pub span: Span,
@@ -166,14 +165,14 @@ pub(crate) struct MissingIssue {
 // FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
 // It is more similar to `IncorrectReprFormatGeneric`.
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")]
+#[diag(attr_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)]
 pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_hint_no_paren, code = "E0552")]
+#[diag(attr_invalid_repr_hint_no_paren, code = E0552)]
 pub(crate) struct InvalidReprHintNoParen {
     #[primary_span]
     pub span: Span,
@@ -182,7 +181,7 @@ pub(crate) struct InvalidReprHintNoParen {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_hint_no_value, code = "E0552")]
+#[diag(attr_invalid_repr_hint_no_value, code = E0552)]
 pub(crate) struct InvalidReprHintNoValue {
     #[primary_span]
     pub span: Span,
@@ -215,7 +214,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnsupportedLiteral {
             },
         );
         diag.span(self.span);
-        diag.code(error_code!(E0565));
+        diag.code(E0565);
         if self.is_bytestr {
             diag.span_suggestion(
                 self.start_point_span,
@@ -229,7 +228,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for UnsupportedLiteral {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_align_need_arg, code = "E0589")]
+#[diag(attr_invalid_repr_align_need_arg, code = E0589)]
 pub(crate) struct InvalidReprAlignNeedArg {
     #[primary_span]
     #[suggestion(code = "align(...)", applicability = "has-placeholders")]
@@ -237,7 +236,7 @@ pub(crate) struct InvalidReprAlignNeedArg {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_invalid_repr_generic, code = "E0589")]
+#[diag(attr_invalid_repr_generic, code = E0589)]
 pub(crate) struct InvalidReprGeneric<'a> {
     #[primary_span]
     pub span: Span,
@@ -247,14 +246,14 @@ pub(crate) struct InvalidReprGeneric<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_repr_format_align_one_arg, code = "E0693")]
+#[diag(attr_incorrect_repr_format_align_one_arg, code = E0693)]
 pub(crate) struct IncorrectReprFormatAlignOneArg {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_incorrect_repr_format_generic, code = "E0693")]
+#[diag(attr_incorrect_repr_format_generic, code = E0693)]
 pub(crate) struct IncorrectReprFormatGeneric<'a> {
     #[primary_span]
     pub span: Span,
@@ -305,14 +304,14 @@ impl<'a> IncorrectReprFormatGenericCause<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_rustc_promotable_pairing, code = "E0717")]
+#[diag(attr_rustc_promotable_pairing, code = E0717)]
 pub(crate) struct RustcPromotablePairing {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(attr_rustc_allowed_unstable_pairing, code = "E0789")]
+#[diag(attr_rustc_allowed_unstable_pairing, code = E0789)]
 pub(crate) struct RustcAllowedUnstablePairing {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 351976cdaea..8a275a83630 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{struct_span_code_err, DiagCtxt, DiagnosticBuilder};
+use rustc_errors::{codes::*, struct_span_code_err, DiagCtxt, DiagnosticBuilder};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::Span;
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index da67862a48d..2e83072b8d1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -3,7 +3,9 @@
 use either::Either;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index e321b92603d..1685624f247 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -1,4 +1,4 @@
-use rustc_errors::MultiSpan;
+use rustc_errors::{codes::*, MultiSpan};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{GenericArg, Ty};
 use rustc_span::Span;
@@ -6,7 +6,7 @@ use rustc_span::Span;
 use crate::diagnostics::RegionName;
 
 #[derive(Diagnostic)]
-#[diag(borrowck_move_unsized, code = "E0161")]
+#[diag(borrowck_move_unsized, code = E0161)]
 pub(crate) struct MoveUnsized<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
@@ -281,7 +281,7 @@ pub(crate) enum CaptureVarCause {
 }
 
 #[derive(Diagnostic)]
-#[diag(borrowck_cannot_move_when_borrowed, code = "E0505")]
+#[diag(borrowck_cannot_move_when_borrowed, code = E0505)]
 pub(crate) struct MoveBorrow<'a> {
     pub place: &'a str,
     pub borrow_place: &'a str,
@@ -294,7 +294,7 @@ pub(crate) struct MoveBorrow<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(borrowck_opaque_type_non_generic_param, code = "E0792")]
+#[diag(borrowck_opaque_type_non_generic_param, code = E0792)]
 pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> {
     pub ty: GenericArg<'tcx>,
     pub kind: &'a str,
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index cf28e62177f..488dfc64cf6 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1099,10 +1099,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn check_user_type_annotations(&mut self) {
         debug!(?self.user_type_annotations);
+        let tcx = self.tcx();
         for user_annotation in self.user_type_annotations {
             let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
             let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
-            self.ascribe_user_type(inferred_ty, annotation, span);
+            if let ty::UserType::TypeOf(def, args) = annotation
+                && let DefKind::InlineConst = tcx.def_kind(def)
+            {
+                self.check_inline_const(inferred_ty, def.expect_local(), args, span);
+            } else {
+                self.ascribe_user_type(inferred_ty, annotation, span);
+            }
         }
     }
 
@@ -1195,6 +1202,36 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         Ok(())
     }
 
+    fn check_inline_const(
+        &mut self,
+        inferred_ty: Ty<'tcx>,
+        def_id: LocalDefId,
+        args: UserArgs<'tcx>,
+        span: Span,
+    ) {
+        assert!(args.user_self_ty.is_none());
+        let tcx = self.tcx();
+        let const_ty = tcx.type_of(def_id).instantiate(tcx, args.args);
+        if let Err(terr) =
+            self.eq_types(const_ty, inferred_ty, Locations::All(span), ConstraintCategory::Boring)
+        {
+            span_bug!(
+                span,
+                "bad inline const pattern: ({:?} = {:?}) {:?}",
+                const_ty,
+                inferred_ty,
+                terr
+            );
+        }
+        let args = self.infcx.resolve_vars_if_possible(args.args);
+        let predicates = self.prove_closure_bounds(tcx, def_id, args, Locations::All(span));
+        self.normalize_and_prove_instantiated_predicates(
+            def_id.to_def_id(),
+            predicates,
+            Locations::All(span),
+        );
+    }
+
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
@@ -1851,7 +1888,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     let def_id = uv.def;
                     if tcx.def_kind(def_id) == DefKind::InlineConst {
                         let def_id = def_id.expect_local();
-                        let predicates = self.prove_closure_bounds(tcx, def_id, uv.args, location);
+                        let predicates = self.prove_closure_bounds(
+                            tcx,
+                            def_id,
+                            uv.args,
+                            location.to_locations(),
+                        );
                         self.normalize_and_prove_instantiated_predicates(
                             def_id.to_def_id(),
                             predicates,
@@ -2654,9 +2696,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             // desugaring. A closure gets desugared to a struct, and
             // these extra requirements are basically like where
             // clauses on the struct.
-            AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => {
-                (def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
-            }
+            AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => (
+                def_id,
+                self.prove_closure_bounds(
+                    tcx,
+                    def_id.expect_local(),
+                    args,
+                    location.to_locations(),
+                ),
+            ),
 
             AggregateKind::Array(_) | AggregateKind::Tuple => {
                 (CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
@@ -2675,7 +2723,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         tcx: TyCtxt<'tcx>,
         def_id: LocalDefId,
         args: GenericArgsRef<'tcx>,
-        location: Location,
+        locations: Locations,
     ) -> ty::InstantiatedPredicates<'tcx> {
         if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements {
             constraint_conversion::ConstraintConversion::new(
@@ -2684,7 +2732,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 self.region_bound_pairs,
                 self.implicit_region_bound,
                 self.param_env,
-                location.to_locations(),
+                locations,
                 DUMMY_SP,                   // irrelevant; will be overridden.
                 ConstraintCategory::Boring, // same as above.
                 self.borrowck_context.constraints,
@@ -2710,7 +2758,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         if let Err(_) = self.eq_args(
             typeck_root_args,
             parent_args,
-            location.to_locations(),
+            locations,
             ConstraintCategory::BoringNoLocation,
         ) {
             span_mirbug!(
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index d6dfd0efaf9..eadb48ddd36 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -1,6 +1,6 @@
 use rustc_errors::{
-    AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
-    MultiSpan, SingleLabelManySpans,
+    codes::*, AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
+    Level, MultiSpan, SingleLabelManySpans,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
@@ -269,7 +269,7 @@ pub(crate) struct ConcatIdentsIdentArgs {
 }
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_bad_derive_target, code = "E0774")]
+#[diag(builtin_macros_bad_derive_target, code = E0774)]
 pub(crate) struct BadDeriveTarget {
     #[primary_span]
     #[label]
@@ -283,7 +283,7 @@ pub(crate) struct BadDeriveTarget {
 pub(crate) struct TestsNotSupport {}
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_unexpected_lit, code = "E0777")]
+#[diag(builtin_macros_unexpected_lit, code = E0777)]
 pub(crate) struct BadDeriveLit {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 5d497d4a188..b13d566b40b 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::Emitter;
 use rustc_errors::{translation::Translate, DiagCtxt, FatalError, Level};
-use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, Style};
+use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, ErrCode, Style};
 use rustc_fs_util::link_or_copy;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_incremental::{
@@ -1000,7 +1000,7 @@ type DiagnosticArgName<'source> = Cow<'source, str>;
 struct Diagnostic {
     msgs: Vec<(DiagnosticMessage, Style)>,
     args: FxHashMap<DiagnosticArgName<'static>, rustc_errors::DiagnosticArgValue<'static>>,
-    code: Option<String>,
+    code: Option<ErrCode>,
     lvl: Level,
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index cca239a43b3..47b1b080119 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -1,6 +1,6 @@
 use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index f90e1906caf..ef291ead190 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -4,7 +4,7 @@ use crate::assert_module_sources::CguReuse;
 use crate::back::command::Command;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
+    codes::*, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
     IntoDiagnosticArg, Level,
 };
 use rustc_macros::Diagnostic;
@@ -612,7 +612,7 @@ pub struct UnknownAtomicOperation;
 
 #[derive(Diagnostic)]
 pub enum InvalidMonomorphization<'tcx> {
-    #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = E0511)]
     BasicIntegerType {
         #[primary_span]
         span: Span,
@@ -620,7 +620,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = E0511)]
     BasicFloatType {
         #[primary_span]
         span: Span,
@@ -628,14 +628,14 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = E0511)]
     FloatToIntUnchecked {
         #[primary_span]
         span: Span,
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = E0511)]
     FloatingPointVector {
         #[primary_span]
         span: Span,
@@ -644,7 +644,7 @@ pub enum InvalidMonomorphization<'tcx> {
         in_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = E0511)]
     FloatingPointType {
         #[primary_span]
         span: Span,
@@ -652,14 +652,14 @@ pub enum InvalidMonomorphization<'tcx> {
         in_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = E0511)]
     UnrecognizedIntrinsic {
         #[primary_span]
         span: Span,
         name: Symbol,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = E0511)]
     SimdArgument {
         #[primary_span]
         span: Span,
@@ -667,7 +667,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = E0511)]
     SimdInput {
         #[primary_span]
         span: Span,
@@ -675,7 +675,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = E0511)]
     SimdFirst {
         #[primary_span]
         span: Span,
@@ -683,7 +683,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = E0511)]
     SimdSecond {
         #[primary_span]
         span: Span,
@@ -691,7 +691,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = E0511)]
     SimdThird {
         #[primary_span]
         span: Span,
@@ -699,7 +699,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = E0511)]
     SimdReturn {
         #[primary_span]
         span: Span,
@@ -707,7 +707,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = E0511)]
     InvalidBitmask {
         #[primary_span]
         span: Span,
@@ -717,7 +717,7 @@ pub enum InvalidMonomorphization<'tcx> {
         expected_bytes: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = E0511)]
     ReturnLengthInputType {
         #[primary_span]
         span: Span,
@@ -728,7 +728,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = E0511)]
     SecondArgumentLength {
         #[primary_span]
         span: Span,
@@ -739,7 +739,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = E0511)]
     ThirdArgumentLength {
         #[primary_span]
         span: Span,
@@ -750,7 +750,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = E0511)]
     ReturnIntegerType {
         #[primary_span]
         span: Span,
@@ -759,7 +759,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = E0511)]
     SimdShuffle {
         #[primary_span]
         span: Span,
@@ -767,7 +767,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_length, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_length, code = E0511)]
     ReturnLength {
         #[primary_span]
         span: Span,
@@ -777,7 +777,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_element, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_element, code = E0511)]
     ReturnElement {
         #[primary_span]
         span: Span,
@@ -788,7 +788,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = E0511)]
     ShuffleIndexNotConstant {
         #[primary_span]
         span: Span,
@@ -796,7 +796,7 @@ pub enum InvalidMonomorphization<'tcx> {
         arg_idx: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = E0511)]
     ShuffleIndexOutOfBounds {
         #[primary_span]
         span: Span,
@@ -805,7 +805,7 @@ pub enum InvalidMonomorphization<'tcx> {
         total_len: u128,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = E0511)]
     InsertedType {
         #[primary_span]
         span: Span,
@@ -815,7 +815,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_return_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_return_type, code = E0511)]
     ReturnType {
         #[primary_span]
         span: Span,
@@ -825,7 +825,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = E0511)]
     ExpectedReturnType {
         #[primary_span]
         span: Span,
@@ -834,7 +834,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = E0511)]
     MismatchedLengths {
         #[primary_span]
         span: Span,
@@ -843,7 +843,7 @@ pub enum InvalidMonomorphization<'tcx> {
         v_len: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = E0511)]
     MaskType {
         #[primary_span]
         span: Span,
@@ -851,7 +851,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = E0511)]
     VectorArgument {
         #[primary_span]
         span: Span,
@@ -860,7 +860,7 @@ pub enum InvalidMonomorphization<'tcx> {
         in_elem: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = E0511)]
     CannotReturn {
         #[primary_span]
         span: Span,
@@ -870,7 +870,7 @@ pub enum InvalidMonomorphization<'tcx> {
         expected_bytes: u64,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = E0511)]
     ExpectedElementType {
         #[primary_span]
         span: Span,
@@ -882,7 +882,7 @@ pub enum InvalidMonomorphization<'tcx> {
         mutability: ExpectedPointerMutability,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = E0511)]
     ThirdArgElementType {
         #[primary_span]
         span: Span,
@@ -891,7 +891,7 @@ pub enum InvalidMonomorphization<'tcx> {
         third_arg: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = E0511)]
     UnsupportedSymbolOfSize {
         #[primary_span]
         span: Span,
@@ -903,7 +903,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = E0511)]
     UnsupportedSymbol {
         #[primary_span]
         span: Span,
@@ -914,7 +914,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ret_ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = E0511)]
     CastFatPointer {
         #[primary_span]
         span: Span,
@@ -922,7 +922,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = E0511)]
     ExpectedPointer {
         #[primary_span]
         span: Span,
@@ -930,7 +930,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = E0511)]
     ExpectedUsize {
         #[primary_span]
         span: Span,
@@ -938,7 +938,7 @@ pub enum InvalidMonomorphization<'tcx> {
         ty: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = E0511)]
     UnsupportedCast {
         #[primary_span]
         span: Span,
@@ -949,7 +949,7 @@ pub enum InvalidMonomorphization<'tcx> {
         out_elem: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = E0511)]
     UnsupportedOperation {
         #[primary_span]
         span: Span,
@@ -958,7 +958,7 @@ pub enum InvalidMonomorphization<'tcx> {
         in_elem: Ty<'tcx>,
     },
 
-    #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = "E0511")]
+    #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = E0511)]
     ExpectedVectorElementType {
         #[primary_span]
         span: Span,
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 064d97a49d7..9e27c19e94c 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -1,8 +1,8 @@
 use std::borrow::Cow;
 
 use rustc_errors::{
-    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee,
-    IntoDiagnostic, Level,
+    codes::*, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage,
+    EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_hir::ConstContext;
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -55,14 +55,14 @@ pub(crate) struct UnstableInStable {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_thread_local_access, code = "E0625")]
+#[diag(const_eval_thread_local_access, code = E0625)]
 pub(crate) struct NonConstOpErr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_static_access, code = "E0013")]
+#[diag(const_eval_static_access, code = E0013)]
 #[help]
 pub(crate) struct StaticAccessErr {
     #[primary_span]
@@ -98,7 +98,7 @@ pub(crate) struct PanicNonStrErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_mut_deref, code = "E0658")]
+#[diag(const_eval_mut_deref, code = E0658)]
 pub(crate) struct MutDerefErr {
     #[primary_span]
     pub span: Span,
@@ -106,7 +106,7 @@ pub(crate) struct MutDerefErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_transient_mut_borrow, code = "E0658")]
+#[diag(const_eval_transient_mut_borrow, code = E0658)]
 pub(crate) struct TransientMutBorrowErr {
     #[primary_span]
     pub span: Span,
@@ -114,7 +114,7 @@ pub(crate) struct TransientMutBorrowErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_transient_mut_raw, code = "E0658")]
+#[diag(const_eval_transient_mut_raw, code = E0658)]
 pub(crate) struct TransientMutRawErr {
     #[primary_span]
     pub span: Span,
@@ -146,7 +146,7 @@ pub(crate) struct UnstableConstFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_mutable_refs, code = "E0764")]
+#[diag(const_eval_unallowed_mutable_refs, code = E0764)]
 pub(crate) struct UnallowedMutableRefs {
     #[primary_span]
     pub span: Span,
@@ -156,7 +156,7 @@ pub(crate) struct UnallowedMutableRefs {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_mutable_raw, code = "E0764")]
+#[diag(const_eval_unallowed_mutable_raw, code = E0764)]
 pub(crate) struct UnallowedMutableRaw {
     #[primary_span]
     pub span: Span,
@@ -165,7 +165,7 @@ pub(crate) struct UnallowedMutableRaw {
     pub teach: Option<()>,
 }
 #[derive(Diagnostic)]
-#[diag(const_eval_non_const_fmt_macro_call, code = "E0015")]
+#[diag(const_eval_non_const_fmt_macro_call, code = E0015)]
 pub(crate) struct NonConstFmtMacroCall {
     #[primary_span]
     pub span: Span,
@@ -173,7 +173,7 @@ pub(crate) struct NonConstFmtMacroCall {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_non_const_fn_call, code = "E0015")]
+#[diag(const_eval_non_const_fn_call, code = E0015)]
 pub(crate) struct NonConstFnCall {
     #[primary_span]
     pub span: Span,
@@ -190,7 +190,7 @@ pub(crate) struct UnallowedOpInConstContext {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_heap_allocations, code = "E0010")]
+#[diag(const_eval_unallowed_heap_allocations, code = E0010)]
 pub(crate) struct UnallowedHeapAllocations {
     #[primary_span]
     #[label]
@@ -201,7 +201,7 @@ pub(crate) struct UnallowedHeapAllocations {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_unallowed_inline_asm, code = "E0015")]
+#[diag(const_eval_unallowed_inline_asm, code = E0015)]
 pub(crate) struct UnallowedInlineAsm {
     #[primary_span]
     pub span: Span,
@@ -209,7 +209,7 @@ pub(crate) struct UnallowedInlineAsm {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_interior_mutable_data_refer, code = "E0492")]
+#[diag(const_eval_interior_mutable_data_refer, code = E0492)]
 pub(crate) struct InteriorMutableDataRefer {
     #[primary_span]
     #[label]
@@ -274,7 +274,7 @@ pub struct RawBytesNote {
 // FIXME(fee1-dead) do not use stringly typed `ConstContext`
 
 #[derive(Diagnostic)]
-#[diag(const_eval_match_eq_non_const, code = "E0015")]
+#[diag(const_eval_match_eq_non_const, code = E0015)]
 #[note]
 pub struct NonConstMatchEq<'tcx> {
     #[primary_span]
@@ -284,7 +284,7 @@ pub struct NonConstMatchEq<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_for_loop_into_iter_non_const, code = "E0015")]
+#[diag(const_eval_for_loop_into_iter_non_const, code = E0015)]
 pub struct NonConstForLoopIntoIter<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -293,7 +293,7 @@ pub struct NonConstForLoopIntoIter<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_question_branch_non_const, code = "E0015")]
+#[diag(const_eval_question_branch_non_const, code = E0015)]
 pub struct NonConstQuestionBranch<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -302,7 +302,7 @@ pub struct NonConstQuestionBranch<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_question_from_residual_non_const, code = "E0015")]
+#[diag(const_eval_question_from_residual_non_const, code = E0015)]
 pub struct NonConstQuestionFromResidual<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -311,7 +311,7 @@ pub struct NonConstQuestionFromResidual<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_try_block_from_output_non_const, code = "E0015")]
+#[diag(const_eval_try_block_from_output_non_const, code = E0015)]
 pub struct NonConstTryBlockFromOutput<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -320,7 +320,7 @@ pub struct NonConstTryBlockFromOutput<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_await_non_const, code = "E0015")]
+#[diag(const_eval_await_non_const, code = E0015)]
 pub struct NonConstAwait<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -329,7 +329,7 @@ pub struct NonConstAwait<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_closure_non_const, code = "E0015")]
+#[diag(const_eval_closure_non_const, code = E0015)]
 pub struct NonConstClosure {
     #[primary_span]
     pub span: Span,
@@ -362,7 +362,7 @@ pub struct ConsiderDereferencing {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_operator_non_const, code = "E0015")]
+#[diag(const_eval_operator_non_const, code = E0015)]
 pub struct NonConstOperator {
     #[primary_span]
     pub span: Span,
@@ -372,7 +372,7 @@ pub struct NonConstOperator {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_deref_coercion_non_const, code = "E0015")]
+#[diag(const_eval_deref_coercion_non_const, code = E0015)]
 #[note]
 pub struct NonConstDerefCoercion<'tcx> {
     #[primary_span]
@@ -385,7 +385,7 @@ pub struct NonConstDerefCoercion<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_live_drop, code = "E0493")]
+#[diag(const_eval_live_drop, code = E0493)]
 pub struct LiveDrop<'tcx> {
     #[primary_span]
     #[label]
@@ -397,7 +397,7 @@ pub struct LiveDrop<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_error, code = "E0080")]
+#[diag(const_eval_error, code = E0080)]
 pub struct ConstEvalError {
     #[primary_span]
     pub span: Span,
@@ -423,7 +423,7 @@ pub struct NullaryIntrinsicError {
 }
 
 #[derive(Diagnostic)]
-#[diag(const_eval_undefined_behavior, code = "E0080")]
+#[diag(const_eval_undefined_behavior, code = E0080)]
 pub struct UndefinedBehavior {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 39bc2b960e9..fb705d91977 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -2,7 +2,7 @@
 
 use hir::def_id::LocalDefId;
 use hir::{ConstContext, LangItem};
-use rustc_errors::{error_code, DiagnosticBuilder};
+use rustc_errors::{codes::*, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
@@ -372,7 +372,7 @@ impl<'tcx> NonConstOp<'tcx> for HeapAllocation {
         ccx.dcx().create_err(errors::UnallowedHeapAllocations {
             span,
             kind: ccx.const_kind(),
-            teach: ccx.tcx.sess.teach(&error_code!(E0010)).then_some(()),
+            teach: ccx.tcx.sess.teach(E0010).then_some(()),
         })
     }
 }
@@ -434,14 +434,14 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
                 span,
                 opt_help: Some(()),
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0492).then_some(()),
             })
         } else {
             ccx.dcx().create_err(errors::InteriorMutableDataRefer {
                 span,
                 opt_help: None,
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0492)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0492).then_some(()),
             })
         }
     }
@@ -469,12 +469,12 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
             hir::BorrowKind::Raw => ccx.tcx.dcx().create_err(errors::UnallowedMutableRaw {
                 span,
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0764).then_some(()),
             }),
             hir::BorrowKind::Ref => ccx.dcx().create_err(errors::UnallowedMutableRefs {
                 span,
                 kind: ccx.const_kind(),
-                teach: ccx.tcx.sess.teach(&error_code!(E0764)).then_some(()),
+                teach: ccx.tcx.sess.teach(E0764).then_some(()),
             }),
         }
     }
@@ -588,7 +588,7 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
         ccx.dcx().create_err(errors::StaticAccessErr {
             span,
             kind: ccx.const_kind(),
-            teach: ccx.tcx.sess.teach(&error_code!(E0013)).then_some(()),
+            teach: ccx.tcx.sess.teach(E0013).then_some(()),
         })
     }
 }
diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml
index 97a7dfef3b3..bfdd871455c 100644
--- a/compiler/rustc_driver_impl/Cargo.toml
+++ b/compiler/rustc_driver_impl/Cargo.toml
@@ -15,7 +15,6 @@ rustc_builtin_macros = { path = "../rustc_builtin_macros" }
 rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
 rustc_const_eval = { path = "../rustc_const_eval" }
 rustc_data_structures = { path = "../rustc_data_structures" }
-rustc_error_codes = { path = "../rustc_error_codes" }
 rustc_errors = { path = "../rustc_errors" }
 rustc_expand = { path = "../rustc_expand" }
 rustc_feature = { path = "../rustc_feature" }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 09e627fa7a3..5903c43ae98 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -23,9 +23,8 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults};
 use rustc_data_structures::profiling::{
     get_resident_set_size, print_time_passes_entry, TimePassesFormat,
 };
-use rustc_errors::registry::{InvalidErrorCode, Registry};
-use rustc_errors::{markdown, ColorConfig};
-use rustc_errors::{DiagCtxt, ErrorGuaranteed, PResult};
+use rustc_errors::registry::Registry;
+use rustc_errors::{markdown, ColorConfig, DiagCtxt, ErrCode, ErrorGuaranteed, PResult};
 use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
@@ -207,7 +206,7 @@ impl Callbacks for TimePassesCallbacks {
 }
 
 pub fn diagnostics_registry() -> Registry {
-    Registry::new(rustc_error_codes::DIAGNOSTICS)
+    Registry::new(rustc_errors::codes::DIAGNOSTICS)
 }
 
 /// This is the primary entry point for rustc.
@@ -535,37 +534,36 @@ pub enum Compilation {
 }
 
 fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) {
+    // Allow "E0123" or "0123" form.
     let upper_cased_code = code.to_ascii_uppercase();
-    let normalised =
-        if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") };
-    match registry.try_find_description(&normalised) {
-        Ok(description) => {
-            let mut is_in_code_block = false;
-            let mut text = String::new();
-            // Slice off the leading newline and print.
-            for line in description.lines() {
-                let indent_level =
-                    line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len());
-                let dedented_line = &line[indent_level..];
-                if dedented_line.starts_with("```") {
-                    is_in_code_block = !is_in_code_block;
-                    text.push_str(&line[..(indent_level + 3)]);
-                } else if is_in_code_block && dedented_line.starts_with("# ") {
-                    continue;
-                } else {
-                    text.push_str(line);
-                }
-                text.push('\n');
-            }
-            if io::stdout().is_terminal() {
-                show_md_content_with_pager(&text, color);
+    let start = if upper_cased_code.starts_with('E') { 1 } else { 0 };
+    if let Ok(code) = upper_cased_code[start..].parse::<u32>()
+        && let Ok(description) = registry.try_find_description(ErrCode::from_u32(code))
+    {
+        let mut is_in_code_block = false;
+        let mut text = String::new();
+        // Slice off the leading newline and print.
+        for line in description.lines() {
+            let indent_level =
+                line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len());
+            let dedented_line = &line[indent_level..];
+            if dedented_line.starts_with("```") {
+                is_in_code_block = !is_in_code_block;
+                text.push_str(&line[..(indent_level + 3)]);
+            } else if is_in_code_block && dedented_line.starts_with("# ") {
+                continue;
             } else {
-                safe_print!("{text}");
+                text.push_str(line);
             }
+            text.push('\n');
         }
-        Err(InvalidErrorCode) => {
-            early_dcx.early_fatal(format!("{code} is not a valid error code"));
+        if io::stdout().is_terminal() {
+            show_md_content_with_pager(&text, color);
+        } else {
+            safe_print!("{text}");
         }
+    } else {
+        early_dcx.early_fatal(format!("{code} is not a valid error code"));
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
deleted file mode 100644
index 9cd9ed54d41..00000000000
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ /dev/null
@@ -1,658 +0,0 @@
-// Error messages for EXXXX errors. Each message should start and end with a
-// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
-// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-//
-// /!\ IMPORTANT /!\
-//
-// Error messages' format must follow the RFC 1567 available here:
-// https://rust-lang.github.io/rfcs/1567-long-error-codes-explanation-normalization.html
-
-register_diagnostics! {
-E0001: include_str!("./error_codes/E0001.md"),
-E0002: include_str!("./error_codes/E0002.md"),
-E0004: include_str!("./error_codes/E0004.md"),
-E0005: include_str!("./error_codes/E0005.md"),
-E0007: include_str!("./error_codes/E0007.md"),
-E0009: include_str!("./error_codes/E0009.md"),
-E0010: include_str!("./error_codes/E0010.md"),
-E0013: include_str!("./error_codes/E0013.md"),
-E0014: include_str!("./error_codes/E0014.md"),
-E0015: include_str!("./error_codes/E0015.md"),
-E0023: include_str!("./error_codes/E0023.md"),
-E0025: include_str!("./error_codes/E0025.md"),
-E0026: include_str!("./error_codes/E0026.md"),
-E0027: include_str!("./error_codes/E0027.md"),
-E0029: include_str!("./error_codes/E0029.md"),
-E0030: include_str!("./error_codes/E0030.md"),
-E0033: include_str!("./error_codes/E0033.md"),
-E0034: include_str!("./error_codes/E0034.md"),
-E0038: include_str!("./error_codes/E0038.md"),
-E0040: include_str!("./error_codes/E0040.md"),
-E0044: include_str!("./error_codes/E0044.md"),
-E0045: include_str!("./error_codes/E0045.md"),
-E0046: include_str!("./error_codes/E0046.md"),
-E0049: include_str!("./error_codes/E0049.md"),
-E0050: include_str!("./error_codes/E0050.md"),
-E0053: include_str!("./error_codes/E0053.md"),
-E0054: include_str!("./error_codes/E0054.md"),
-E0055: include_str!("./error_codes/E0055.md"),
-E0057: include_str!("./error_codes/E0057.md"),
-E0059: include_str!("./error_codes/E0059.md"),
-E0060: include_str!("./error_codes/E0060.md"),
-E0061: include_str!("./error_codes/E0061.md"),
-E0062: include_str!("./error_codes/E0062.md"),
-E0063: include_str!("./error_codes/E0063.md"),
-E0067: include_str!("./error_codes/E0067.md"),
-E0069: include_str!("./error_codes/E0069.md"),
-E0070: include_str!("./error_codes/E0070.md"),
-E0071: include_str!("./error_codes/E0071.md"),
-E0072: include_str!("./error_codes/E0072.md"),
-E0073: include_str!("./error_codes/E0073.md"),
-E0074: include_str!("./error_codes/E0074.md"),
-E0075: include_str!("./error_codes/E0075.md"),
-E0076: include_str!("./error_codes/E0076.md"),
-E0077: include_str!("./error_codes/E0077.md"),
-E0080: include_str!("./error_codes/E0080.md"),
-E0081: include_str!("./error_codes/E0081.md"),
-E0084: include_str!("./error_codes/E0084.md"),
-E0087: include_str!("./error_codes/E0087.md"),
-E0088: include_str!("./error_codes/E0088.md"),
-E0089: include_str!("./error_codes/E0089.md"),
-E0090: include_str!("./error_codes/E0090.md"),
-E0091: include_str!("./error_codes/E0091.md"),
-E0092: include_str!("./error_codes/E0092.md"),
-E0093: include_str!("./error_codes/E0093.md"),
-E0094: include_str!("./error_codes/E0094.md"),
-E0106: include_str!("./error_codes/E0106.md"),
-E0107: include_str!("./error_codes/E0107.md"),
-E0109: include_str!("./error_codes/E0109.md"),
-E0110: include_str!("./error_codes/E0110.md"),
-E0116: include_str!("./error_codes/E0116.md"),
-E0117: include_str!("./error_codes/E0117.md"),
-E0118: include_str!("./error_codes/E0118.md"),
-E0119: include_str!("./error_codes/E0119.md"),
-E0120: include_str!("./error_codes/E0120.md"),
-E0121: include_str!("./error_codes/E0121.md"),
-E0124: include_str!("./error_codes/E0124.md"),
-E0128: include_str!("./error_codes/E0128.md"),
-E0130: include_str!("./error_codes/E0130.md"),
-E0131: include_str!("./error_codes/E0131.md"),
-E0132: include_str!("./error_codes/E0132.md"),
-E0133: include_str!("./error_codes/E0133.md"),
-E0136: include_str!("./error_codes/E0136.md"),
-E0137: include_str!("./error_codes/E0137.md"),
-E0138: include_str!("./error_codes/E0138.md"),
-E0139: include_str!("./error_codes/E0139.md"),
-E0152: include_str!("./error_codes/E0152.md"),
-E0154: include_str!("./error_codes/E0154.md"),
-E0158: include_str!("./error_codes/E0158.md"),
-E0161: include_str!("./error_codes/E0161.md"),
-E0162: include_str!("./error_codes/E0162.md"),
-E0164: include_str!("./error_codes/E0164.md"),
-E0165: include_str!("./error_codes/E0165.md"),
-E0170: include_str!("./error_codes/E0170.md"),
-E0178: include_str!("./error_codes/E0178.md"),
-E0183: include_str!("./error_codes/E0183.md"),
-E0184: include_str!("./error_codes/E0184.md"),
-E0185: include_str!("./error_codes/E0185.md"),
-E0186: include_str!("./error_codes/E0186.md"),
-E0191: include_str!("./error_codes/E0191.md"),
-E0192: include_str!("./error_codes/E0192.md"),
-E0193: include_str!("./error_codes/E0193.md"),
-E0195: include_str!("./error_codes/E0195.md"),
-E0197: include_str!("./error_codes/E0197.md"),
-E0198: include_str!("./error_codes/E0198.md"),
-E0199: include_str!("./error_codes/E0199.md"),
-E0200: include_str!("./error_codes/E0200.md"),
-E0201: include_str!("./error_codes/E0201.md"),
-E0203: include_str!("./error_codes/E0203.md"),
-E0204: include_str!("./error_codes/E0204.md"),
-E0205: include_str!("./error_codes/E0205.md"),
-E0206: include_str!("./error_codes/E0206.md"),
-E0207: include_str!("./error_codes/E0207.md"),
-E0208: include_str!("./error_codes/E0208.md"),
-E0210: include_str!("./error_codes/E0210.md"),
-E0211: include_str!("./error_codes/E0211.md"),
-E0212: include_str!("./error_codes/E0212.md"),
-E0214: include_str!("./error_codes/E0214.md"),
-E0220: include_str!("./error_codes/E0220.md"),
-E0221: include_str!("./error_codes/E0221.md"),
-E0222: include_str!("./error_codes/E0222.md"),
-E0223: include_str!("./error_codes/E0223.md"),
-E0224: include_str!("./error_codes/E0224.md"),
-E0225: include_str!("./error_codes/E0225.md"),
-E0226: include_str!("./error_codes/E0226.md"),
-E0227: include_str!("./error_codes/E0227.md"),
-E0228: include_str!("./error_codes/E0228.md"),
-E0229: include_str!("./error_codes/E0229.md"),
-E0230: include_str!("./error_codes/E0230.md"),
-E0231: include_str!("./error_codes/E0231.md"),
-E0232: include_str!("./error_codes/E0232.md"),
-E0243: include_str!("./error_codes/E0243.md"),
-E0244: include_str!("./error_codes/E0244.md"),
-E0251: include_str!("./error_codes/E0251.md"),
-E0252: include_str!("./error_codes/E0252.md"),
-E0253: include_str!("./error_codes/E0253.md"),
-E0254: include_str!("./error_codes/E0254.md"),
-E0255: include_str!("./error_codes/E0255.md"),
-E0256: include_str!("./error_codes/E0256.md"),
-E0259: include_str!("./error_codes/E0259.md"),
-E0260: include_str!("./error_codes/E0260.md"),
-E0261: include_str!("./error_codes/E0261.md"),
-E0262: include_str!("./error_codes/E0262.md"),
-E0263: include_str!("./error_codes/E0263.md"),
-E0264: include_str!("./error_codes/E0264.md"),
-E0267: include_str!("./error_codes/E0267.md"),
-E0268: include_str!("./error_codes/E0268.md"),
-E0271: include_str!("./error_codes/E0271.md"),
-E0275: include_str!("./error_codes/E0275.md"),
-E0276: include_str!("./error_codes/E0276.md"),
-E0277: include_str!("./error_codes/E0277.md"),
-E0281: include_str!("./error_codes/E0281.md"),
-E0282: include_str!("./error_codes/E0282.md"),
-E0283: include_str!("./error_codes/E0283.md"),
-E0284: include_str!("./error_codes/E0284.md"),
-E0297: include_str!("./error_codes/E0297.md"),
-E0301: include_str!("./error_codes/E0301.md"),
-E0302: include_str!("./error_codes/E0302.md"),
-E0303: include_str!("./error_codes/E0303.md"),
-E0307: include_str!("./error_codes/E0307.md"),
-E0308: include_str!("./error_codes/E0308.md"),
-E0309: include_str!("./error_codes/E0309.md"),
-E0310: include_str!("./error_codes/E0310.md"),
-E0311: include_str!("./error_codes/E0311.md"),
-E0312: include_str!("./error_codes/E0312.md"),
-E0316: include_str!("./error_codes/E0316.md"),
-E0317: include_str!("./error_codes/E0317.md"),
-E0320: include_str!("./error_codes/E0320.md"),
-E0321: include_str!("./error_codes/E0321.md"),
-E0322: include_str!("./error_codes/E0322.md"),
-E0323: include_str!("./error_codes/E0323.md"),
-E0324: include_str!("./error_codes/E0324.md"),
-E0325: include_str!("./error_codes/E0325.md"),
-E0326: include_str!("./error_codes/E0326.md"),
-E0328: include_str!("./error_codes/E0328.md"),
-E0329: include_str!("./error_codes/E0329.md"),
-E0364: include_str!("./error_codes/E0364.md"),
-E0365: include_str!("./error_codes/E0365.md"),
-E0366: include_str!("./error_codes/E0366.md"),
-E0367: include_str!("./error_codes/E0367.md"),
-E0368: include_str!("./error_codes/E0368.md"),
-E0369: include_str!("./error_codes/E0369.md"),
-E0370: include_str!("./error_codes/E0370.md"),
-E0371: include_str!("./error_codes/E0371.md"),
-E0373: include_str!("./error_codes/E0373.md"),
-E0374: include_str!("./error_codes/E0374.md"),
-E0375: include_str!("./error_codes/E0375.md"),
-E0376: include_str!("./error_codes/E0376.md"),
-E0377: include_str!("./error_codes/E0377.md"),
-E0378: include_str!("./error_codes/E0378.md"),
-E0379: include_str!("./error_codes/E0379.md"),
-E0380: include_str!("./error_codes/E0380.md"),
-E0381: include_str!("./error_codes/E0381.md"),
-E0382: include_str!("./error_codes/E0382.md"),
-E0383: include_str!("./error_codes/E0383.md"),
-E0384: include_str!("./error_codes/E0384.md"),
-E0386: include_str!("./error_codes/E0386.md"),
-E0387: include_str!("./error_codes/E0387.md"),
-E0388: include_str!("./error_codes/E0388.md"),
-E0389: include_str!("./error_codes/E0389.md"),
-E0390: include_str!("./error_codes/E0390.md"),
-E0391: include_str!("./error_codes/E0391.md"),
-E0392: include_str!("./error_codes/E0392.md"),
-E0393: include_str!("./error_codes/E0393.md"),
-E0398: include_str!("./error_codes/E0398.md"),
-E0399: include_str!("./error_codes/E0399.md"),
-E0401: include_str!("./error_codes/E0401.md"),
-E0403: include_str!("./error_codes/E0403.md"),
-E0404: include_str!("./error_codes/E0404.md"),
-E0405: include_str!("./error_codes/E0405.md"),
-E0407: include_str!("./error_codes/E0407.md"),
-E0408: include_str!("./error_codes/E0408.md"),
-E0409: include_str!("./error_codes/E0409.md"),
-E0411: include_str!("./error_codes/E0411.md"),
-E0412: include_str!("./error_codes/E0412.md"),
-E0415: include_str!("./error_codes/E0415.md"),
-E0416: include_str!("./error_codes/E0416.md"),
-E0422: include_str!("./error_codes/E0422.md"),
-E0423: include_str!("./error_codes/E0423.md"),
-E0424: include_str!("./error_codes/E0424.md"),
-E0425: include_str!("./error_codes/E0425.md"),
-E0426: include_str!("./error_codes/E0426.md"),
-E0428: include_str!("./error_codes/E0428.md"),
-E0429: include_str!("./error_codes/E0429.md"),
-E0430: include_str!("./error_codes/E0430.md"),
-E0431: include_str!("./error_codes/E0431.md"),
-E0432: include_str!("./error_codes/E0432.md"),
-E0433: include_str!("./error_codes/E0433.md"),
-E0434: include_str!("./error_codes/E0434.md"),
-E0435: include_str!("./error_codes/E0435.md"),
-E0436: include_str!("./error_codes/E0436.md"),
-E0437: include_str!("./error_codes/E0437.md"),
-E0438: include_str!("./error_codes/E0438.md"),
-E0439: include_str!("./error_codes/E0439.md"),
-E0445: include_str!("./error_codes/E0445.md"),
-E0446: include_str!("./error_codes/E0446.md"),
-E0447: include_str!("./error_codes/E0447.md"),
-E0448: include_str!("./error_codes/E0448.md"),
-E0449: include_str!("./error_codes/E0449.md"),
-E0451: include_str!("./error_codes/E0451.md"),
-E0452: include_str!("./error_codes/E0452.md"),
-E0453: include_str!("./error_codes/E0453.md"),
-E0454: include_str!("./error_codes/E0454.md"),
-E0455: include_str!("./error_codes/E0455.md"),
-E0457: include_str!("./error_codes/E0457.md"),
-E0458: include_str!("./error_codes/E0458.md"),
-E0459: include_str!("./error_codes/E0459.md"),
-E0460: include_str!("./error_codes/E0460.md"),
-E0461: include_str!("./error_codes/E0461.md"),
-E0462: include_str!("./error_codes/E0462.md"),
-E0463: include_str!("./error_codes/E0463.md"),
-E0464: include_str!("./error_codes/E0464.md"),
-E0466: include_str!("./error_codes/E0466.md"),
-E0468: include_str!("./error_codes/E0468.md"),
-E0469: include_str!("./error_codes/E0469.md"),
-E0472: include_str!("./error_codes/E0472.md"),
-E0476: include_str!("./error_codes/E0476.md"),
-E0477: include_str!("./error_codes/E0477.md"),
-E0478: include_str!("./error_codes/E0478.md"),
-E0482: include_str!("./error_codes/E0482.md"),
-E0491: include_str!("./error_codes/E0491.md"),
-E0492: include_str!("./error_codes/E0492.md"),
-E0493: include_str!("./error_codes/E0493.md"),
-E0495: include_str!("./error_codes/E0495.md"),
-E0496: include_str!("./error_codes/E0496.md"),
-E0497: include_str!("./error_codes/E0497.md"),
-E0498: include_str!("./error_codes/E0498.md"),
-E0499: include_str!("./error_codes/E0499.md"),
-E0500: include_str!("./error_codes/E0500.md"),
-E0501: include_str!("./error_codes/E0501.md"),
-E0502: include_str!("./error_codes/E0502.md"),
-E0503: include_str!("./error_codes/E0503.md"),
-E0504: include_str!("./error_codes/E0504.md"),
-E0505: include_str!("./error_codes/E0505.md"),
-E0506: include_str!("./error_codes/E0506.md"),
-E0507: include_str!("./error_codes/E0507.md"),
-E0508: include_str!("./error_codes/E0508.md"),
-E0509: include_str!("./error_codes/E0509.md"),
-E0510: include_str!("./error_codes/E0510.md"),
-E0511: include_str!("./error_codes/E0511.md"),
-E0512: include_str!("./error_codes/E0512.md"),
-E0514: include_str!("./error_codes/E0514.md"),
-E0515: include_str!("./error_codes/E0515.md"),
-E0516: include_str!("./error_codes/E0516.md"),
-E0517: include_str!("./error_codes/E0517.md"),
-E0518: include_str!("./error_codes/E0518.md"),
-E0519: include_str!("./error_codes/E0519.md"),
-E0520: include_str!("./error_codes/E0520.md"),
-E0521: include_str!("./error_codes/E0521.md"),
-E0522: include_str!("./error_codes/E0522.md"),
-E0523: include_str!("./error_codes/E0523.md"),
-E0524: include_str!("./error_codes/E0524.md"),
-E0525: include_str!("./error_codes/E0525.md"),
-E0527: include_str!("./error_codes/E0527.md"),
-E0528: include_str!("./error_codes/E0528.md"),
-E0529: include_str!("./error_codes/E0529.md"),
-E0530: include_str!("./error_codes/E0530.md"),
-E0531: include_str!("./error_codes/E0531.md"),
-E0532: include_str!("./error_codes/E0532.md"),
-E0533: include_str!("./error_codes/E0533.md"),
-E0534: include_str!("./error_codes/E0534.md"),
-E0535: include_str!("./error_codes/E0535.md"),
-E0536: include_str!("./error_codes/E0536.md"),
-E0537: include_str!("./error_codes/E0537.md"),
-E0538: include_str!("./error_codes/E0538.md"),
-E0539: include_str!("./error_codes/E0539.md"),
-E0541: include_str!("./error_codes/E0541.md"),
-E0542: include_str!("./error_codes/E0542.md"),
-E0543: include_str!("./error_codes/E0543.md"),
-E0544: include_str!("./error_codes/E0544.md"),
-E0545: include_str!("./error_codes/E0545.md"),
-E0546: include_str!("./error_codes/E0546.md"),
-E0547: include_str!("./error_codes/E0547.md"),
-E0549: include_str!("./error_codes/E0549.md"),
-E0550: include_str!("./error_codes/E0550.md"),
-E0551: include_str!("./error_codes/E0551.md"),
-E0552: include_str!("./error_codes/E0552.md"),
-E0554: include_str!("./error_codes/E0554.md"),
-E0556: include_str!("./error_codes/E0556.md"),
-E0557: include_str!("./error_codes/E0557.md"),
-E0559: include_str!("./error_codes/E0559.md"),
-E0560: include_str!("./error_codes/E0560.md"),
-E0561: include_str!("./error_codes/E0561.md"),
-E0562: include_str!("./error_codes/E0562.md"),
-E0565: include_str!("./error_codes/E0565.md"),
-E0566: include_str!("./error_codes/E0566.md"),
-E0567: include_str!("./error_codes/E0567.md"),
-E0568: include_str!("./error_codes/E0568.md"),
-E0569: include_str!("./error_codes/E0569.md"),
-E0570: include_str!("./error_codes/E0570.md"),
-E0571: include_str!("./error_codes/E0571.md"),
-E0572: include_str!("./error_codes/E0572.md"),
-E0573: include_str!("./error_codes/E0573.md"),
-E0574: include_str!("./error_codes/E0574.md"),
-E0575: include_str!("./error_codes/E0575.md"),
-E0576: include_str!("./error_codes/E0576.md"),
-E0577: include_str!("./error_codes/E0577.md"),
-E0578: include_str!("./error_codes/E0578.md"),
-E0579: include_str!("./error_codes/E0579.md"),
-E0580: include_str!("./error_codes/E0580.md"),
-E0581: include_str!("./error_codes/E0581.md"),
-E0582: include_str!("./error_codes/E0582.md"),
-E0583: include_str!("./error_codes/E0583.md"),
-E0584: include_str!("./error_codes/E0584.md"),
-E0585: include_str!("./error_codes/E0585.md"),
-E0586: include_str!("./error_codes/E0586.md"),
-E0587: include_str!("./error_codes/E0587.md"),
-E0588: include_str!("./error_codes/E0588.md"),
-E0589: include_str!("./error_codes/E0589.md"),
-E0590: include_str!("./error_codes/E0590.md"),
-E0591: include_str!("./error_codes/E0591.md"),
-E0592: include_str!("./error_codes/E0592.md"),
-E0593: include_str!("./error_codes/E0593.md"),
-E0594: include_str!("./error_codes/E0594.md"),
-E0595: include_str!("./error_codes/E0595.md"),
-E0596: include_str!("./error_codes/E0596.md"),
-E0597: include_str!("./error_codes/E0597.md"),
-E0599: include_str!("./error_codes/E0599.md"),
-E0600: include_str!("./error_codes/E0600.md"),
-E0601: include_str!("./error_codes/E0601.md"),
-E0602: include_str!("./error_codes/E0602.md"),
-E0603: include_str!("./error_codes/E0603.md"),
-E0604: include_str!("./error_codes/E0604.md"),
-E0605: include_str!("./error_codes/E0605.md"),
-E0606: include_str!("./error_codes/E0606.md"),
-E0607: include_str!("./error_codes/E0607.md"),
-E0608: include_str!("./error_codes/E0608.md"),
-E0609: include_str!("./error_codes/E0609.md"),
-E0610: include_str!("./error_codes/E0610.md"),
-E0614: include_str!("./error_codes/E0614.md"),
-E0615: include_str!("./error_codes/E0615.md"),
-E0616: include_str!("./error_codes/E0616.md"),
-E0617: include_str!("./error_codes/E0617.md"),
-E0618: include_str!("./error_codes/E0618.md"),
-E0619: include_str!("./error_codes/E0619.md"),
-E0620: include_str!("./error_codes/E0620.md"),
-E0621: include_str!("./error_codes/E0621.md"),
-E0622: include_str!("./error_codes/E0622.md"),
-E0623: include_str!("./error_codes/E0623.md"),
-E0624: include_str!("./error_codes/E0624.md"),
-E0625: include_str!("./error_codes/E0625.md"),
-E0626: include_str!("./error_codes/E0626.md"),
-E0627: include_str!("./error_codes/E0627.md"),
-E0628: include_str!("./error_codes/E0628.md"),
-E0631: include_str!("./error_codes/E0631.md"),
-E0632: include_str!("./error_codes/E0632.md"),
-E0633: include_str!("./error_codes/E0633.md"),
-E0634: include_str!("./error_codes/E0634.md"),
-E0635: include_str!("./error_codes/E0635.md"),
-E0636: include_str!("./error_codes/E0636.md"),
-E0637: include_str!("./error_codes/E0637.md"),
-E0638: include_str!("./error_codes/E0638.md"),
-E0639: include_str!("./error_codes/E0639.md"),
-E0640: include_str!("./error_codes/E0640.md"),
-E0641: include_str!("./error_codes/E0641.md"),
-E0642: include_str!("./error_codes/E0642.md"),
-E0643: include_str!("./error_codes/E0643.md"),
-E0644: include_str!("./error_codes/E0644.md"),
-E0646: include_str!("./error_codes/E0646.md"),
-E0647: include_str!("./error_codes/E0647.md"),
-E0648: include_str!("./error_codes/E0648.md"),
-E0657: include_str!("./error_codes/E0657.md"),
-E0658: include_str!("./error_codes/E0658.md"),
-E0659: include_str!("./error_codes/E0659.md"),
-E0660: include_str!("./error_codes/E0660.md"),
-E0661: include_str!("./error_codes/E0661.md"),
-E0662: include_str!("./error_codes/E0662.md"),
-E0663: include_str!("./error_codes/E0663.md"),
-E0664: include_str!("./error_codes/E0664.md"),
-E0665: include_str!("./error_codes/E0665.md"),
-E0666: include_str!("./error_codes/E0666.md"),
-E0667: include_str!("./error_codes/E0667.md"),
-E0668: include_str!("./error_codes/E0668.md"),
-E0669: include_str!("./error_codes/E0669.md"),
-E0670: include_str!("./error_codes/E0670.md"),
-E0671: include_str!("./error_codes/E0671.md"),
-E0687: include_str!("./error_codes/E0687.md"),
-E0688: include_str!("./error_codes/E0688.md"),
-E0689: include_str!("./error_codes/E0689.md"),
-E0690: include_str!("./error_codes/E0690.md"),
-E0691: include_str!("./error_codes/E0691.md"),
-E0692: include_str!("./error_codes/E0692.md"),
-E0693: include_str!("./error_codes/E0693.md"),
-E0695: include_str!("./error_codes/E0695.md"),
-E0696: include_str!("./error_codes/E0696.md"),
-E0697: include_str!("./error_codes/E0697.md"),
-E0698: include_str!("./error_codes/E0698.md"),
-E0699: include_str!("./error_codes/E0699.md"),
-E0700: include_str!("./error_codes/E0700.md"),
-E0701: include_str!("./error_codes/E0701.md"),
-E0703: include_str!("./error_codes/E0703.md"),
-E0704: include_str!("./error_codes/E0704.md"),
-E0705: include_str!("./error_codes/E0705.md"),
-E0706: include_str!("./error_codes/E0706.md"),
-E0708: include_str!("./error_codes/E0708.md"),
-E0710: include_str!("./error_codes/E0710.md"),
-E0712: include_str!("./error_codes/E0712.md"),
-E0713: include_str!("./error_codes/E0713.md"),
-E0714: include_str!("./error_codes/E0714.md"),
-E0715: include_str!("./error_codes/E0715.md"),
-E0716: include_str!("./error_codes/E0716.md"),
-E0711: include_str!("./error_codes/E0711.md"),
-E0717: include_str!("./error_codes/E0717.md"),
-E0718: include_str!("./error_codes/E0718.md"),
-E0719: include_str!("./error_codes/E0719.md"),
-E0720: include_str!("./error_codes/E0720.md"),
-E0722: include_str!("./error_codes/E0722.md"),
-E0724: include_str!("./error_codes/E0724.md"),
-E0725: include_str!("./error_codes/E0725.md"),
-E0726: include_str!("./error_codes/E0726.md"),
-E0727: include_str!("./error_codes/E0727.md"),
-E0728: include_str!("./error_codes/E0728.md"),
-E0729: include_str!("./error_codes/E0729.md"),
-E0730: include_str!("./error_codes/E0730.md"),
-E0731: include_str!("./error_codes/E0731.md"),
-E0732: include_str!("./error_codes/E0732.md"),
-E0733: include_str!("./error_codes/E0733.md"),
-E0734: include_str!("./error_codes/E0734.md"),
-E0735: include_str!("./error_codes/E0735.md"),
-E0736: include_str!("./error_codes/E0736.md"),
-E0737: include_str!("./error_codes/E0737.md"),
-E0739: include_str!("./error_codes/E0739.md"),
-E0740: include_str!("./error_codes/E0740.md"),
-E0741: include_str!("./error_codes/E0741.md"),
-E0742: include_str!("./error_codes/E0742.md"),
-E0743: include_str!("./error_codes/E0743.md"),
-E0744: include_str!("./error_codes/E0744.md"),
-E0745: include_str!("./error_codes/E0745.md"),
-E0746: include_str!("./error_codes/E0746.md"),
-E0747: include_str!("./error_codes/E0747.md"),
-E0748: include_str!("./error_codes/E0748.md"),
-E0749: include_str!("./error_codes/E0749.md"),
-E0750: include_str!("./error_codes/E0750.md"),
-E0751: include_str!("./error_codes/E0751.md"),
-E0752: include_str!("./error_codes/E0752.md"),
-E0753: include_str!("./error_codes/E0753.md"),
-E0754: include_str!("./error_codes/E0754.md"),
-E0755: include_str!("./error_codes/E0755.md"),
-E0756: include_str!("./error_codes/E0756.md"),
-E0757: include_str!("./error_codes/E0757.md"),
-E0758: include_str!("./error_codes/E0758.md"),
-E0759: include_str!("./error_codes/E0759.md"),
-E0760: include_str!("./error_codes/E0760.md"),
-E0761: include_str!("./error_codes/E0761.md"),
-E0762: include_str!("./error_codes/E0762.md"),
-E0763: include_str!("./error_codes/E0763.md"),
-E0764: include_str!("./error_codes/E0764.md"),
-E0765: include_str!("./error_codes/E0765.md"),
-E0766: include_str!("./error_codes/E0766.md"),
-E0767: include_str!("./error_codes/E0767.md"),
-E0768: include_str!("./error_codes/E0768.md"),
-E0769: include_str!("./error_codes/E0769.md"),
-E0770: include_str!("./error_codes/E0770.md"),
-E0771: include_str!("./error_codes/E0771.md"),
-E0772: include_str!("./error_codes/E0772.md"),
-E0773: include_str!("./error_codes/E0773.md"),
-E0774: include_str!("./error_codes/E0774.md"),
-E0775: include_str!("./error_codes/E0775.md"),
-E0776: include_str!("./error_codes/E0776.md"),
-E0777: include_str!("./error_codes/E0777.md"),
-E0778: include_str!("./error_codes/E0778.md"),
-E0779: include_str!("./error_codes/E0779.md"),
-E0780: include_str!("./error_codes/E0780.md"),
-E0781: include_str!("./error_codes/E0781.md"),
-E0782: include_str!("./error_codes/E0782.md"),
-E0783: include_str!("./error_codes/E0783.md"),
-E0784: include_str!("./error_codes/E0784.md"),
-E0785: include_str!("./error_codes/E0785.md"),
-E0786: include_str!("./error_codes/E0786.md"),
-E0787: include_str!("./error_codes/E0787.md"),
-E0788: include_str!("./error_codes/E0788.md"),
-E0789: include_str!("./error_codes/E0789.md"),
-E0790: include_str!("./error_codes/E0790.md"),
-E0791: include_str!("./error_codes/E0791.md"),
-E0792: include_str!("./error_codes/E0792.md"),
-E0793: include_str!("./error_codes/E0793.md"),
-E0794: include_str!("./error_codes/E0794.md"),
-E0795: include_str!("./error_codes/E0795.md"),
-E0796: include_str!("./error_codes/E0796.md"),
-E0797: include_str!("./error_codes/E0797.md"),
-}
-
-// Undocumented removed error codes. Note that many removed error codes are kept in the list above
-// and marked as no-longer emitted with a note in the markdown file (see E0001 for an example).
-//  E0006, // merged with E0005
-//  E0008, // cannot bind by-move into a pattern guard
-//  E0019, // merged into E0015
-//  E0035, // merged into E0087/E0089
-//  E0036, // merged into E0087/E0089
-//  E0068,
-//  E0085,
-//  E0086,
-//  E0101, // replaced with E0282
-//  E0102, // replaced with E0282
-//  E0103,
-//  E0104,
-//  E0122, // bounds in type aliases are ignored, turned into proper lint
-//  E0123,
-//  E0127,
-//  E0129,
-//  E0134,
-//  E0135,
-//  E0141,
-//  E0153, // unused error code
-//  E0157, // unused error code
-//  E0159, // use of trait `{}` as struct constructor
-//  E0163, // merged into E0071
-//  E0167,
-//  E0168,
-//  E0172, // non-trait found in a type sum, moved to resolve
-//  E0173, // manual implementations of unboxed closure traits are experimental
-//  E0174,
-//  E0182, // merged into E0229
-//  E0187, // cannot infer the kind of the closure
-//  E0188, // can not cast an immutable reference to a mutable pointer
-//  E0189, // deprecated: can only cast a boxed pointer to a boxed object
-//  E0190, // deprecated: can only cast a &-pointer to an &-object
-//  E0194, // merged into E0403
-//  E0196, // cannot determine a type for this closure
-//  E0209, // builtin traits can only be implemented on structs or enums
-//  E0213, // associated types are not accepted in this context
-//  E0215, // angle-bracket notation is not stable with `Fn`
-//  E0216, // parenthetical notation is only stable with `Fn`
-//  E0217, // ambiguous associated type, defined in multiple supertraits
-//  E0218, // no associated type defined
-//  E0219, // associated type defined in higher-ranked supertrait
-//  E0233,
-//  E0234,
-//  E0235, // structure constructor specifies a structure of type but
-//  E0236, // no lang item for range syntax
-//  E0237, // no lang item for range syntax
-//  E0238, // parenthesized parameters may only be used with a trait
-//  E0239, // `next` method of `Iterator` trait has unexpected type
-//  E0240,
-//  E0241,
-//  E0242,
-//  E0245, // not a trait
-//  E0246, // invalid recursive type
-//  E0247,
-//  E0248, // value used as a type, now reported earlier during resolution
-//         // as E0412
-//  E0249,
-//  E0257,
-//  E0258,
-//  E0272, // on_unimplemented #0
-//  E0273, // on_unimplemented #1
-//  E0274, // on_unimplemented #2
-//  E0278, // requirement is not satisfied
-//  E0279,
-//  E0280, // changed to ICE
-//  E0285, // overflow evaluation builtin bounds
-//  E0296, // replaced with a generic attribute input check
-//  E0298, // cannot compare constants
-//  E0299, // mismatched types between arms
-//  E0300, // unexpanded macro
-//  E0304, // expected signed integer constant
-//  E0305, // expected constant
-//  E0313, // removed: found unreachable
-//  E0314, // closure outlives stack frame
-//  E0315, // cannot invoke closure outside of its lifetime
-//  E0319, // trait impls for defaulted traits allowed just for structs/enums
-//  E0372, // coherence not object safe
-//  E0385, // {} in an aliasable location
-//  E0402, // cannot use an outer type parameter in this context
-//  E0406, // merged into 420
-//  E0410, // merged into 408
-//  E0413, // merged into 530
-//  E0414, // merged into 530
-//  E0417, // merged into 532
-//  E0418, // merged into 532
-//  E0419, // merged into 531
-//  E0420, // merged into 532
-//  E0421, // merged into 531
-//  E0427, // merged into 530
-//  E0445, // merged into 446 and type privacy lints
-//  E0456, // plugin `..` is not available for triple `..`
-//  E0465, // removed: merged with E0464
-//  E0467, // removed
-//  E0470, // removed
-//  E0471, // constant evaluation error (in pattern)
-//  E0473, // dereference of reference outside its lifetime
-//  E0474, // captured variable `..` does not outlive the enclosing closure
-//  E0475, // index of slice outside its lifetime
-//  E0479, // the type `..` (provided as the value of a type parameter) is...
-//  E0480, // lifetime of method receiver does not outlive the method call
-//  E0481, // lifetime of function argument does not outlive the function call
-//  E0483, // lifetime of operand does not outlive the operation
-//  E0484, // reference is not valid at the time of borrow
-//  E0485, // automatically reference is not valid at the time of borrow
-//  E0486, // type of expression contains references that are not valid during..
-//  E0487, // unsafe use of destructor: destructor might be called while...
-//  E0488, // lifetime of variable does not enclose its declaration
-//  E0489, // type/lifetime parameter not in scope here
-//  E0490, // removed: unreachable
-//  E0526, // shuffle indices are not constant
-//  E0540, // multiple rustc_deprecated attributes
-//  E0548, // replaced with a generic attribute input check
-//  E0553, // multiple rustc_const_unstable attributes
-//  E0555, // replaced with a generic attribute input check
-//  E0558, // replaced with a generic attribute input check
-//  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
-//  E0564, // only named lifetimes are allowed in `impl Trait`,
-//         // but `{}` was found in the type `{}`
-//  E0598, // lifetime of {} is too short to guarantee its contents can be...
-//  E0611, // merged into E0616
-//  E0612, // merged into E0609
-//  E0613, // Removed (merged with E0609)
-//  E0629, // missing 'feature' (rustc_const_unstable)
-//  E0630, // rustc_const_unstable attribute must be paired with stable/unstable
-//         // attribute
-//  E0645, // trait aliases not finished
-//  E0694, // an unknown tool name found in scoped attributes
-//  E0702, // replaced with a generic attribute input check
-//  E0707, // multiple elided lifetimes used in arguments of `async fn`
-//  E0709, // multiple different lifetimes used in arguments of `async fn`
-//  E0721, // `await` keyword
-//  E0723, // unstable feature in `const` context
-//  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
-//  E0744, // merged into E0728
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index dd281811636..5b2766618fc 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -1,19 +1,679 @@
+//! This library is used to gather all error codes into one place, to make
+//! their maintenance easier.
+
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![deny(rustdoc::invalid_codeblock_attributes)]
 #![deny(rustc::untranslatable_diagnostic)]
 #![deny(rustc::diagnostic_outside_of_impl)]
-//! This library is used to gather all error codes into one place,
-//! the goal being to make their maintenance easier.
 
-macro_rules! register_diagnostics {
-    ($($ecode:ident: $message:expr,)*) => (
-        pub static DIAGNOSTICS: &[(&str, &str)] = &[
-            $( (stringify!($ecode), $message), )*
-        ];
+// This higher-order macro defines the error codes that are in use. It is used
+// in the `rustc_errors` crate. Removed error codes are listed in the comment
+// below.
+//
+// /!\ IMPORTANT /!\
+//
+// Error code explanation are defined in `error_codes/EXXXX.md` files. They must follow the RFC
+// 1567 available here:
+// https://rust-lang.github.io/rfcs/1567-long-error-codes-explanation-normalization.html
+//
+// Also, the contents of this macro is checked by tidy (in `check_error_codes_docs`). If you change
+// the macro syntax you will need to change tidy as well.
+//
+// Both columns are necessary because it's not possible in Rust to create a new identifier such as
+// `E0123` from an integer literal such as `0123`, unfortunately.
+#[macro_export]
+macro_rules! error_codes {
+    ($macro:path) => (
+        $macro!(
+E0001: 0001,
+E0002: 0002,
+E0004: 0004,
+E0005: 0005,
+E0007: 0007,
+E0009: 0009,
+E0010: 0010,
+E0013: 0013,
+E0014: 0014,
+E0015: 0015,
+E0023: 0023,
+E0025: 0025,
+E0026: 0026,
+E0027: 0027,
+E0029: 0029,
+E0030: 0030,
+E0033: 0033,
+E0034: 0034,
+E0038: 0038,
+E0040: 0040,
+E0044: 0044,
+E0045: 0045,
+E0046: 0046,
+E0049: 0049,
+E0050: 0050,
+E0053: 0053,
+E0054: 0054,
+E0055: 0055,
+E0057: 0057,
+E0059: 0059,
+E0060: 0060,
+E0061: 0061,
+E0062: 0062,
+E0063: 0063,
+E0067: 0067,
+E0069: 0069,
+E0070: 0070,
+E0071: 0071,
+E0072: 0072,
+E0073: 0073,
+E0074: 0074,
+E0075: 0075,
+E0076: 0076,
+E0077: 0077,
+E0080: 0080,
+E0081: 0081,
+E0084: 0084,
+E0087: 0087,
+E0088: 0088,
+E0089: 0089,
+E0090: 0090,
+E0091: 0091,
+E0092: 0092,
+E0093: 0093,
+E0094: 0094,
+E0106: 0106,
+E0107: 0107,
+E0109: 0109,
+E0110: 0110,
+E0116: 0116,
+E0117: 0117,
+E0118: 0118,
+E0119: 0119,
+E0120: 0120,
+E0121: 0121,
+E0124: 0124,
+E0128: 0128,
+E0130: 0130,
+E0131: 0131,
+E0132: 0132,
+E0133: 0133,
+E0136: 0136,
+E0137: 0137,
+E0138: 0138,
+E0139: 0139,
+E0152: 0152,
+E0154: 0154,
+E0158: 0158,
+E0161: 0161,
+E0162: 0162,
+E0164: 0164,
+E0165: 0165,
+E0170: 0170,
+E0178: 0178,
+E0183: 0183,
+E0184: 0184,
+E0185: 0185,
+E0186: 0186,
+E0191: 0191,
+E0192: 0192,
+E0193: 0193,
+E0195: 0195,
+E0197: 0197,
+E0198: 0198,
+E0199: 0199,
+E0200: 0200,
+E0201: 0201,
+E0203: 0203,
+E0204: 0204,
+E0205: 0205,
+E0206: 0206,
+E0207: 0207,
+E0208: 0208,
+E0210: 0210,
+E0211: 0211,
+E0212: 0212,
+E0214: 0214,
+E0220: 0220,
+E0221: 0221,
+E0222: 0222,
+E0223: 0223,
+E0224: 0224,
+E0225: 0225,
+E0226: 0226,
+E0227: 0227,
+E0228: 0228,
+E0229: 0229,
+E0230: 0230,
+E0231: 0231,
+E0232: 0232,
+E0243: 0243,
+E0244: 0244,
+E0251: 0251,
+E0252: 0252,
+E0253: 0253,
+E0254: 0254,
+E0255: 0255,
+E0256: 0256,
+E0259: 0259,
+E0260: 0260,
+E0261: 0261,
+E0262: 0262,
+E0263: 0263,
+E0264: 0264,
+E0267: 0267,
+E0268: 0268,
+E0271: 0271,
+E0275: 0275,
+E0276: 0276,
+E0277: 0277,
+E0281: 0281,
+E0282: 0282,
+E0283: 0283,
+E0284: 0284,
+E0297: 0297,
+E0301: 0301,
+E0302: 0302,
+E0303: 0303,
+E0307: 0307,
+E0308: 0308,
+E0309: 0309,
+E0310: 0310,
+E0311: 0311,
+E0312: 0312,
+E0316: 0316,
+E0317: 0317,
+E0320: 0320,
+E0321: 0321,
+E0322: 0322,
+E0323: 0323,
+E0324: 0324,
+E0325: 0325,
+E0326: 0326,
+E0328: 0328,
+E0329: 0329,
+E0364: 0364,
+E0365: 0365,
+E0366: 0366,
+E0367: 0367,
+E0368: 0368,
+E0369: 0369,
+E0370: 0370,
+E0371: 0371,
+E0373: 0373,
+E0374: 0374,
+E0375: 0375,
+E0376: 0376,
+E0377: 0377,
+E0378: 0378,
+E0379: 0379,
+E0380: 0380,
+E0381: 0381,
+E0382: 0382,
+E0383: 0383,
+E0384: 0384,
+E0386: 0386,
+E0387: 0387,
+E0388: 0388,
+E0389: 0389,
+E0390: 0390,
+E0391: 0391,
+E0392: 0392,
+E0393: 0393,
+E0398: 0398,
+E0399: 0399,
+E0401: 0401,
+E0403: 0403,
+E0404: 0404,
+E0405: 0405,
+E0407: 0407,
+E0408: 0408,
+E0409: 0409,
+E0411: 0411,
+E0412: 0412,
+E0415: 0415,
+E0416: 0416,
+E0422: 0422,
+E0423: 0423,
+E0424: 0424,
+E0425: 0425,
+E0426: 0426,
+E0428: 0428,
+E0429: 0429,
+E0430: 0430,
+E0431: 0431,
+E0432: 0432,
+E0433: 0433,
+E0434: 0434,
+E0435: 0435,
+E0436: 0436,
+E0437: 0437,
+E0438: 0438,
+E0439: 0439,
+E0445: 0445,
+E0446: 0446,
+E0447: 0447,
+E0448: 0448,
+E0449: 0449,
+E0451: 0451,
+E0452: 0452,
+E0453: 0453,
+E0454: 0454,
+E0455: 0455,
+E0457: 0457,
+E0458: 0458,
+E0459: 0459,
+E0460: 0460,
+E0461: 0461,
+E0462: 0462,
+E0463: 0463,
+E0464: 0464,
+E0466: 0466,
+E0468: 0468,
+E0469: 0469,
+E0472: 0472,
+E0476: 0476,
+E0477: 0477,
+E0478: 0478,
+E0482: 0482,
+E0491: 0491,
+E0492: 0492,
+E0493: 0493,
+E0495: 0495,
+E0496: 0496,
+E0497: 0497,
+E0498: 0498,
+E0499: 0499,
+E0500: 0500,
+E0501: 0501,
+E0502: 0502,
+E0503: 0503,
+E0504: 0504,
+E0505: 0505,
+E0506: 0506,
+E0507: 0507,
+E0508: 0508,
+E0509: 0509,
+E0510: 0510,
+E0511: 0511,
+E0512: 0512,
+E0514: 0514,
+E0515: 0515,
+E0516: 0516,
+E0517: 0517,
+E0518: 0518,
+E0519: 0519,
+E0520: 0520,
+E0521: 0521,
+E0522: 0522,
+E0523: 0523,
+E0524: 0524,
+E0525: 0525,
+E0527: 0527,
+E0528: 0528,
+E0529: 0529,
+E0530: 0530,
+E0531: 0531,
+E0532: 0532,
+E0533: 0533,
+E0534: 0534,
+E0535: 0535,
+E0536: 0536,
+E0537: 0537,
+E0538: 0538,
+E0539: 0539,
+E0541: 0541,
+E0542: 0542,
+E0543: 0543,
+E0544: 0544,
+E0545: 0545,
+E0546: 0546,
+E0547: 0547,
+E0549: 0549,
+E0550: 0550,
+E0551: 0551,
+E0552: 0552,
+E0554: 0554,
+E0556: 0556,
+E0557: 0557,
+E0559: 0559,
+E0560: 0560,
+E0561: 0561,
+E0562: 0562,
+E0565: 0565,
+E0566: 0566,
+E0567: 0567,
+E0568: 0568,
+E0569: 0569,
+E0570: 0570,
+E0571: 0571,
+E0572: 0572,
+E0573: 0573,
+E0574: 0574,
+E0575: 0575,
+E0576: 0576,
+E0577: 0577,
+E0578: 0578,
+E0579: 0579,
+E0580: 0580,
+E0581: 0581,
+E0582: 0582,
+E0583: 0583,
+E0584: 0584,
+E0585: 0585,
+E0586: 0586,
+E0587: 0587,
+E0588: 0588,
+E0589: 0589,
+E0590: 0590,
+E0591: 0591,
+E0592: 0592,
+E0593: 0593,
+E0594: 0594,
+E0595: 0595,
+E0596: 0596,
+E0597: 0597,
+E0599: 0599,
+E0600: 0600,
+E0601: 0601,
+E0602: 0602,
+E0603: 0603,
+E0604: 0604,
+E0605: 0605,
+E0606: 0606,
+E0607: 0607,
+E0608: 0608,
+E0609: 0609,
+E0610: 0610,
+E0614: 0614,
+E0615: 0615,
+E0616: 0616,
+E0617: 0617,
+E0618: 0618,
+E0619: 0619,
+E0620: 0620,
+E0621: 0621,
+E0622: 0622,
+E0623: 0623,
+E0624: 0624,
+E0625: 0625,
+E0626: 0626,
+E0627: 0627,
+E0628: 0628,
+E0631: 0631,
+E0632: 0632,
+E0633: 0633,
+E0634: 0634,
+E0635: 0635,
+E0636: 0636,
+E0637: 0637,
+E0638: 0638,
+E0639: 0639,
+E0640: 0640,
+E0641: 0641,
+E0642: 0642,
+E0643: 0643,
+E0644: 0644,
+E0646: 0646,
+E0647: 0647,
+E0648: 0648,
+E0657: 0657,
+E0658: 0658,
+E0659: 0659,
+E0660: 0660,
+E0661: 0661,
+E0662: 0662,
+E0663: 0663,
+E0664: 0664,
+E0665: 0665,
+E0666: 0666,
+E0667: 0667,
+E0668: 0668,
+E0669: 0669,
+E0670: 0670,
+E0671: 0671,
+E0687: 0687,
+E0688: 0688,
+E0689: 0689,
+E0690: 0690,
+E0691: 0691,
+E0692: 0692,
+E0693: 0693,
+E0695: 0695,
+E0696: 0696,
+E0697: 0697,
+E0698: 0698,
+E0699: 0699,
+E0700: 0700,
+E0701: 0701,
+E0703: 0703,
+E0704: 0704,
+E0705: 0705,
+E0706: 0706,
+E0708: 0708,
+E0710: 0710,
+E0712: 0712,
+E0713: 0713,
+E0714: 0714,
+E0715: 0715,
+E0716: 0716,
+E0711: 0711,
+E0717: 0717,
+E0718: 0718,
+E0719: 0719,
+E0720: 0720,
+E0722: 0722,
+E0724: 0724,
+E0725: 0725,
+E0726: 0726,
+E0727: 0727,
+E0728: 0728,
+E0729: 0729,
+E0730: 0730,
+E0731: 0731,
+E0732: 0732,
+E0733: 0733,
+E0734: 0734,
+E0735: 0735,
+E0736: 0736,
+E0737: 0737,
+E0739: 0739,
+E0740: 0740,
+E0741: 0741,
+E0742: 0742,
+E0743: 0743,
+E0744: 0744,
+E0745: 0745,
+E0746: 0746,
+E0747: 0747,
+E0748: 0748,
+E0749: 0749,
+E0750: 0750,
+E0751: 0751,
+E0752: 0752,
+E0753: 0753,
+E0754: 0754,
+E0755: 0755,
+E0756: 0756,
+E0757: 0757,
+E0758: 0758,
+E0759: 0759,
+E0760: 0760,
+E0761: 0761,
+E0762: 0762,
+E0763: 0763,
+E0764: 0764,
+E0765: 0765,
+E0766: 0766,
+E0767: 0767,
+E0768: 0768,
+E0769: 0769,
+E0770: 0770,
+E0771: 0771,
+E0772: 0772,
+E0773: 0773,
+E0774: 0774,
+E0775: 0775,
+E0776: 0776,
+E0777: 0777,
+E0778: 0778,
+E0779: 0779,
+E0780: 0780,
+E0781: 0781,
+E0782: 0782,
+E0783: 0783,
+E0784: 0784,
+E0785: 0785,
+E0786: 0786,
+E0787: 0787,
+E0788: 0788,
+E0789: 0789,
+E0790: 0790,
+E0791: 0791,
+E0792: 0792,
+E0793: 0793,
+E0794: 0794,
+E0795: 0795,
+E0796: 0796,
+E0797: 0797,
+        );
     )
 }
 
-mod error_codes;
-pub use error_codes::DIAGNOSTICS;
+// Undocumented removed error codes. Note that many removed error codes are kept in the list above
+// and marked as no-longer emitted with a note in the markdown file (see E0001 for an example).
+//  E0006, // merged with E0005
+//  E0008, // cannot bind by-move into a pattern guard
+//  E0019, // merged into E0015
+//  E0035, // merged into E0087/E0089
+//  E0036, // merged into E0087/E0089
+//  E0068,
+//  E0085,
+//  E0086,
+//  E0101, // replaced with E0282
+//  E0102, // replaced with E0282
+//  E0103,
+//  E0104,
+//  E0122, // bounds in type aliases are ignored, turned into proper lint
+//  E0123,
+//  E0127,
+//  E0129,
+//  E0134,
+//  E0135,
+//  E0141,
+//  E0153, // unused error code
+//  E0157, // unused error code
+//  E0159, // use of trait `{}` as struct constructor
+//  E0163, // merged into E0071
+//  E0167,
+//  E0168,
+//  E0172, // non-trait found in a type sum, moved to resolve
+//  E0173, // manual implementations of unboxed closure traits are experimental
+//  E0174,
+//  E0182, // merged into E0229
+//  E0187, // cannot infer the kind of the closure
+//  E0188, // can not cast an immutable reference to a mutable pointer
+//  E0189, // deprecated: can only cast a boxed pointer to a boxed object
+//  E0190, // deprecated: can only cast a &-pointer to an &-object
+//  E0194, // merged into E0403
+//  E0196, // cannot determine a type for this closure
+//  E0209, // builtin traits can only be implemented on structs or enums
+//  E0213, // associated types are not accepted in this context
+//  E0215, // angle-bracket notation is not stable with `Fn`
+//  E0216, // parenthetical notation is only stable with `Fn`
+//  E0217, // ambiguous associated type, defined in multiple supertraits
+//  E0218, // no associated type defined
+//  E0219, // associated type defined in higher-ranked supertrait
+//  E0233,
+//  E0234,
+//  E0235, // structure constructor specifies a structure of type but
+//  E0236, // no lang item for range syntax
+//  E0237, // no lang item for range syntax
+//  E0238, // parenthesized parameters may only be used with a trait
+//  E0239, // `next` method of `Iterator` trait has unexpected type
+//  E0240,
+//  E0241,
+//  E0242,
+//  E0245, // not a trait
+//  E0246, // invalid recursive type
+//  E0247,
+//  E0248, // value used as a type, now reported earlier during resolution
+//         // as E0412
+//  E0249,
+//  E0257,
+//  E0258,
+//  E0272, // on_unimplemented #0
+//  E0273, // on_unimplemented #1
+//  E0274, // on_unimplemented #2
+//  E0278, // requirement is not satisfied
+//  E0279,
+//  E0280, // changed to ICE
+//  E0285, // overflow evaluation builtin bounds
+//  E0296, // replaced with a generic attribute input check
+//  E0298, // cannot compare constants
+//  E0299, // mismatched types between arms
+//  E0300, // unexpanded macro
+//  E0304, // expected signed integer constant
+//  E0305, // expected constant
+//  E0313, // removed: found unreachable
+//  E0314, // closure outlives stack frame
+//  E0315, // cannot invoke closure outside of its lifetime
+//  E0319, // trait impls for defaulted traits allowed just for structs/enums
+//  E0372, // coherence not object safe
+//  E0385, // {} in an aliasable location
+//  E0402, // cannot use an outer type parameter in this context
+//  E0406, // merged into 420
+//  E0410, // merged into 408
+//  E0413, // merged into 530
+//  E0414, // merged into 530
+//  E0417, // merged into 532
+//  E0418, // merged into 532
+//  E0419, // merged into 531
+//  E0420, // merged into 532
+//  E0421, // merged into 531
+//  E0427, // merged into 530
+//  E0445, // merged into 446 and type privacy lints
+//  E0456, // plugin `..` is not available for triple `..`
+//  E0465, // removed: merged with E0464
+//  E0467, // removed
+//  E0470, // removed
+//  E0471, // constant evaluation error (in pattern)
+//  E0473, // dereference of reference outside its lifetime
+//  E0474, // captured variable `..` does not outlive the enclosing closure
+//  E0475, // index of slice outside its lifetime
+//  E0479, // the type `..` (provided as the value of a type parameter) is...
+//  E0480, // lifetime of method receiver does not outlive the method call
+//  E0481, // lifetime of function argument does not outlive the function call
+//  E0483, // lifetime of operand does not outlive the operation
+//  E0484, // reference is not valid at the time of borrow
+//  E0485, // automatically reference is not valid at the time of borrow
+//  E0486, // type of expression contains references that are not valid during..
+//  E0487, // unsafe use of destructor: destructor might be called while...
+//  E0488, // lifetime of variable does not enclose its declaration
+//  E0489, // type/lifetime parameter not in scope here
+//  E0490, // removed: unreachable
+//  E0526, // shuffle indices are not constant
+//  E0540, // multiple rustc_deprecated attributes
+//  E0548, // replaced with a generic attribute input check
+//  E0553, // multiple rustc_const_unstable attributes
+//  E0555, // replaced with a generic attribute input check
+//  E0558, // replaced with a generic attribute input check
+//  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
+//  E0564, // only named lifetimes are allowed in `impl Trait`,
+//         // but `{}` was found in the type `{}`
+//  E0598, // lifetime of {} is too short to guarantee its contents can be...
+//  E0611, // merged into E0616
+//  E0612, // merged into E0609
+//  E0613, // Removed (merged with E0609)
+//  E0629, // missing 'feature' (rustc_const_unstable)
+//  E0630, // rustc_const_unstable attribute must be paired with stable/unstable
+//         // attribute
+//  E0645, // trait aliases not finished
+//  E0694, // an unknown tool name found in scoped attributes
+//  E0702, // replaced with a generic attribute input check
+//  E0707, // multiple elided lifetimes used in arguments of `async fn`
+//  E0709, // multiple different lifetimes used in arguments of `async fn`
+//  E0721, // `await` keyword
+//  E0723, // unstable feature in `const` context
+//  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
+//  E0744, // merged into E0728
diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml
index 0c1fcecb571..a2d1fd2a924 100644
--- a/compiler/rustc_errors/Cargo.toml
+++ b/compiler/rustc_errors/Cargo.toml
@@ -10,9 +10,11 @@ derive_setters = "0.1.6"
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_data_structures = { path = "../rustc_data_structures" }
+rustc_error_codes = { path = "../rustc_error_codes" }
 rustc_error_messages = { path = "../rustc_error_messages" }
 rustc_fluent_macro = { path = "../rustc_fluent_macro" }
 rustc_hir = { path = "../rustc_hir" }
+rustc_index = { path = "../rustc_index" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index f0699a56f98..949f52ef6b5 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -9,8 +9,8 @@ use crate::emitter::FileWithAnnotatedLines;
 use crate::snippet::Line;
 use crate::translation::{to_fluent_args, Translate};
 use crate::{
-    CodeSuggestion, Diagnostic, DiagnosticMessage, Emitter, FluentBundle, LazyFallbackBundle,
-    Level, MultiSpan, Style, SubDiagnostic,
+    CodeSuggestion, Diagnostic, DiagnosticMessage, Emitter, ErrCode, FluentBundle,
+    LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
 };
 use annotate_snippets::{Annotation, AnnotationType, Renderer, Slice, Snippet, SourceAnnotation};
 use rustc_data_structures::sync::Lrc;
@@ -127,7 +127,7 @@ impl AnnotateSnippetEmitter {
         level: &Level,
         messages: &[(DiagnosticMessage, Style)],
         args: &FluentArgs<'_>,
-        code: &Option<String>,
+        code: &Option<ErrCode>,
         msp: &MultiSpan,
         _children: &[SubDiagnostic],
         _suggestions: &[CodeSuggestion],
@@ -178,6 +178,7 @@ impl AnnotateSnippetEmitter {
                         .collect::<Vec<Owned>>()
                 })
                 .collect();
+            let code = code.map(|code| code.to_string());
             let snippet = Snippet {
                 title: Some(Annotation {
                     label: Some(&message),
diff --git a/compiler/rustc_errors/src/codes.rs b/compiler/rustc_errors/src/codes.rs
new file mode 100644
index 00000000000..947cf27ca79
--- /dev/null
+++ b/compiler/rustc_errors/src/codes.rs
@@ -0,0 +1,39 @@
+//! This module defines the following.
+//! - The `ErrCode` type.
+//! - A constant for every error code, with a name like `E0123`.
+//! - A static table `DIAGNOSTICS` pairing every error code constant with its
+//!   long description text.
+
+use std::fmt;
+
+rustc_index::newtype_index! {
+    #[max = 9999] // Because all error codes have four digits.
+    #[orderable]
+    #[encodable]
+    #[debug_format = "ErrCode({})"]
+    pub struct ErrCode {}
+}
+
+impl fmt::Display for ErrCode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "E{:04}", self.as_u32())
+    }
+}
+
+macro_rules! define_error_code_constants_and_diagnostics_table {
+    ($($name:ident: $num:literal,)*) => (
+        $(
+            pub const $name: $crate::ErrCode = $crate::ErrCode::from_u32($num);
+        )*
+        pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[
+            $( (
+                $name,
+                include_str!(
+                    concat!("../../rustc_error_codes/src/error_codes/", stringify!($name), ".md")
+                )
+            ), )*
+        ];
+    )
+}
+
+rustc_error_codes::error_codes!(define_error_code_constants_and_diagnostics_table);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 4934bc2450c..8a32e29ddc9 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -1,7 +1,8 @@
 use crate::snippet::Style;
 use crate::{
-    CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level,
-    MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
+    CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee,
+    ErrCode, Level, MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart,
+    SuggestionStyle,
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
@@ -104,7 +105,7 @@ pub struct Diagnostic {
     pub(crate) level: Level,
 
     pub messages: Vec<(DiagnosticMessage, Style)>,
-    pub code: Option<String>,
+    pub code: Option<ErrCode>,
     pub span: MultiSpan,
     pub children: Vec<SubDiagnostic>,
     pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
@@ -893,8 +894,8 @@ impl Diagnostic {
         self
     }
 
-    pub fn code(&mut self, s: String) -> &mut Self {
-        self.code = Some(s);
+    pub fn code(&mut self, code: ErrCode) -> &mut Self {
+        self.code = Some(code);
         self
     }
 
@@ -903,8 +904,8 @@ impl Diagnostic {
         self
     }
 
-    pub fn get_code(&self) -> Option<&str> {
-        self.code.as_deref()
+    pub fn get_code(&self) -> Option<ErrCode> {
+        self.code
     }
 
     pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
@@ -990,7 +991,7 @@ impl Diagnostic {
         &Level,
         &[(DiagnosticMessage, Style)],
         Vec<(&Cow<'static, str>, &DiagnosticArgValue<'static>)>,
-        &Option<String>,
+        &Option<ErrCode>,
         &Option<IsLint>,
         &MultiSpan,
         &Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 87e2d295c7f..8bfb1816486 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -1,7 +1,7 @@
 use crate::diagnostic::IntoDiagnosticArg;
 use crate::{DiagCtxt, Level, MultiSpan, StashKey};
 use crate::{
-    Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrorGuaranteed, ExplicitBug,
+    Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrCode, ErrorGuaranteed, ExplicitBug,
     SubdiagnosticMessage,
 };
 use rustc_lint_defs::Applicability;
@@ -399,7 +399,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
         name: String, has_future_breakage: bool,
     ));
     forward!((code, with_code)(
-        s: String,
+        code: ErrCode,
     ));
     forward!((arg, with_arg)(
         name: impl Into<Cow<'static, str>>, arg: impl IntoDiagnosticArg,
@@ -439,12 +439,7 @@ impl<G: EmissionGuarantee> Drop for DiagnosticBuilder<'_, G> {
 
 #[macro_export]
 macro_rules! struct_span_code_err {
-    ($dcx:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        $dcx.struct_span_err($span, format!($($message)*)).with_code($crate::error_code!($code))
+    ($dcx:expr, $span:expr, $code:expr, $($message:tt)*) => ({
+        $dcx.struct_span_err($span, format!($($message)*)).with_code($code)
     })
 }
-
-#[macro_export]
-macro_rules! error_code {
-    ($code:ident) => {{ stringify!($code).to_owned() }};
-}
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index d58d05095cd..df3fd4af4b4 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -1,7 +1,7 @@
 use crate::diagnostic::DiagnosticLocation;
 use crate::{fluent_generated as fluent, AddToDiagnostic};
 use crate::{
-    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
+    DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, ErrCode, IntoDiagnostic,
     IntoDiagnosticArg, Level,
 };
 use rustc_ast as ast;
@@ -93,6 +93,7 @@ into_diagnostic_arg_using_display!(
     &TargetTriple,
     SplitDebuginfo,
     ExitStatus,
+    ErrCode,
 );
 
 into_diagnostic_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 23efdaea0eb..9f76c1dd248 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -17,8 +17,8 @@ use crate::styled_buffer::StyledBuffer;
 use crate::translation::{to_fluent_args, Translate};
 use crate::{
     diagnostic::DiagnosticLocation, CodeSuggestion, DiagCtxt, Diagnostic, DiagnosticMessage,
-    FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
-    SuggestionStyle, TerminalUrl,
+    ErrCode, FluentBundle, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic,
+    SubstitutionHighlight, SuggestionStyle, TerminalUrl,
 };
 use rustc_lint_defs::pluralize;
 
@@ -1309,7 +1309,7 @@ impl HumanEmitter {
         msp: &MultiSpan,
         msgs: &[(DiagnosticMessage, Style)],
         args: &FluentArgs<'_>,
-        code: &Option<String>,
+        code: &Option<ErrCode>,
         level: &Level,
         max_line_num_len: usize,
         is_secondary: bool,
@@ -1340,9 +1340,9 @@ impl HumanEmitter {
                 buffer.append(0, "[", Style::Level(*level));
                 let code = if let TerminalUrl::Yes = self.terminal_url {
                     let path = "https://doc.rust-lang.org/error_codes";
-                    Cow::Owned(format!("\x1b]8;;{path}/{code}.html\x07{code}\x1b]8;;\x07"))
+                    format!("\x1b]8;;{path}/{code}.html\x07{code}\x1b]8;;\x07")
                 } else {
-                    Cow::Borrowed(code)
+                    code.to_string()
                 };
                 buffer.append(0, &code, Style::Level(*level));
                 buffer.append(0, "]", Style::Level(*level));
@@ -2076,7 +2076,7 @@ impl HumanEmitter {
         level: &Level,
         messages: &[(DiagnosticMessage, Style)],
         args: &FluentArgs<'_>,
-        code: &Option<String>,
+        code: &Option<ErrCode>,
         span: &MultiSpan,
         children: &[SubDiagnostic],
         suggestions: &[CodeSuggestion],
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 51b064f4c61..6f922998279 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -400,10 +400,10 @@ impl Diagnostic {
 
         let translated_message = je.translate_messages(&diag.messages, &args);
 
-        let code = if let Some(code) = &diag.code {
+        let code = if let Some(code) = diag.code {
             Some(DiagnosticCode {
                 code: code.to_string(),
-                explanation: je.registry.as_ref().unwrap().try_find_description(&code).ok(),
+                explanation: je.registry.as_ref().unwrap().try_find_description(code).ok(),
             })
         } else if let Some(IsLint { name, .. }) = &diag.is_lint {
             Some(DiagnosticCode { code: name.to_string(), explanation: None })
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index ee831c4f560..6d9208341a5 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -2,23 +2,26 @@
 //!
 //! This module contains the code for creating and emitting diagnostics.
 
+// tidy-alphabetical-start
+#![allow(incomplete_features)]
+#![allow(internal_features)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(rustdoc_internals)]
 #![feature(array_windows)]
 #![feature(associated_type_defaults)]
 #![feature(box_into_inner)]
 #![feature(box_patterns)]
+#![feature(error_reporter)]
 #![feature(extract_if)]
 #![feature(let_chains)]
+#![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(rustc_attrs)]
-#![feature(yeet_expr)]
+#![feature(rustdoc_internals)]
 #![feature(try_blocks)]
-#![feature(error_reporter)]
-#![allow(incomplete_features)]
-#![allow(internal_features)]
+#![feature(yeet_expr)]
+// tidy-alphabetical-end
 
 #[macro_use]
 extern crate rustc_macros;
@@ -28,6 +31,7 @@ extern crate tracing;
 
 extern crate self as rustc_errors;
 
+pub use codes::*;
 pub use diagnostic::{
     AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgValue,
     DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
@@ -76,6 +80,7 @@ use std::path::{Path, PathBuf};
 use Level::*;
 
 pub mod annotate_snippet_emitter_writer;
+pub mod codes;
 mod diagnostic;
 mod diagnostic_builder;
 mod diagnostic_impls;
@@ -444,10 +449,10 @@ struct DiagCtxtInner {
     /// This set contains the code of all emitted diagnostics to avoid
     /// emitting the same diagnostic with extended help (`--teach`) twice, which
     /// would be unnecessary repetition.
-    taught_diagnostics: FxHashSet<String>,
+    taught_diagnostics: FxHashSet<ErrCode>,
 
     /// Used to suggest rustc --explain `<error code>`
-    emitted_diagnostic_codes: FxIndexSet<String>,
+    emitted_diagnostic_codes: FxIndexSet<ErrCode>,
 
     /// This set contains a hash of every diagnostic that has been emitted by
     /// this `DiagCtxt`. These hashes is used to avoid emitting the same error
@@ -1002,9 +1007,9 @@ impl DiagCtxt {
             let mut error_codes = inner
                 .emitted_diagnostic_codes
                 .iter()
-                .filter_map(|code| {
+                .filter_map(|&code| {
                     if registry.try_find_description(code).is_ok().clone() {
-                        Some(code.clone())
+                        Some(code.to_string())
                     } else {
                         None
                     }
@@ -1050,8 +1055,8 @@ impl DiagCtxt {
     ///
     /// Used to suppress emitting the same error multiple times with extended explanation when
     /// calling `-Zteach`.
-    pub fn must_teach(&self, code: &str) -> bool {
-        self.inner.borrow_mut().taught_diagnostics.insert(code.to_string())
+    pub fn must_teach(&self, code: ErrCode) -> bool {
+        self.inner.borrow_mut().taught_diagnostics.insert(code)
     }
 
     pub fn force_print_diagnostic(&self, db: Diagnostic) {
@@ -1311,8 +1316,8 @@ impl DiagCtxtInner {
 
         let mut guaranteed = None;
         (*TRACK_DIAGNOSTIC)(diagnostic, &mut |mut diagnostic| {
-            if let Some(ref code) = diagnostic.code {
-                self.emitted_diagnostic_codes.insert(code.clone());
+            if let Some(code) = diagnostic.code {
+                self.emitted_diagnostic_codes.insert(code);
             }
 
             let already_emitted = {
diff --git a/compiler/rustc_errors/src/registry.rs b/compiler/rustc_errors/src/registry.rs
index f26d8e7ebdc..8834d04d971 100644
--- a/compiler/rustc_errors/src/registry.rs
+++ b/compiler/rustc_errors/src/registry.rs
@@ -1,3 +1,4 @@
+use crate::ErrCode;
 use rustc_data_structures::fx::FxHashMap;
 
 #[derive(Debug)]
@@ -5,17 +6,17 @@ pub struct InvalidErrorCode;
 
 #[derive(Clone)]
 pub struct Registry {
-    long_descriptions: FxHashMap<&'static str, &'static str>,
+    long_descriptions: FxHashMap<ErrCode, &'static str>,
 }
 
 impl Registry {
-    pub fn new(long_descriptions: &[(&'static str, &'static str)]) -> Registry {
+    pub fn new(long_descriptions: &[(ErrCode, &'static str)]) -> Registry {
         Registry { long_descriptions: long_descriptions.iter().copied().collect() }
     }
 
     /// Returns `InvalidErrorCode` if the code requested does not exist in the
     /// registry.
-    pub fn try_find_description(&self, code: &str) -> Result<&'static str, InvalidErrorCode> {
-        self.long_descriptions.get(code).copied().ok_or(InvalidErrorCode)
+    pub fn try_find_description(&self, code: ErrCode) -> Result<&'static str, InvalidErrorCode> {
+        self.long_descriptions.get(&code).copied().ok_or(InvalidErrorCode)
     }
 }
diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs
index 4a1c00f0104..2584ff62e98 100644
--- a/compiler/rustc_expand/src/errors.rs
+++ b/compiler/rustc_expand/src/errors.rs
@@ -1,4 +1,5 @@
 use rustc_ast::ast;
+use rustc_errors::codes::*;
 use rustc_macros::Diagnostic;
 use rustc_session::Limit;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
@@ -175,7 +176,7 @@ pub(crate) struct TakesNoArguments<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_feature_removed, code = "E0557")]
+#[diag(expand_feature_removed, code = E0557)]
 pub(crate) struct FeatureRemoved<'a> {
     #[primary_span]
     #[label]
@@ -191,7 +192,7 @@ pub(crate) struct FeatureRemovedReason<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_feature_not_allowed, code = "E0725")]
+#[diag(expand_feature_not_allowed, code = E0725)]
 pub(crate) struct FeatureNotAllowed {
     #[primary_span]
     pub span: Span,
@@ -210,7 +211,7 @@ pub(crate) struct RecursionLimitReached<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_malformed_feature_attribute, code = "E0556")]
+#[diag(expand_malformed_feature_attribute, code = E0556)]
 pub(crate) struct MalformedFeatureAttribute {
     #[primary_span]
     pub span: Span,
@@ -347,7 +348,7 @@ pub(crate) struct ModuleInBlockName {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_module_file_not_found, code = "E0583")]
+#[diag(expand_module_file_not_found, code = E0583)]
 #[help]
 #[note]
 pub(crate) struct ModuleFileNotFound {
@@ -359,7 +360,7 @@ pub(crate) struct ModuleFileNotFound {
 }
 
 #[derive(Diagnostic)]
-#[diag(expand_module_multiple_candidates, code = "E0761")]
+#[diag(expand_module_multiple_candidates, code = E0761)]
 #[help]
 pub(crate) struct ModuleMultipleCandidates {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 3aad510f366..c22daad334f 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index bfe88df4e1a..5e9076243f8 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -7,7 +7,9 @@ use crate::fluent_generated as fluent;
 use crate::traits::error_reporting::report_object_safety_error;
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_data_structures::unord::UnordMap;
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed};
+use rustc_errors::{
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::traits::FulfillmentError;
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 4284758b117..30b10446afc 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -5,7 +5,9 @@ use crate::astconv::{
 };
 use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
 use rustc_ast::ast::ParamKindOrd;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index 33e782abc68..98cd8a085ba 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -1,5 +1,5 @@
 use rustc_ast::TraitObjectSyntax;
-use rustc_errors::{Diagnostic, StashKey};
+use rustc_errors::{codes::*, Diagnostic, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 3ba63c659c7..89f39897ea8 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -18,8 +18,8 @@ use crate::require_c_abi_if_c_variadic;
 use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{
-    error_code, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
-    ErrorGuaranteed, FatalError, MultiSpan,
+    codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
+    FatalError, MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -1072,9 +1072,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 if let Some(binding) = binding
                     && let ConvertedBindingKind::Equality(_) = binding.kind
                 {
-                    error_code!(E0222)
+                    E0222
                 } else {
-                    error_code!(E0221)
+                    E0221
                 },
             );
 
@@ -1630,7 +1630,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             let reported = tcx
                 .dcx()
                 .struct_span_err(span, msg)
-                .with_code(rustc_errors::error_code!(E0624))
+                .with_code(E0624)
                 .with_span_label(span, format!("private {kind}"))
                 .with_span_label(def_span, format!("{kind} defined here"))
                 .emit();
diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
index 5f35f75c77b..2d85ad5789e 100644
--- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
@@ -2,7 +2,7 @@ use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBou
 use crate::bounds::Bounds;
 use crate::errors::TraitObjectDeclaredWithNoTraits;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index c63bafcdcd4..2fe3499e8e6 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -5,7 +5,7 @@ use super::compare_impl_item::check_type_bounds;
 use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
 use super::*;
 use rustc_attr as attr;
-use rustc_errors::{ErrorGuaranteed, MultiSpan};
+use rustc_errors::{codes::*, ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LocalDefId};
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 57829d9d418..479421af77f 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2,7 +2,7 @@ use super::potentially_plural_count;
 use crate::errors::LifetimesOrBoundsMismatchOnTrait;
 use hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit;
@@ -1382,7 +1382,7 @@ fn compare_number_of_generics<'tcx>(
                     kind = kind,
                 ),
             );
-            err.code("E0049".into());
+            err.code(E0049);
 
             let msg =
                 format!("expected {trait_count} {kind} parameter{}", pluralize!(trait_count),);
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs
index 3275a81c3dd..9fe95487bb9 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/dropck.rs
@@ -2,7 +2,7 @@
 //
 // We don't do any drop checking during hir typeck.
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
+use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_middle::ty::util::CheckRegions;
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 60e4403c1c7..2d0d6611444 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -8,7 +8,7 @@ use crate::errors::{
 };
 
 use hir::def_id::DefId;
-use rustc_errors::{struct_span_code_err, DiagnosticMessage};
+use rustc_errors::{codes::*, struct_span_code_err, DiagnosticMessage};
 use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 70213ee0614..0978a5e6596 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -4,7 +4,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
+    codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
 };
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 63ea0272014..951440d6a2d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index dafa899ef24..8cf1f2c9407 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -6,7 +6,7 @@
 // mappings. That mapping code resides here.
 
 use crate::errors;
-use rustc_errors::{error_code, struct_span_code_err};
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
@@ -61,7 +61,7 @@ fn enforce_trait_manually_implementable(
         // Maintain explicit error code for `Unsize`, since it has a useful
         // explanation about using `CoerceUnsized` instead.
         if Some(trait_def_id) == tcx.lang_items().unsize_trait() {
-            err.code(error_code!(E0328));
+            err.code(E0328);
         }
 
         return Err(err.emit());
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index e4c407af53f..e3b5c724cde 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -1,7 +1,7 @@
 //! Unsafety checker: every impl either implements a trait defined in this
 //! crate or pertains to a type defined in this crate.
 
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::Unsafety;
 use rustc_middle::ty::TyCtxt;
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a857e01f4fa..97d792e49ae 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -8,7 +8,7 @@
 
 use rustc_ast::walk_list;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index f14390b77c6..e5871276d64 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -2,8 +2,8 @@
 
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    error_code, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
-    Level, MultiSpan,
+    codes::*, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
+    MultiSpan,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
@@ -52,7 +52,7 @@ pub struct AssocKindMismatchWrapInBracesSugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_assoc_item_not_found, code = "E0220")]
+#[diag(hir_analysis_assoc_item_not_found, code = E0220)]
 pub struct AssocItemNotFound<'a> {
     #[primary_span]
     pub span: Span,
@@ -122,7 +122,7 @@ pub enum AssocItemNotFoundSugg<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_unrecognized_atomic_operation, code = "E0092")]
+#[diag(hir_analysis_unrecognized_atomic_operation, code = E0092)]
 pub struct UnrecognizedAtomicOperation<'a> {
     #[primary_span]
     #[label]
@@ -131,7 +131,7 @@ pub struct UnrecognizedAtomicOperation<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")]
+#[diag(hir_analysis_wrong_number_of_generic_arguments_to_intrinsic, code = E0094)]
 pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
     #[primary_span]
     #[label]
@@ -142,7 +142,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_unrecognized_intrinsic_function, code = "E0093")]
+#[diag(hir_analysis_unrecognized_intrinsic_function, code = E0093)]
 pub struct UnrecognizedIntrinsicFunction {
     #[primary_span]
     #[label]
@@ -151,7 +151,7 @@ pub struct UnrecognizedIntrinsicFunction {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_lifetimes_or_bounds_mismatch_on_trait, code = "E0195")]
+#[diag(hir_analysis_lifetimes_or_bounds_mismatch_on_trait, code = E0195)]
 pub struct LifetimesOrBoundsMismatchOnTrait {
     #[primary_span]
     #[label]
@@ -178,7 +178,7 @@ pub struct AsyncTraitImplShouldBeAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_drop_impl_on_wrong_item, code = "E0120")]
+#[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
 pub struct DropImplOnWrongItem {
     #[primary_span]
     #[label]
@@ -186,7 +186,7 @@ pub struct DropImplOnWrongItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_field_already_declared, code = "E0124")]
+#[diag(hir_analysis_field_already_declared, code = E0124)]
 pub struct FieldAlreadyDeclared {
     pub field_name: Ident,
     #[primary_span]
@@ -197,7 +197,7 @@ pub struct FieldAlreadyDeclared {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_copy_impl_on_type_with_dtor, code = "E0184")]
+#[diag(hir_analysis_copy_impl_on_type_with_dtor, code = E0184)]
 pub struct CopyImplOnTypeWithDtor {
     #[primary_span]
     #[label]
@@ -205,14 +205,14 @@ pub struct CopyImplOnTypeWithDtor {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_multiple_relaxed_default_bounds, code = "E0203")]
+#[diag(hir_analysis_multiple_relaxed_default_bounds, code = E0203)]
 pub struct MultipleRelaxedDefaultBounds {
     #[primary_span]
     pub spans: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_copy_impl_on_non_adt, code = "E0206")]
+#[diag(hir_analysis_copy_impl_on_non_adt, code = E0206)]
 pub struct CopyImplOnNonAdt {
     #[primary_span]
     #[label]
@@ -228,7 +228,7 @@ pub struct ConstParamTyImplOnNonAdt {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_trait_object_declared_with_no_traits, code = "E0224")]
+#[diag(hir_analysis_trait_object_declared_with_no_traits, code = E0224)]
 pub struct TraitObjectDeclaredWithNoTraits {
     #[primary_span]
     pub span: Span,
@@ -237,14 +237,14 @@ pub struct TraitObjectDeclaredWithNoTraits {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_ambiguous_lifetime_bound, code = "E0227")]
+#[diag(hir_analysis_ambiguous_lifetime_bound, code = E0227)]
 pub struct AmbiguousLifetimeBound {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_assoc_type_binding_not_allowed, code = "E0229")]
+#[diag(hir_analysis_assoc_type_binding_not_allowed, code = E0229)]
 pub struct AssocTypeBindingNotAllowed {
     #[primary_span]
     #[label]
@@ -264,7 +264,7 @@ pub struct ParenthesizedFnTraitExpansion {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_typeof_reserved_keyword_used, code = "E0516")]
+#[diag(hir_analysis_typeof_reserved_keyword_used, code = E0516)]
 pub struct TypeofReservedKeywordUsed<'tcx> {
     pub ty: Ty<'tcx>,
     #[primary_span]
@@ -275,7 +275,7 @@ pub struct TypeofReservedKeywordUsed<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_value_of_associated_struct_already_specified, code = "E0719")]
+#[diag(hir_analysis_value_of_associated_struct_already_specified, code = E0719)]
 pub struct ValueOfAssociatedStructAlreadySpecified {
     #[primary_span]
     #[label]
@@ -320,7 +320,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for MissingTypeParams {
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
         let mut err = DiagnosticBuilder::new(dcx, level, fluent::hir_analysis_missing_type_params);
         err.span(self.span);
-        err.code(error_code!(E0393));
+        err.code(E0393);
         err.arg("parameterCount", self.missing_type_params.len());
         err.arg(
             "parameters",
@@ -373,7 +373,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for MissingTypeParams {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_manual_implementation, code = "E0183")]
+#[diag(hir_analysis_manual_implementation, code = E0183)]
 #[help]
 pub struct ManualImplementation {
     #[primary_span]
@@ -421,7 +421,7 @@ pub struct SelfInImplSelf {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_linkage_type, code = "E0791")]
+#[diag(hir_analysis_linkage_type, code = E0791)]
 pub(crate) struct LinkageType {
     #[primary_span]
     pub span: Span,
@@ -429,7 +429,7 @@ pub(crate) struct LinkageType {
 
 #[derive(Diagnostic)]
 #[help]
-#[diag(hir_analysis_auto_deref_reached_recursion_limit, code = "E0055")]
+#[diag(hir_analysis_auto_deref_reached_recursion_limit, code = E0055)]
 pub struct AutoDerefReachedRecursionLimit<'a> {
     #[primary_span]
     #[label]
@@ -440,7 +440,7 @@ pub struct AutoDerefReachedRecursionLimit<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_where_clause_on_main, code = "E0646")]
+#[diag(hir_analysis_where_clause_on_main, code = E0646)]
 pub(crate) struct WhereClauseOnMain {
     #[primary_span]
     pub span: Span,
@@ -485,7 +485,7 @@ pub(crate) struct StartTargetFeature {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_start_not_async, code = "E0752")]
+#[diag(hir_analysis_start_not_async, code = E0752)]
 pub(crate) struct StartAsync {
     #[primary_span]
     #[label]
@@ -493,7 +493,7 @@ pub(crate) struct StartAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_start_function_where, code = "E0647")]
+#[diag(hir_analysis_start_function_where, code = E0647)]
 pub(crate) struct StartFunctionWhere {
     #[primary_span]
     #[label]
@@ -501,7 +501,7 @@ pub(crate) struct StartFunctionWhere {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_start_function_parameters, code = "E0132")]
+#[diag(hir_analysis_start_function_parameters, code = E0132)]
 pub(crate) struct StartFunctionParameters {
     #[primary_span]
     #[label]
@@ -509,14 +509,14 @@ pub(crate) struct StartFunctionParameters {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_main_function_return_type_generic, code = "E0131")]
+#[diag(hir_analysis_main_function_return_type_generic, code = E0131)]
 pub(crate) struct MainFunctionReturnTypeGeneric {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_main_function_async, code = "E0752")]
+#[diag(hir_analysis_main_function_async, code = E0752)]
 pub(crate) struct MainFunctionAsync {
     #[primary_span]
     pub span: Span,
@@ -525,7 +525,7 @@ pub(crate) struct MainFunctionAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_main_function_generic_parameters, code = "E0131")]
+#[diag(hir_analysis_main_function_generic_parameters, code = E0131)]
 pub(crate) struct MainFunctionGenericParameters {
     #[primary_span]
     pub span: Span,
@@ -534,7 +534,7 @@ pub(crate) struct MainFunctionGenericParameters {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_variadic_function_compatible_convention, code = "E0045")]
+#[diag(hir_analysis_variadic_function_compatible_convention, code = E0045)]
 pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
     #[primary_span]
     #[label]
@@ -587,7 +587,7 @@ pub(crate) struct TypeOf<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_pass_to_variadic_function, code = "E0617")]
+#[diag(hir_analysis_pass_to_variadic_function, code = E0617)]
 pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
     #[primary_span]
     pub span: Span,
@@ -601,7 +601,7 @@ pub(crate) struct PassToVariadicFunction<'tcx, 'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cast_thin_pointer_to_fat_pointer, code = "E0607")]
+#[diag(hir_analysis_cast_thin_pointer_to_fat_pointer, code = E0607)]
 pub(crate) struct CastThinPointerToFatPointer<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -610,7 +610,7 @@ pub(crate) struct CastThinPointerToFatPointer<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_invalid_union_field, code = "E0740")]
+#[diag(hir_analysis_invalid_union_field, code = E0740)]
 pub(crate) struct InvalidUnionField {
     #[primary_span]
     pub field_span: Span,
@@ -649,7 +649,7 @@ pub(crate) struct ReturnTypeNotationEqualityBound {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = "E0121")]
+#[diag(hir_analysis_placeholder_not_allowed_item_signatures, code = E0121)]
 pub(crate) struct PlaceholderNotAllowedItemSignatures {
     #[primary_span]
     #[label]
@@ -658,7 +658,7 @@ pub(crate) struct PlaceholderNotAllowedItemSignatures {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_associated_type_trait_uninferred_generic_params, code = "E0212")]
+#[diag(hir_analysis_associated_type_trait_uninferred_generic_params, code = E0212)]
 pub(crate) struct AssociatedTypeTraitUninferredGenericParams {
     #[primary_span]
     pub span: Span,
@@ -684,7 +684,7 @@ pub(crate) struct AssociatedTypeTraitUninferredGenericParamsMultipartSuggestion
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_enum_discriminant_overflowed, code = "E0370")]
+#[diag(hir_analysis_enum_discriminant_overflowed, code = E0370)]
 #[note]
 pub(crate) struct EnumDiscriminantOverflowed {
     #[primary_span]
@@ -774,7 +774,7 @@ pub(crate) struct SIMDFFIHighlyExperimental {
 
 #[derive(Diagnostic)]
 pub enum ImplNotMarkedDefault {
-    #[diag(hir_analysis_impl_not_marked_default, code = "E0520")]
+    #[diag(hir_analysis_impl_not_marked_default, code = E0520)]
     #[note]
     Ok {
         #[primary_span]
@@ -784,7 +784,7 @@ pub enum ImplNotMarkedDefault {
         ok_label: Span,
         ident: Symbol,
     },
-    #[diag(hir_analysis_impl_not_marked_default_err, code = "E0520")]
+    #[diag(hir_analysis_impl_not_marked_default_err, code = E0520)]
     #[note]
     Err {
         #[primary_span]
@@ -795,7 +795,7 @@ pub enum ImplNotMarkedDefault {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_missing_trait_item, code = "E0046")]
+#[diag(hir_analysis_missing_trait_item, code = E0046)]
 pub(crate) struct MissingTraitItem {
     #[primary_span]
     #[label]
@@ -846,7 +846,7 @@ pub(crate) struct MissingTraitItemSuggestionNone {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_missing_one_of_trait_item, code = "E0046")]
+#[diag(hir_analysis_missing_one_of_trait_item, code = E0046)]
 pub(crate) struct MissingOneOfTraitItem {
     #[primary_span]
     #[label]
@@ -857,7 +857,7 @@ pub(crate) struct MissingOneOfTraitItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_missing_trait_item_unstable, code = "E0046")]
+#[diag(hir_analysis_missing_trait_item_unstable, code = E0046)]
 #[note]
 pub(crate) struct MissingTraitItemUnstable {
     #[primary_span]
@@ -872,7 +872,7 @@ pub(crate) struct MissingTraitItemUnstable {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_transparent_enum_variant, code = "E0731")]
+#[diag(hir_analysis_transparent_enum_variant, code = E0731)]
 pub(crate) struct TransparentEnumVariant {
     #[primary_span]
     #[label]
@@ -886,7 +886,7 @@ pub(crate) struct TransparentEnumVariant {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_transparent_non_zero_sized_enum, code = "E0690")]
+#[diag(hir_analysis_transparent_non_zero_sized_enum, code = E0690)]
 pub(crate) struct TransparentNonZeroSizedEnum<'a> {
     #[primary_span]
     #[label]
@@ -898,7 +898,7 @@ pub(crate) struct TransparentNonZeroSizedEnum<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_transparent_non_zero_sized, code = "E0690")]
+#[diag(hir_analysis_transparent_non_zero_sized, code = E0690)]
 pub(crate) struct TransparentNonZeroSized<'a> {
     #[primary_span]
     #[label]
@@ -1045,7 +1045,7 @@ pub(crate) struct ReturnPositionImplTraitInTraitRefined<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside, code = "E0390")]
+#[diag(hir_analysis_inherent_ty_outside, code = E0390)]
 #[help]
 pub struct InherentTyOutside {
     #[primary_span]
@@ -1054,7 +1054,7 @@ pub struct InherentTyOutside {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
 pub struct DispatchFromDynCoercion<'a> {
     #[primary_span]
     pub span: Span,
@@ -1066,14 +1066,14 @@ pub struct DispatchFromDynCoercion<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_repr, code = "E0378")]
+#[diag(hir_analysis_dispatch_from_dyn_repr, code = E0378)]
 pub struct DispatchFromDynRepr {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside_relevant, code = "E0390")]
+#[diag(hir_analysis_inherent_ty_outside_relevant, code = E0390)]
 #[help]
 pub struct InherentTyOutsideRelevant {
     #[primary_span]
@@ -1083,7 +1083,7 @@ pub struct InherentTyOutsideRelevant {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside_new, code = "E0116")]
+#[diag(hir_analysis_inherent_ty_outside_new, code = E0116)]
 #[note]
 pub struct InherentTyOutsideNew {
     #[primary_span]
@@ -1092,7 +1092,7 @@ pub struct InherentTyOutsideNew {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_ty_outside_primitive, code = "E0390")]
+#[diag(hir_analysis_inherent_ty_outside_primitive, code = E0390)]
 #[help]
 pub struct InherentTyOutsidePrimitive {
     #[primary_span]
@@ -1102,7 +1102,7 @@ pub struct InherentTyOutsidePrimitive {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_primitive_ty, code = "E0390")]
+#[diag(hir_analysis_inherent_primitive_ty, code = E0390)]
 #[help]
 pub struct InherentPrimitiveTy<'a> {
     #[primary_span]
@@ -1118,7 +1118,7 @@ pub struct InherentPrimitiveTyNote<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_dyn, code = "E0785")]
+#[diag(hir_analysis_inherent_dyn, code = E0785)]
 #[note]
 pub struct InherentDyn {
     #[primary_span]
@@ -1127,7 +1127,7 @@ pub struct InherentDyn {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_inherent_nominal, code = "E0118")]
+#[diag(hir_analysis_inherent_nominal, code = E0118)]
 #[note]
 pub struct InherentNominal {
     #[primary_span]
@@ -1136,7 +1136,7 @@ pub struct InherentNominal {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_zst, code = "E0378")]
+#[diag(hir_analysis_dispatch_from_dyn_zst, code = E0378)]
 #[note]
 pub struct DispatchFromDynZST<'a> {
     #[primary_span]
@@ -1146,7 +1146,7 @@ pub struct DispatchFromDynZST<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
 pub struct DispatchFromDynSingle<'a> {
     #[primary_span]
     pub span: Span,
@@ -1156,7 +1156,7 @@ pub struct DispatchFromDynSingle<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_dispatch_from_dyn_multi, code = "E0378")]
+#[diag(hir_analysis_dispatch_from_dyn_multi, code = E0378)]
 #[note]
 pub struct DispatchFromDynMulti {
     #[primary_span]
@@ -1168,7 +1168,7 @@ pub struct DispatchFromDynMulti {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0376")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0376)]
 pub struct DispatchFromDynStruct<'a> {
     #[primary_span]
     pub span: Span,
@@ -1176,7 +1176,7 @@ pub struct DispatchFromDynStruct<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0377")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0377)]
 pub struct DispatchFromDynSame<'a> {
     #[primary_span]
     pub span: Span,
@@ -1188,7 +1188,7 @@ pub struct DispatchFromDynSame<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0374")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0374)]
 pub struct CoerceUnsizedOneField<'a> {
     #[primary_span]
     pub span: Span,
@@ -1198,7 +1198,7 @@ pub struct CoerceUnsizedOneField<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_multi, code = "E0375")]
+#[diag(hir_analysis_coerce_unsized_multi, code = E0375)]
 #[note]
 pub struct CoerceUnsizedMulti {
     #[primary_span]
@@ -1211,7 +1211,7 @@ pub struct CoerceUnsizedMulti {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+#[diag(hir_analysis_coerce_unsized_may, code = E0378)]
 pub struct CoerceUnsizedMay<'a> {
     #[primary_span]
     pub span: Span,
@@ -1219,7 +1219,7 @@ pub struct CoerceUnsizedMay<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_trait_cannot_impl_for_ty, code = "E0204")]
+#[diag(hir_analysis_trait_cannot_impl_for_ty, code = E0204)]
 pub struct TraitCannotImplForTy {
     #[primary_span]
     pub span: Span,
@@ -1241,7 +1241,7 @@ pub struct ImplForTyRequires {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_traits_with_defualt_impl, code = "E0321")]
+#[diag(hir_analysis_traits_with_defualt_impl, code = E0321)]
 #[note]
 pub struct TraitsWithDefaultImpl<'a> {
     #[primary_span]
@@ -1252,7 +1252,7 @@ pub struct TraitsWithDefaultImpl<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cross_crate_traits, code = "E0321")]
+#[diag(hir_analysis_cross_crate_traits, code = E0321)]
 pub struct CrossCrateTraits<'a> {
     #[primary_span]
     #[label]
@@ -1262,7 +1262,7 @@ pub struct CrossCrateTraits<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_cross_crate_traits_defined, code = "E0321")]
+#[diag(hir_analysis_cross_crate_traits_defined, code = E0321)]
 pub struct CrossCrateTraitsDefined {
     #[primary_span]
     #[label]
@@ -1271,7 +1271,7 @@ pub struct CrossCrateTraitsDefined {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_ty_param_first_local, code = "E0210")]
+#[diag(hir_analysis_ty_param_first_local, code = E0210)]
 #[note]
 pub struct TyParamFirstLocal<'a> {
     #[primary_span]
@@ -1284,7 +1284,7 @@ pub struct TyParamFirstLocal<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_ty_param_some, code = "E0210")]
+#[diag(hir_analysis_ty_param_some, code = E0210)]
 #[note]
 pub struct TyParamSome<'a> {
     #[primary_span]
@@ -1297,7 +1297,7 @@ pub struct TyParamSome<'a> {
 
 #[derive(Diagnostic)]
 pub enum OnlyCurrentTraits<'a> {
-    #[diag(hir_analysis_only_current_traits_outside, code = "E0117")]
+    #[diag(hir_analysis_only_current_traits_outside, code = E0117)]
     Outside {
         #[primary_span]
         #[label(hir_analysis_only_current_traits_label)]
@@ -1317,7 +1317,7 @@ pub enum OnlyCurrentTraits<'a> {
         #[subdiagnostic]
         sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
-    #[diag(hir_analysis_only_current_traits_primitive, code = "E0117")]
+    #[diag(hir_analysis_only_current_traits_primitive, code = E0117)]
     Primitive {
         #[primary_span]
         #[label(hir_analysis_only_current_traits_label)]
@@ -1337,7 +1337,7 @@ pub enum OnlyCurrentTraits<'a> {
         #[subdiagnostic]
         sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
     },
-    #[diag(hir_analysis_only_current_traits_arbitrary, code = "E0117")]
+    #[diag(hir_analysis_only_current_traits_arbitrary, code = E0117)]
     Arbitrary {
         #[primary_span]
         #[label(hir_analysis_only_current_traits_label)]
@@ -1412,7 +1412,7 @@ pub struct OnlyCurrentTraitsPointerSugg<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_static_mut_ref, code = "E0796")]
+#[diag(hir_analysis_static_mut_ref, code = E0796)]
 #[note]
 pub struct StaticMutRef {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 2fe08ead72b..c072891e295 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -12,7 +12,7 @@ use crate::constrained_generic_params as cgp;
 use min_specialization::check_min_specialization;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_hir_analysis/src/structured_errors.rs b/compiler/rustc_hir_analysis/src/structured_errors.rs
index b061d637138..6846e4defe5 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors.rs
@@ -6,18 +6,18 @@ pub use self::{
     missing_cast_for_variadic_arg::*, sized_unsized_cast::*, wrong_number_of_generic_args::*,
 };
 
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{DiagnosticBuilder, ErrCode};
 use rustc_session::Session;
 
 pub trait StructuredDiagnostic<'tcx> {
     fn session(&self) -> &Session;
 
-    fn code(&self) -> String;
+    fn code(&self) -> ErrCode;
 
     fn diagnostic(&self) -> DiagnosticBuilder<'tcx> {
         let err = self.diagnostic_common();
 
-        if self.session().teach(&self.code()) {
+        if self.session().teach(self.code()) {
             self.diagnostic_extended(err)
         } else {
             self.diagnostic_regular(err)
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
index 6f4435db411..50b4ef623ac 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs
@@ -1,5 +1,5 @@
 use crate::{errors, structured_errors::StructuredDiagnostic};
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode};
 use rustc_middle::ty::{Ty, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::Span;
@@ -16,8 +16,8 @@ impl<'tcx> StructuredDiagnostic<'tcx> for MissingCastForVariadicArg<'tcx, '_> {
         self.sess
     }
 
-    fn code(&self) -> String {
-        rustc_errors::error_code!(E0617)
+    fn code(&self) -> ErrCode {
+        E0617
     }
 
     fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
index 19cac4a38aa..54d54a2af93 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs
@@ -1,5 +1,5 @@
 use crate::{errors, structured_errors::StructuredDiagnostic};
-use rustc_errors::DiagnosticBuilder;
+use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode};
 use rustc_middle::ty::{Ty, TypeVisitableExt};
 use rustc_session::Session;
 use rustc_span::Span;
@@ -16,8 +16,8 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCast<'tcx> {
         self.sess
     }
 
-    fn code(&self) -> String {
-        rustc_errors::error_code!(E0607)
+    fn code(&self) -> ErrCode {
+        E0607
     }
 
     fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index ba81e7f1f81..501915d2e7e 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -1,5 +1,7 @@
 use crate::structured_errors::StructuredDiagnostic;
-use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    codes::*, pluralize, Applicability, Diagnostic, DiagnosticBuilder, ErrCode, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
 use rustc_session::Session;
@@ -1105,8 +1107,8 @@ impl<'tcx> StructuredDiagnostic<'tcx> for WrongNumberOfGenericArgs<'_, 'tcx> {
         self.tcx.sess
     }
 
-    fn code(&self) -> String {
-        rustc_errors::error_code!(E0107)
+    fn code(&self) -> ErrCode {
+        E0107
     }
 
     fn diagnostic_common(&self) -> DiagnosticBuilder<'tcx> {
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index bd8a2024caa..a0ac839f3dd 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -33,7 +33,7 @@ use super::FnCtxt;
 use crate::errors;
 use crate::type_error_struct;
 use hir::ExprKind;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{codes::*, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_macros::{TypeFoldable, TypeVisitable};
 use rustc_middle::mir::Mutability;
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 858faf161f6..ca636ebcade 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -36,7 +36,9 @@
 //! ```
 
 use crate::FnCtxt;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
+};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 4f929068887..b75cf4b4e8b 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -3,8 +3,8 @@ use std::borrow::Cow;
 
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg, MultiSpan,
-    SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg,
+    MultiSpan, SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
@@ -15,7 +15,7 @@ use rustc_span::{
 };
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_field_multiply_specified_in_initializer, code = "E0062")]
+#[diag(hir_typeck_field_multiply_specified_in_initializer, code = E0062)]
 pub struct FieldMultiplySpecifiedInInitializer {
     #[primary_span]
     #[label]
@@ -26,7 +26,7 @@ pub struct FieldMultiplySpecifiedInInitializer {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = "E0572")]
+#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = E0572)]
 pub struct ReturnStmtOutsideOfFnBody {
     #[primary_span]
     pub span: Span,
@@ -62,14 +62,14 @@ pub struct RustCallIncorrectArgs {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = "E0627")]
+#[diag(hir_typeck_yield_expr_outside_of_coroutine, code = E0627)]
 pub struct YieldExprOutsideOfCoroutine {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_struct_expr_non_exhaustive, code = "E0639")]
+#[diag(hir_typeck_struct_expr_non_exhaustive, code = E0639)]
 pub struct StructExprNonExhaustive {
     #[primary_span]
     pub span: Span,
@@ -77,7 +77,7 @@ pub struct StructExprNonExhaustive {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_method_call_on_unknown_raw_pointee, code = "E0699")]
+#[diag(hir_typeck_method_call_on_unknown_raw_pointee, code = E0699)]
 pub struct MethodCallOnUnknownRawPointee {
     #[primary_span]
     pub span: Span,
@@ -92,14 +92,14 @@ pub struct MissingFnLangItems {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_functional_record_update_on_non_struct, code = "E0436")]
+#[diag(hir_typeck_functional_record_update_on_non_struct, code = E0436)]
 pub struct FunctionalRecordUpdateOnNonStruct {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_address_of_temporary_taken, code = "E0745")]
+#[diag(hir_typeck_address_of_temporary_taken, code = E0745)]
 pub struct AddressOfTemporaryTaken {
     #[primary_span]
     #[label]
@@ -145,7 +145,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_explicit_destructor, code = "E0040")]
+#[diag(hir_typeck_explicit_destructor, code = E0040)]
 pub struct ExplicitDestructorCall {
     #[primary_span]
     #[label]
@@ -168,7 +168,7 @@ pub enum ExplicitDestructorCallSugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_missing_parentheses_in_range, code = "E0689")]
+#[diag(hir_typeck_missing_parentheses_in_range, code = E0689)]
 pub struct MissingParenthesesInRange {
     #[primary_span]
     #[label(hir_typeck_missing_parentheses_in_range)]
@@ -321,7 +321,7 @@ impl HelpUseLatestEdition {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_invalid_callee, code = "E0618")]
+#[diag(hir_typeck_invalid_callee, code = E0618)]
 pub struct InvalidCallee {
     #[primary_span]
     pub span: Span,
@@ -329,7 +329,7 @@ pub struct InvalidCallee {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_int_to_fat, code = "E0606")]
+#[diag(hir_typeck_int_to_fat, code = E0606)]
 pub struct IntToWide<'tcx> {
     #[primary_span]
     #[label(hir_typeck_int_to_fat_label)]
@@ -510,7 +510,7 @@ pub struct TrivialCast<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_no_associated_item, code = "E0599")]
+#[diag(hir_typeck_no_associated_item, code = E0599)]
 pub struct NoAssociatedItem {
     #[primary_span]
     pub span: Span,
@@ -532,7 +532,7 @@ pub struct CandidateTraitNote {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_cannot_cast_to_bool, code = "E0054")]
+#[diag(hir_typeck_cannot_cast_to_bool, code = E0054)]
 pub struct CannotCastToBool<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -549,7 +549,7 @@ pub struct CastEnumDrop<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_cast_unknown_pointer, code = "E0641")]
+#[diag(hir_typeck_cast_unknown_pointer, code = E0641)]
 pub struct CastUnknownPointer {
     #[primary_span]
     pub span: Span,
@@ -600,7 +600,7 @@ pub enum CannotCastToBoolHelp {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_typeck_ctor_is_private, code = "E0603")]
+#[diag(hir_typeck_ctor_is_private, code = E0603)]
 pub struct CtorIsPrivate {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 3bc40325588..d00ae4db300 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -25,8 +25,8 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder,
-    ErrorGuaranteed, StashKey,
+    codes::*, pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic,
+    DiagnosticBuilder, ErrCode, ErrorGuaranteed, StashKey,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -527,7 +527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Ty::new_error(tcx, e)
             }
             Res::Def(DefKind::Variant, _) => {
-                let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value");
+                let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, E0533, "value");
                 Ty::new_error(tcx, e)
             }
             _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
@@ -939,7 +939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn check_lhs_assignable(
         &self,
         lhs: &'tcx hir::Expr<'tcx>,
-        err_code: &'static str,
+        code: ErrCode,
         op_span: Span,
         adjust_err: impl FnOnce(&mut Diagnostic),
     ) {
@@ -948,7 +948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let mut err = self.dcx().struct_span_err(op_span, "invalid left-hand side of assignment");
-        err.code(err_code.into());
+        err.code(code);
         err.span_label(lhs.span, "cannot assign to this expression");
 
         self.comes_from_while_condition(lhs.hir_id, |expr| {
@@ -1244,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             diag.emit();
         }
 
-        self.check_lhs_assignable(lhs, "E0070", span, |err| {
+        self.check_lhs_assignable(lhs, E0070, span, |err| {
             if let Some(rhs_ty) = self.typeck_results.borrow().expr_ty_opt(rhs) {
                 suggest_deref_binop(err, rhs_ty);
             }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 6a77450f075..2494feee1ff 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -12,7 +12,9 @@ use crate::{
 use itertools::Itertools;
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{pluralize, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey};
+use rustc_errors::{
+    codes::*, pluralize, Applicability, Diagnostic, ErrCode, ErrorGuaranteed, MultiSpan, StashKey,
+};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -177,7 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
         }
 
-        let mut err_code = "E0061";
+        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 {
@@ -187,7 +189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ty::Tuple(arg_types) => {
                     // Argument length differs
                     if arg_types.len() != provided_args.len() {
-                        err_code = "E0057";
+                        err_code = E0057;
                     }
                     let expected_input_tys = match expected_input_tys {
                         Some(expected_input_tys) => match expected_input_tys.get(0) {
@@ -358,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         if c_variadic && provided_arg_count < minimum_input_count {
-            err_code = "E0060";
+            err_code = E0060;
         }
 
         for arg in provided_args.iter().skip(minimum_input_count) {
@@ -443,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         formal_and_expected_inputs: IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
         provided_args: IndexVec<ProvidedIdx, &'tcx hir::Expr<'tcx>>,
         c_variadic: bool,
-        err_code: &str,
+        err_code: ErrCode,
         fn_def_id: Option<DefId>,
         call_span: Span,
         call_expr: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 896d000233a..95c1139e43e 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -2140,46 +2140,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr_ty: Ty<'tcx>,
     ) -> bool {
         let tcx = self.tcx;
-        let (adt, unwrap) = match expected.kind() {
+        let (adt, substs, unwrap) = match expected.kind() {
             // In case Option<NonZero*> is wanted, but * is provided, suggest calling new
-            ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
-                // Unwrap option
-                let ty::Adt(adt, _) = args.type_at(0).kind() else {
+            ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
+                let nonzero_type = substs.type_at(0); // Unwrap option type.
+                let ty::Adt(adt, substs) = nonzero_type.kind() else {
                     return false;
                 };
-
-                (adt, "")
+                (adt, substs, "")
             }
-            // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types
-            ty::Adt(adt, _) => (adt, ".unwrap()"),
+            // In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
+            ty::Adt(adt, substs) => (adt, substs, ".unwrap()"),
             _ => return false,
         };
 
-        let map = [
-            (sym::NonZeroU8, tcx.types.u8),
-            (sym::NonZeroU16, tcx.types.u16),
-            (sym::NonZeroU32, tcx.types.u32),
-            (sym::NonZeroU64, tcx.types.u64),
-            (sym::NonZeroU128, tcx.types.u128),
-            (sym::NonZeroI8, tcx.types.i8),
-            (sym::NonZeroI16, tcx.types.i16),
-            (sym::NonZeroI32, tcx.types.i32),
-            (sym::NonZeroI64, tcx.types.i64),
-            (sym::NonZeroI128, tcx.types.i128),
+        if !self.tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
+            return false;
+        }
+
+        // FIXME: This can be simplified once `NonZero<T>` is stable.
+        let coercable_types = [
+            ("NonZeroU8", tcx.types.u8),
+            ("NonZeroU16", tcx.types.u16),
+            ("NonZeroU32", tcx.types.u32),
+            ("NonZeroU64", tcx.types.u64),
+            ("NonZeroU128", tcx.types.u128),
+            ("NonZeroI8", tcx.types.i8),
+            ("NonZeroI16", tcx.types.i16),
+            ("NonZeroI32", tcx.types.i32),
+            ("NonZeroI64", tcx.types.i64),
+            ("NonZeroI128", tcx.types.i128),
         ];
 
-        let Some((s, _)) = map.iter().find(|&&(s, t)| {
-            self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t)
+        let int_type = substs.type_at(0);
+
+        let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
+            if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }
         }) else {
             return false;
         };
 
-        let path = self.tcx.def_path_str(adt.non_enum_variant().def_id);
-
         err.multipart_suggestion(
-            format!("consider calling `{s}::new`"),
+            format!("consider calling `{nonzero_alias}::new`"),
             vec![
-                (expr.span.shrink_to_lo(), format!("{path}::new(")),
+                (expr.span.shrink_to_lo(), format!("{nonzero_alias}::new(")),
                 (expr.span.shrink_to_hi(), format!("){unwrap}")),
             ],
             Applicability::MaybeIncorrect,
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index e087733130e..2dee5093e87 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -1,5 +1,5 @@
 use hir::HirId;
-use rustc_errors::struct_span_code_err;
+use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_index::Idx;
 use rustc_middle::ty::layout::{LayoutError, SizeSkeleton};
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 36cd6583147..36aa949668f 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -51,7 +51,7 @@ use crate::expectation::Expectation;
 use crate::fn_ctxt::LoweredTy;
 use crate::gather_locals::GatherLocalsVisitor;
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
+use rustc_errors::{codes::*, struct_span_code_err, ErrCode, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::Visitor;
@@ -71,7 +71,7 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 #[macro_export]
 macro_rules! type_error_struct {
-    ($dcx:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
+    ($dcx:expr, $span:expr, $typ:expr, $code:expr, $($message:tt)*) => ({
         let mut err = rustc_errors::struct_span_code_err!($dcx, $span, $code, $($message)*);
 
         if $typ.references_error() {
@@ -375,7 +375,7 @@ fn report_unexpected_variant_res(
     res: Res,
     qpath: &hir::QPath<'_>,
     span: Span,
-    err_code: &str,
+    err_code: ErrCode,
     expected: &str,
 ) -> ErrorGuaranteed {
     let res_descr = match res {
@@ -386,9 +386,9 @@ fn report_unexpected_variant_res(
     let err = tcx
         .dcx()
         .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`"))
-        .with_code(err_code.into());
+        .with_code(err_code);
     match res {
-        Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => {
+        Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == E0164 => {
             let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
             err.with_span_label(span, "`fn` calls are not allowed in patterns")
                 .with_help(format!("for more information, visit {patterns_url}"))
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 47f6e3f934e..314d28e6e04 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3,17 +3,16 @@
 
 // ignore-tidy-filelength
 
-use crate::errors;
-use crate::errors::{CandidateTraitNote, NoAssociatedItem};
+use crate::errors::{self, CandidateTraitNote, NoAssociatedItem};
 use crate::Expectation;
 use crate::FnCtxt;
 use rustc_ast::ast::Mutability;
 use rustc_attr::parse_confusables;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::unord::UnordSet;
-use rustc_errors::StashKey;
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    MultiSpan, StashKey,
 };
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index ff82e2d653c..bbe6d9e9670 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -5,7 +5,7 @@ use super::{has_expected_num_generic_args, FnCtxt};
 use crate::Expectation;
 use rustc_ast as ast;
 use rustc_data_structures::packed::Pu128;
-use rustc_errors::{struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::traits::ObligationCauseCode;
@@ -44,7 +44,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return_ty
             };
 
-        self.check_lhs_assignable(lhs, "E0067", op.span, |err| {
+        self.check_lhs_assignable(lhs, E0067, op.span, |err| {
             if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
                 if self
                     .lookup_op_method(
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index e31eeab4c4a..a611d0eda85 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -3,8 +3,8 @@ use crate::{errors, FnCtxt, LoweredTy};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    MultiSpan,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed, MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -576,7 +576,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if (lhs, rhs).references_error() {
             err.downgrade_to_delayed_bug();
         }
-        if self.tcx.sess.teach(&err.get_code().unwrap()) {
+        if self.tcx.sess.teach(err.get_code().unwrap()) {
             err.note(
                 "In a match expression, only numbers and characters can be matched \
                     against a range. This is because the compiler checks that the range \
@@ -847,7 +847,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 type_str
             );
             err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
-            if self.tcx.sess.teach(&err.get_code().unwrap()) {
+            if self.tcx.sess.teach(err.get_code().unwrap()) {
                 err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
             }
             return Err(err.emit());
@@ -907,7 +907,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => {
                 let expected = "unit struct, unit variant or constant";
-                let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected);
+                let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, E0533, expected);
                 return Ty::new_error(tcx, e);
             }
             Res::SelfCtor(..)
@@ -1061,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         let report_unexpected_res = |res: Res| {
             let expected = "tuple struct or tuple variant";
-            let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0164", expected);
+            let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, E0164, expected);
             on_error(e);
             e
         };
@@ -1669,7 +1669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
         }
-        if tcx.sess.teach(&err.get_code().unwrap()) {
+        if tcx.sess.teach(err.get_code().unwrap()) {
             err.note(
                 "This error indicates that a struct pattern attempted to \
                  extract a nonexistent field from a struct. Struct fields \
diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs
index d3cf267dc9d..0c1180b3e98 100644
--- a/compiler/rustc_index/src/interval.rs
+++ b/compiler/rustc_index/src/interval.rs
@@ -236,6 +236,12 @@ impl<I: Idx> IntervalSet<I> {
         I: Step,
     {
         assert_eq!(self.domain, other.domain);
+        if self.map.len() < other.map.len() {
+            let backup = self.clone();
+            self.map.clone_from(&other.map);
+            return self.union(&backup);
+        }
+
         let mut did_insert = false;
         for range in other.iter_intervals() {
             did_insert |= self.insert_range(range);
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index aee99063e03..4e9f573091b 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -1,7 +1,7 @@
 use hir::GenericParamKind;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString,
-    IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage,
+    DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
 };
 use rustc_hir as hir;
 use rustc_hir::FnRetTy;
@@ -33,7 +33,7 @@ pub struct OpaqueHiddenTypeDiag {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_type_annotations_needed, code = "E0282")]
+#[diag(infer_type_annotations_needed, code = E0282)]
 pub struct AnnotationRequired<'a> {
     #[primary_span]
     pub span: Span,
@@ -51,7 +51,7 @@ pub struct AnnotationRequired<'a> {
 
 // Copy of `AnnotationRequired` for E0283
 #[derive(Diagnostic)]
-#[diag(infer_type_annotations_needed, code = "E0283")]
+#[diag(infer_type_annotations_needed, code = E0283)]
 pub struct AmbiguousImpl<'a> {
     #[primary_span]
     pub span: Span,
@@ -69,7 +69,7 @@ pub struct AmbiguousImpl<'a> {
 
 // Copy of `AnnotationRequired` for E0284
 #[derive(Diagnostic)]
-#[diag(infer_type_annotations_needed, code = "E0284")]
+#[diag(infer_type_annotations_needed, code = E0284)]
 pub struct AmbiguousReturn<'a> {
     #[primary_span]
     pub span: Span,
@@ -421,7 +421,7 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_lifetime_mismatch, code = "E0623")]
+#[diag(infer_lifetime_mismatch, code = E0623)]
 pub struct LifetimeMismatch<'a> {
     #[primary_span]
     pub span: Span,
@@ -495,7 +495,7 @@ pub struct MismatchedStaticLifetime<'a> {
 
 #[derive(Diagnostic)]
 pub enum ExplicitLifetimeRequired<'a> {
-    #[diag(infer_explicit_lifetime_required_with_ident, code = "E0621")]
+    #[diag(infer_explicit_lifetime_required_with_ident, code = E0621)]
     WithIdent {
         #[primary_span]
         #[label]
@@ -511,7 +511,7 @@ pub enum ExplicitLifetimeRequired<'a> {
         #[skip_arg]
         new_ty: Ty<'a>,
     },
-    #[diag(infer_explicit_lifetime_required_with_param_type, code = "E0621")]
+    #[diag(infer_explicit_lifetime_required_with_param_type, code = E0621)]
     WithParamType {
         #[primary_span]
         #[label]
@@ -819,7 +819,7 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_but_calling_introduces, code = "E0772")]
+#[diag(infer_but_calling_introduces, code = E0772)]
 pub struct ButCallingIntroduces {
     #[label(infer_label1)]
     pub param_ty_span: Span,
@@ -871,14 +871,14 @@ impl AddToDiagnostic for MoreTargeted {
     where
         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
     {
-        diag.code(rustc_errors::error_code!(E0772));
+        diag.code(E0772);
         diag.primary_message(fluent::infer_more_targeted);
         diag.arg("ident", self.ident);
     }
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_but_needs_to_satisfy, code = "E0759")]
+#[diag(infer_but_needs_to_satisfy, code = E0759)]
 pub struct ButNeedsToSatisfy {
     #[primary_span]
     pub sp: Span,
@@ -904,7 +904,7 @@ pub struct ButNeedsToSatisfy {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_outlives_content, code = "E0312")]
+#[diag(infer_outlives_content, code = E0312)]
 pub struct OutlivesContent<'a> {
     #[primary_span]
     pub span: Span,
@@ -913,7 +913,7 @@ pub struct OutlivesContent<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_outlives_bound, code = "E0476")]
+#[diag(infer_outlives_bound, code = E0476)]
 pub struct OutlivesBound<'a> {
     #[primary_span]
     pub span: Span,
@@ -922,7 +922,7 @@ pub struct OutlivesBound<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_fulfill_req_lifetime, code = "E0477")]
+#[diag(infer_fulfill_req_lifetime, code = E0477)]
 pub struct FulfillReqLifetime<'a> {
     #[primary_span]
     pub span: Span,
@@ -932,7 +932,7 @@ pub struct FulfillReqLifetime<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_lf_bound_not_satisfied, code = "E0478")]
+#[diag(infer_lf_bound_not_satisfied, code = E0478)]
 pub struct LfBoundNotSatisfied<'a> {
     #[primary_span]
     pub span: Span,
@@ -941,7 +941,7 @@ pub struct LfBoundNotSatisfied<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_ref_longer_than_data, code = "E0491")]
+#[diag(infer_ref_longer_than_data, code = E0491)]
 pub struct RefLongerThanData<'a> {
     #[primary_span]
     pub span: Span,
@@ -1117,7 +1117,7 @@ pub enum PlaceholderRelationLfNotSatisfied {
 }
 
 #[derive(Diagnostic)]
-#[diag(infer_opaque_captures_lifetime, code = "E0700")]
+#[diag(infer_opaque_captures_lifetime, code = E0700)]
 pub struct OpaqueCapturesLifetime<'tcx> {
     #[primary_span]
     pub span: Span,
@@ -1378,73 +1378,73 @@ pub enum TypeErrorAdditionalDiags {
 
 #[derive(Diagnostic)]
 pub enum ObligationCauseFailureCode {
-    #[diag(infer_oc_method_compat, code = "E0308")]
+    #[diag(infer_oc_method_compat, code = E0308)]
     MethodCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_type_compat, code = "E0308")]
+    #[diag(infer_oc_type_compat, code = E0308)]
     TypeCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_const_compat, code = "E0308")]
+    #[diag(infer_oc_const_compat, code = E0308)]
     ConstCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_try_compat, code = "E0308")]
+    #[diag(infer_oc_try_compat, code = E0308)]
     TryCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_match_compat, code = "E0308")]
+    #[diag(infer_oc_match_compat, code = E0308)]
     MatchCompat {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_if_else_different, code = "E0308")]
+    #[diag(infer_oc_if_else_different, code = E0308)]
     IfElseDifferent {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_no_else, code = "E0317")]
+    #[diag(infer_oc_no_else, code = E0317)]
     NoElse {
         #[primary_span]
         span: Span,
     },
-    #[diag(infer_oc_no_diverge, code = "E0308")]
+    #[diag(infer_oc_no_diverge, code = E0308)]
     NoDiverge {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_fn_main_correct_type, code = "E0580")]
+    #[diag(infer_oc_fn_main_correct_type, code = E0580)]
     FnMainCorrectType {
         #[primary_span]
         span: Span,
     },
-    #[diag(infer_oc_fn_start_correct_type, code = "E0308")]
+    #[diag(infer_oc_fn_start_correct_type, code = E0308)]
     FnStartCorrectType {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_fn_lang_correct_type, code = "E0308")]
+    #[diag(infer_oc_fn_lang_correct_type, code = E0308)]
     FnLangCorrectType {
         #[primary_span]
         span: Span,
@@ -1452,33 +1452,33 @@ pub enum ObligationCauseFailureCode {
         subdiags: Vec<TypeErrorAdditionalDiags>,
         lang_item_name: Symbol,
     },
-    #[diag(infer_oc_intrinsic_correct_type, code = "E0308")]
+    #[diag(infer_oc_intrinsic_correct_type, code = E0308)]
     IntrinsicCorrectType {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_method_correct_type, code = "E0308")]
+    #[diag(infer_oc_method_correct_type, code = E0308)]
     MethodCorrectType {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_closure_selfref, code = "E0644")]
+    #[diag(infer_oc_closure_selfref, code = E0644)]
     ClosureSelfref {
         #[primary_span]
         span: Span,
     },
-    #[diag(infer_oc_cant_coerce, code = "E0308")]
+    #[diag(infer_oc_cant_coerce, code = E0308)]
     CantCoerce {
         #[primary_span]
         span: Span,
         #[subdiagnostic]
         subdiags: Vec<TypeErrorAdditionalDiags>,
     },
-    #[diag(infer_oc_generic, code = "E0308")]
+    #[diag(infer_oc_generic, code = E0308)]
     Generic {
         #[primary_span]
         span: Span,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 7882e761a0c..e19177fccef 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -60,7 +60,7 @@ use crate::traits::{
 
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_errors::{
-    error_code, pluralize, struct_span_code_err, Applicability, DiagCtxt, Diagnostic,
+    codes::*, pluralize, struct_span_code_err, Applicability, DiagCtxt, Diagnostic,
     DiagnosticBuilder, DiagnosticStyledString, ErrorGuaranteed, IntoDiagnosticArg,
 };
 use rustc_hir as hir;
@@ -2362,9 +2362,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             .dcx()
             .struct_span_err(span, format!("{labeled_user_string} may not live long enough"));
         err.code(match sub.kind() {
-            ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => error_code!(E0309),
-            ty::ReStatic => error_code!(E0310),
-            _ => error_code!(E0311),
+            ty::ReEarlyParam(_) | ty::ReLateParam(_) if sub.has_name() => E0309,
+            ty::ReStatic => E0310,
+            _ => E0311,
         });
 
         '_explain: {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 03c8e08aa01..cf1e042c529 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -5,7 +5,7 @@ use crate::errors::{
 use crate::infer::error_reporting::TypeErrCtxt;
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxt;
-use rustc_errors::{DiagnosticBuilder, IntoDiagnosticArg};
+use rustc_errors::{codes::*, DiagnosticBuilder, ErrCode, IntoDiagnosticArg};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def::{CtorOf, DefKind, Namespace};
@@ -43,12 +43,12 @@ pub enum TypeAnnotationNeeded {
     E0284,
 }
 
-impl Into<String> for TypeAnnotationNeeded {
-    fn into(self) -> String {
+impl Into<ErrCode> for TypeAnnotationNeeded {
+    fn into(self) -> ErrCode {
         match self {
-            Self::E0282 => rustc_errors::error_code!(E0282),
-            Self::E0283 => rustc_errors::error_code!(E0283),
-            Self::E0284 => rustc_errors::error_code!(E0284),
+            Self::E0282 => E0282,
+            Self::E0283 => E0283,
+            Self::E0284 => E0284,
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 21ea48c6c83..0e7c641e0e0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -195,7 +195,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             }
                         }
                         diag.help("type parameters must be constrained to match other types");
-                        if tcx.sess.teach(&diag.get_code().unwrap()) {
+                        if tcx.sess.teach(diag.get_code().unwrap()) {
                             diag.help(
                                 "given a type parameter `T` and a method `foo`:
 ```
@@ -678,7 +678,7 @@ impl<T> Trait<T> for X {
                  https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
             );
         }
-        if tcx.sess.teach(&diag.get_code().unwrap()) {
+        if tcx.sess.teach(diag.get_code().unwrap()) {
             diag.help(
                 "given an associated type `T` and a method `foo`:
 ```
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index 6f218019dee..eabc1b953af 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -2,7 +2,7 @@ use super::ObjectSafetyViolation;
 
 use crate::infer::InferCtxt;
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Map;
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
index 841d282a099..3bd0c1b8031 100644
--- a/compiler/rustc_lint/src/errors.rs
+++ b/compiler/rustc_lint/src/errors.rs
@@ -1,11 +1,11 @@
 use crate::fluent_generated as fluent;
-use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
+use rustc_errors::{codes::*, AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::lint::Level;
 use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
-#[diag(lint_overruled_attribute, code = "E0453")]
+#[diag(lint_overruled_attribute, code = E0453)]
 pub struct OverruledAttribute<'a> {
     #[primary_span]
     pub span: Span,
@@ -48,7 +48,7 @@ impl AddToDiagnostic for OverruledAttributeSub {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_malformed_attribute, code = "E0452")]
+#[diag(lint_malformed_attribute, code = E0452)]
 pub struct MalformedAttribute {
     #[primary_span]
     pub span: Span,
@@ -67,7 +67,7 @@ pub enum MalformedAttributeSub {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_unknown_tool_in_scoped_lint, code = "E0710")]
+#[diag(lint_unknown_tool_in_scoped_lint, code = E0710)]
 pub struct UnknownToolInScopedLint {
     #[primary_span]
     pub span: Option<Span>,
@@ -78,7 +78,7 @@ pub struct UnknownToolInScopedLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = "E0783")]
+#[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = E0783)]
 pub struct BuiltinEllipsisInclusiveRangePatterns {
     #[primary_span]
     pub span: Span,
@@ -95,13 +95,13 @@ pub struct RequestedLevel<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_unsupported_group, code = "E0602")]
+#[diag(lint_unsupported_group, code = E0602)]
 pub struct UnsupportedGroup {
     pub lint_group: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(lint_check_name_unknown_tool, code = "E0602")]
+#[diag(lint_check_name_unknown_tool, code = E0602)]
 pub struct CheckNameUnknownTool<'a> {
     pub tool_name: Symbol,
     #[subdiagnostic]
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index e19bb1cb62f..f916deb4a46 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -5,8 +5,8 @@ use std::num::NonZeroU32;
 use crate::errors::RequestedLevel;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder, DiagnosticMessage,
-    DiagnosticStyledString, SubdiagnosticMessage, SuggestionStyle,
+    codes::*, AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder,
+    DiagnosticMessage, DiagnosticStyledString, SubdiagnosticMessage, SuggestionStyle,
 };
 use rustc_hir::def_id::DefId;
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
@@ -1065,7 +1065,7 @@ pub enum UnknownLintSuggestion {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(lint_unknown_lint, code = "E0602")]
+#[diag(lint_unknown_lint, code = E0602)]
 pub struct UnknownLintFromCommandLine<'a> {
     pub name: String,
     #[subdiagnostic]
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 0b7ecff8148..85bb9584a05 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -209,9 +209,9 @@ impl DiagnosticDeriveVariantBuilder {
                 if path.is_ident("code") {
                     self.code.set_once((), path.span().unwrap());
 
-                    let code = nested.parse::<syn::LitStr>()?;
+                    let code = nested.parse::<syn::Expr>()?;
                     tokens.extend(quote! {
-                        diag.code(#code.to_string());
+                        diag.code(#code);
                     });
                 } else {
                     span_err(path.span().unwrap(), "unknown argument")
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 135b9e32fe7..33dffe6998a 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -20,7 +20,7 @@ use synstructure::Structure;
 /// # extern crate rust_middle;
 /// # use rustc_middle::ty::Ty;
 /// #[derive(Diagnostic)]
-/// #[diag(borrowck_move_out_of_borrow, code = "E0505")]
+/// #[diag(borrowck_move_out_of_borrow, code = E0505)]
 /// pub struct MoveOutOfBorrowError<'tcx> {
 ///     pub name: Ident,
 ///     pub ty: Ty<'tcx>,
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 27c26d31781..d17bf0cf708 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -4,7 +4,7 @@ use std::{
 };
 
 use rustc_errors::{
-    error_code, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
+    codes::*, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_macros::Diagnostic;
 use rustc_session::config;
@@ -122,7 +122,7 @@ pub struct WasmImportForm {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_empty_link_name, code = "E0454")]
+#[diag(metadata_empty_link_name, code = E0454)]
 pub struct EmptyLinkName {
     #[primary_span]
     #[label]
@@ -130,21 +130,21 @@ pub struct EmptyLinkName {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_link_framework_apple, code = "E0455")]
+#[diag(metadata_link_framework_apple, code = E0455)]
 pub struct LinkFrameworkApple {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_framework_only_windows, code = "E0455")]
+#[diag(metadata_framework_only_windows, code = E0455)]
 pub struct FrameworkOnlyWindows {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_unknown_link_kind, code = "E0458")]
+#[diag(metadata_unknown_link_kind, code = E0458)]
 pub struct UnknownLinkKind<'a> {
     #[primary_span]
     #[label]
@@ -239,7 +239,7 @@ pub struct IncompatibleWasmLink {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_link_requires_name, code = "E0459")]
+#[diag(metadata_link_requires_name, code = E0459)]
 pub struct LinkRequiresName {
     #[primary_span]
     #[label]
@@ -502,7 +502,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_multiple_candidates);
         diag.arg("crate_name", self.crate_name);
         diag.arg("flavor", self.flavor);
-        diag.code(error_code!(E0464));
+        diag.code(E0464);
         diag.span(self.span);
         for (i, candidate) in self.candidates.iter().enumerate() {
             diag.note(format!("candidate #{}: {}", i + 1, candidate.display()));
@@ -512,7 +512,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_symbol_conflicts_current, code = "E0519")]
+#[diag(metadata_symbol_conflicts_current, code = E0519)]
 pub struct SymbolConflictsCurrent {
     #[primary_span]
     pub span: Span,
@@ -537,7 +537,7 @@ pub struct DlError {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_newer_crate_version, code = "E0460")]
+#[diag(metadata_newer_crate_version, code = E0460)]
 #[note]
 #[note(metadata_found_crate_versions)]
 pub struct NewerCrateVersion {
@@ -549,7 +549,7 @@ pub struct NewerCrateVersion {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_no_crate_with_triple, code = "E0461")]
+#[diag(metadata_no_crate_with_triple, code = E0461)]
 #[note(metadata_found_crate_versions)]
 pub struct NoCrateWithTriple<'a> {
     #[primary_span]
@@ -561,7 +561,7 @@ pub struct NoCrateWithTriple<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_found_staticlib, code = "E0462")]
+#[diag(metadata_found_staticlib, code = E0462)]
 #[note(metadata_found_crate_versions)]
 #[help]
 pub struct FoundStaticlib {
@@ -573,7 +573,7 @@ pub struct FoundStaticlib {
 }
 
 #[derive(Diagnostic)]
-#[diag(metadata_incompatible_rustc, code = "E0514")]
+#[diag(metadata_incompatible_rustc, code = E0514)]
 #[note(metadata_found_crate_versions)]
 #[help]
 pub struct IncompatibleRustc {
@@ -598,7 +598,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for InvalidMetadataFiles {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::metadata_invalid_meta_files);
         diag.arg("crate_name", self.crate_name);
         diag.arg("add_info", self.add_info);
-        diag.code(error_code!(E0786));
+        diag.code(E0786);
         diag.span(self.span);
         for crate_rejection in self.crate_rejections {
             diag.note(crate_rejection);
@@ -627,7 +627,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for CannotFindCrate {
         diag.arg("current_crate", self.current_crate);
         diag.arg("add_info", self.add_info);
         diag.arg("locator_triple", self.locator_triple.triple());
-        diag.code(error_code!(E0463));
+        diag.code(E0463);
         diag.span(self.span);
         if (self.crate_name == sym::std || self.crate_name == sym::core)
             && self.locator_triple != TargetTriple::from_triple(config::host_triple())
diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs
index 3c553657087..e0436b38c4b 100644
--- a/compiler/rustc_middle/src/error.rs
+++ b/compiler/rustc_middle/src/error.rs
@@ -1,14 +1,14 @@
 use std::borrow::Cow;
 use std::fmt;
 
-use rustc_errors::{DiagnosticArgValue, DiagnosticMessage};
+use rustc_errors::{codes::*, DiagnosticArgValue, DiagnosticMessage};
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
 
 use crate::ty::Ty;
 
 #[derive(Diagnostic)]
-#[diag(middle_drop_check_overflow, code = "E0320")]
+#[diag(middle_drop_check_overflow, code = E0320)]
 #[note]
 pub struct DropCheckOverflow<'tcx> {
     #[primary_span]
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 6a03bf243eb..27b48f46e75 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -1,7 +1,7 @@
 use crate::dep_graph::dep_kinds;
 use crate::query::plumbing::CyclePlaceholder;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_middle::ty::Representability;
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index a7f6f4873e3..065c93e86a8 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -15,7 +15,9 @@
 use crate::build::expr::as_place::PlaceBuilder;
 use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
 use crate::build::Builder;
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_middle::thir::{self, *};
+use rustc_middle::ty;
 
 use std::mem;
 
@@ -149,7 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 ref subpattern,
                 ascription: thir::Ascription { ref annotation, variance },
             } => {
-                // Apply the type ascription to the value at `match_pair.place`, which is the
+                // Apply the type ascription to the value at `match_pair.place`
                 if let Some(source) = match_pair.place.try_to_place(self) {
                     candidate.ascriptions.push(Ascription {
                         annotation: annotation.clone(),
@@ -205,7 +207,38 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 Err(match_pair)
             }
 
-            PatKind::InlineConstant { subpattern: ref pattern, def: _ } => {
+            PatKind::InlineConstant { subpattern: ref pattern, def } => {
+                // Apply a type ascription for the inline constant to the value at `match_pair.place`
+                if let Some(source) = match_pair.place.try_to_place(self) {
+                    let span = match_pair.pattern.span;
+                    let parent_id = self.tcx.typeck_root_def_id(self.def_id.to_def_id());
+                    let args = ty::InlineConstArgs::new(
+                        self.tcx,
+                        ty::InlineConstArgsParts {
+                            parent_args: ty::GenericArgs::identity_for_item(self.tcx, parent_id),
+                            ty: self.infcx.next_ty_var(TypeVariableOrigin {
+                                kind: TypeVariableOriginKind::MiscVariable,
+                                span,
+                            }),
+                        },
+                    )
+                    .args;
+                    let user_ty =
+                        self.infcx.canonicalize_user_type_annotation(ty::UserType::TypeOf(
+                            def.to_def_id(),
+                            ty::UserArgs { args, user_self_ty: None },
+                        ));
+                    let annotation = ty::CanonicalUserTypeAnnotation {
+                        inferred_ty: pattern.ty,
+                        span,
+                        user_ty: Box::new(user_ty),
+                    };
+                    candidate.ascriptions.push(Ascription {
+                        annotation,
+                        source,
+                        variance: ty::Contravariant,
+                    });
+                }
                 candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
 
                 Ok(())
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index e1b998b2471..6929c8040c5 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1,7 +1,7 @@
 use crate::fluent_generated as fluent;
 use rustc_errors::DiagnosticArgValue;
 use rustc_errors::{
-    error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
     IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -138,7 +138,7 @@ pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = "E0133")]
+#[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)]
 #[note]
 pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
     #[primary_span]
@@ -150,7 +150,7 @@ pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")]
+#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)]
 #[note]
 pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
     #[primary_span]
@@ -161,7 +161,7 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
     #[primary_span]
@@ -175,7 +175,7 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
@@ -187,7 +187,7 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_inline_assembly_requires_unsafe, code = "E0133")]
+#[diag(mir_build_inline_assembly_requires_unsafe, code = E0133)]
 #[note]
 pub struct UseOfInlineAssemblyRequiresUnsafe {
     #[primary_span]
@@ -198,7 +198,7 @@ pub struct UseOfInlineAssemblyRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -209,7 +209,7 @@ pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_initializing_type_with_requires_unsafe, code = "E0133")]
+#[diag(mir_build_initializing_type_with_requires_unsafe, code = E0133)]
 #[note]
 pub struct InitializingTypeWithRequiresUnsafe {
     #[primary_span]
@@ -222,7 +222,7 @@ pub struct InitializingTypeWithRequiresUnsafe {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
@@ -234,7 +234,7 @@ pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_mutable_static_requires_unsafe, code = "E0133")]
+#[diag(mir_build_mutable_static_requires_unsafe, code = E0133)]
 #[note]
 pub struct UseOfMutableStaticRequiresUnsafe {
     #[primary_span]
@@ -245,7 +245,7 @@ pub struct UseOfMutableStaticRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -256,7 +256,7 @@ pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_extern_static_requires_unsafe, code = "E0133")]
+#[diag(mir_build_extern_static_requires_unsafe, code = E0133)]
 #[note]
 pub struct UseOfExternStaticRequiresUnsafe {
     #[primary_span]
@@ -267,7 +267,7 @@ pub struct UseOfExternStaticRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -278,7 +278,7 @@ pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = "E0133")]
+#[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)]
 #[note]
 pub struct DerefOfRawPointerRequiresUnsafe {
     #[primary_span]
@@ -289,7 +289,7 @@ pub struct DerefOfRawPointerRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -300,7 +300,7 @@ pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_union_field_requires_unsafe, code = "E0133")]
+#[diag(mir_build_union_field_requires_unsafe, code = E0133)]
 #[note]
 pub struct AccessToUnionFieldRequiresUnsafe {
     #[primary_span]
@@ -311,7 +311,7 @@ pub struct AccessToUnionFieldRequiresUnsafe {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[note]
 pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
     #[primary_span]
@@ -322,7 +322,7 @@ pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")]
+#[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = E0133)]
 #[note]
 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
     #[primary_span]
@@ -335,7 +335,7 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
@@ -347,7 +347,7 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllow
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")]
+#[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = E0133)]
 #[note]
 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
     #[primary_span]
@@ -360,7 +360,7 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
 #[derive(Diagnostic)]
 #[diag(
     mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
-    code = "E0133"
+    code = E0133
 )]
 #[note]
 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
@@ -372,7 +372,7 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_fn_with_requires_unsafe, code = "E0133")]
+#[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)]
 #[help]
 pub struct CallToFunctionWithRequiresUnsafe<'a> {
     #[primary_span]
@@ -390,7 +390,7 @@ pub struct CallToFunctionWithRequiresUnsafe<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
+#[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)]
 #[help]
 pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
     #[primary_span]
@@ -468,7 +468,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
             fluent::mir_build_non_exhaustive_patterns_type_not_empty,
         );
         diag.span(self.span);
-        diag.code(error_code!(E0004));
+        diag.code(E0004);
         let peeled_ty = self.ty.peel_refs();
         diag.arg("ty", self.ty);
         diag.arg("peeled_ty", peeled_ty);
@@ -539,28 +539,28 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
 pub struct NonExhaustiveMatchAllArmsGuarded;
 
 #[derive(Diagnostic)]
-#[diag(mir_build_static_in_pattern, code = "E0158")]
+#[diag(mir_build_static_in_pattern, code = E0158)]
 pub struct StaticInPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_assoc_const_in_pattern, code = "E0158")]
+#[diag(mir_build_assoc_const_in_pattern, code = E0158)]
 pub struct AssocConstInPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_const_param_in_pattern, code = "E0158")]
+#[diag(mir_build_const_param_in_pattern, code = E0158)]
 pub struct ConstParamInPattern {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_non_const_path, code = "E0080")]
+#[diag(mir_build_non_const_path, code = E0080)]
 pub struct NonConstPath {
     #[primary_span]
     pub span: Span,
@@ -590,7 +590,7 @@ pub struct CouldNotEvalConstPattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")]
+#[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = E0030)]
 pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
     #[primary_span]
     #[label]
@@ -611,7 +611,7 @@ pub struct LiteralOutOfRange<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")]
+#[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = E0579)]
 pub struct LowerRangeBoundMustBeLessThanUpper {
     #[primary_span]
     pub span: Span,
@@ -634,7 +634,7 @@ pub struct TrailingIrrefutableLetPatterns {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(mir_build_bindings_with_variant_name, code = "E0170")]
+#[diag(mir_build_bindings_with_variant_name, code = E0170)]
 pub struct BindingsWithVariantName {
     #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")]
     pub suggestion: Option<Span>,
@@ -821,7 +821,7 @@ pub struct NonPartialEqMatch<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_pattern_not_covered, code = "E0005")]
+#[diag(mir_build_pattern_not_covered, code = E0005)]
 pub(crate) struct PatternNotCovered<'s, 'tcx> {
     #[primary_span]
     pub span: Span,
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 435ea3dc3bb..caf7f4227db 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -11,7 +11,7 @@ use rustc_ast::Mutability;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
+    codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::*;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index ff7e985bdfd..2190ad14b55 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -8,7 +8,7 @@ pub(crate) use self::check_match::check_match;
 use crate::errors::*;
 use crate::thir::util::UserAnnotatedTyHelpers;
 
-use rustc_errors::error_code;
+use rustc_errors::codes::*;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
@@ -209,7 +209,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     RangeEnd::Included => {
                         self.tcx.dcx().emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper {
                             span,
-                            teach: self.tcx.sess.teach(&error_code!(E0030)).then_some(()),
+                            teach: self.tcx.sess.teach(E0030).then_some(()),
                         })
                     }
                     RangeEnd::Excluded => {
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 4574cb4d28d..4ef3d47d6a6 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -1,7 +1,7 @@
 use std::borrow::Cow;
 
 use rustc_errors::{
-    Applicability, DecorateLint, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder,
+    codes::*, Applicability, DecorateLint, DiagCtxt, DiagnosticArgValue, DiagnosticBuilder,
     DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, Level,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -33,7 +33,7 @@ pub(crate) enum ConstMutate {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_transform_unaligned_packed_ref, code = "E0793")]
+#[diag(mir_transform_unaligned_packed_ref, code = E0793)]
 #[note]
 #[note(mir_transform_note_ub)]
 #[help]
@@ -66,7 +66,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for RequiresUnsafe {
     #[track_caller]
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::mir_transform_requires_unsafe);
-        diag.code("E0133".to_string());
+        diag.code(E0133);
         diag.span(self.span);
         diag.span_label(self.span, self.details.label());
         let desc = dcx.eagerly_translate_to_string(self.details.label(), [].into_iter());
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index f904e0c44ea..aac8c0b3103 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -772,6 +772,20 @@ parse_unexpected_const_param_declaration = unexpected `const` parameter declarat
 parse_unexpected_default_value_for_lifetime_in_generic_parameters = unexpected default lifetime parameter
     .label = lifetime parameters cannot have default values
 
+parse_unexpected_expr_in_pat =
+    expected {$is_bound ->
+        [true] a pattern range bound
+       *[false] a pattern
+    }, found {$is_method_call ->
+        [true] a method call
+       *[false] an expression
+    }
+
+    .label = {$is_method_call ->
+        [true] method calls
+       *[false] arbitrary expressions
+    } are not allowed in patterns
+
 parse_unexpected_if_with_if = unexpected `if` in the condition expression
     .suggestion = remove the `if`
 
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 40852048293..4e4bf9bdad9 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -3,7 +3,7 @@ use std::borrow::Cow;
 use rustc_ast::token::Token;
 use rustc_ast::{Path, Visibility};
 use rustc_errors::{
-    AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
     SubdiagnosticMessage,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
@@ -25,7 +25,7 @@ pub(crate) struct AmbiguousPlus {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_maybe_recover_from_bad_type_plus, code = "E0178")]
+#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
 pub(crate) struct BadTypePlus {
     pub ty: String,
     #[primary_span]
@@ -807,7 +807,7 @@ pub(crate) struct InclusiveRangeMatchArrow {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_inclusive_range_no_end, code = "E0586")]
+#[diag(parse_inclusive_range_no_end, code = E0586)]
 #[note]
 pub(crate) struct InclusiveRangeNoEnd {
     #[primary_span]
@@ -901,7 +901,7 @@ pub(crate) struct MismatchedClosingDelimiter {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_incorrect_visibility_restriction, code = "E0704")]
+#[diag(parse_incorrect_visibility_restriction, code = E0704)]
 #[help]
 pub(crate) struct IncorrectVisibilityRestriction {
     #[primary_span]
@@ -925,7 +925,7 @@ pub(crate) struct ExpectedStatementAfterOuterAttr {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_doc_comment_does_not_document_anything, code = "E0585")]
+#[diag(parse_doc_comment_does_not_document_anything, code = E0585)]
 #[help]
 pub(crate) struct DocCommentDoesNotDocumentAnything {
     #[primary_span]
@@ -1357,7 +1357,7 @@ pub(crate) struct AttributeOnParamType {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_pattern_method_param_without_body, code = "E0642")]
+#[diag(parse_pattern_method_param_without_body, code = E0642)]
 pub(crate) struct PatternMethodParamWithoutBody {
     #[primary_span]
     #[suggestion(code = "_", applicability = "machine-applicable")]
@@ -1565,7 +1565,7 @@ pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_async_fn_in_2015, code = "E0670")]
+#[diag(parse_async_fn_in_2015, code = E0670)]
 pub(crate) struct AsyncFnIn2015 {
     #[primary_span]
     #[label]
@@ -1929,7 +1929,7 @@ pub struct CrDocComment {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_no_digits_literal, code = "E0768")]
+#[diag(parse_no_digits_literal, code = E0768)]
 pub struct NoDigitsLiteral {
     #[primary_span]
     pub span: Span,
@@ -2416,6 +2416,18 @@ pub(crate) struct ExpectedCommaAfterPatternField {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_unexpected_expr_in_pat)]
+pub(crate) struct UnexpectedExpressionInPattern {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    /// Was a `RangePatternBound` expected?
+    pub is_bound: bool,
+    /// Was the unexpected expression a `MethodCallExpression`?
+    pub is_method_call: bool,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_unexpected_paren_in_range_pat)]
 pub(crate) struct UnexpectedParenInRangePat {
     #[primary_span]
@@ -2499,7 +2511,7 @@ pub(crate) struct FnPointerCannotBeAsync {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_nested_c_variadic_type, code = "E0743")]
+#[diag(parse_nested_c_variadic_type, code = E0743)]
 pub(crate) struct NestedCVariadicType {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 20ec4a300c1..31552452676 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -7,7 +7,7 @@ use rustc_ast::ast::{self, AttrStyle};
 use rustc_ast::token::{self, CommentKind, Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::util::unicode::contains_text_flow_control_chars;
-use rustc_errors::{error_code, Applicability, DiagCtxt, DiagnosticBuilder, StashKey};
+use rustc_errors::{codes::*, Applicability, DiagCtxt, DiagnosticBuilder, StashKey};
 use rustc_lexer::unescape::{self, EscapeError, Mode};
 use rustc_lexer::{Base, DocStyle, RawStrError};
 use rustc_lexer::{Cursor, LiteralKind};
@@ -397,7 +397,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 if !terminated {
                     self.dcx()
                         .struct_span_fatal(self.mk_sp(start, end), "unterminated character literal")
-                        .with_code(error_code!(E0762))
+                        .with_code(E0762)
                         .emit()
                 }
                 self.cook_unicode(token::Char, Mode::Char, start, end, 1, 1) // ' '
@@ -409,7 +409,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start + BytePos(1), end),
                             "unterminated byte constant",
                         )
-                        .with_code(error_code!(E0763))
+                        .with_code(E0763)
                         .emit()
                 }
                 self.cook_unicode(token::Byte, Mode::Byte, start, end, 2, 1) // b' '
@@ -421,7 +421,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start, end),
                             "unterminated double quote string",
                         )
-                        .with_code(error_code!(E0765))
+                        .with_code(E0765)
                         .emit()
                 }
                 self.cook_unicode(token::Str, Mode::Str, start, end, 1, 1) // " "
@@ -433,7 +433,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start + BytePos(1), end),
                             "unterminated double quote byte string",
                         )
-                        .with_code(error_code!(E0766))
+                        .with_code(E0766)
                         .emit()
                 }
                 self.cook_unicode(token::ByteStr, Mode::ByteStr, start, end, 2, 1) // b" "
@@ -445,7 +445,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                             self.mk_sp(start + BytePos(1), end),
                             "unterminated C string",
                         )
-                        .with_code(error_code!(E0767))
+                        .with_code(E0767)
                         .emit()
                 }
                 self.cook_mixed(token::CStr, Mode::CStr, start, end, 2, 1) // c" "
@@ -582,7 +582,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
     ) -> ! {
         let mut err =
             self.dcx().struct_span_fatal(self.mk_sp(start, start), "unterminated raw string");
-        err.code(error_code!(E0748));
+        err.code(E0748);
         err.span_label(self.mk_sp(start, start), "unterminated raw string");
 
         if n_hashes > 0 {
@@ -614,7 +614,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
         };
         let last_bpos = self.pos;
         let mut err = self.dcx().struct_span_fatal(self.mk_sp(start, last_bpos), msg);
-        err.code(error_code!(E0758));
+        err.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();
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index a92609c2c2f..98e062dd784 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -8,7 +8,7 @@ use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle
 use rustc_ast as ast;
 use rustc_ast::attr;
 use rustc_ast::token::{self, Delimiter, Nonterminal};
-use rustc_errors::{error_code, Diagnostic, PResult};
+use rustc_errors::{codes::*, Diagnostic, PResult};
 use rustc_span::{sym, BytePos, Span};
 use thin_vec::ThinVec;
 use tracing::debug;
@@ -61,7 +61,7 @@ impl<'a> Parser<'a> {
                     let mut err = self
                         .dcx()
                         .struct_span_err(span, fluent::parse_inner_doc_comment_not_permitted);
-                    err.code(error_code!(E0753));
+                    err.code(E0753);
                     if let Some(replacement_span) = self.annotate_following_item_if_applicable(
                         &mut err,
                         span,
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index b789b65797b..c395decab12 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -444,6 +444,19 @@ impl<'a> Parser<'a> {
             ) if self.restrictions.contains(Restrictions::CONST_EXPR) => {
                 return None;
             }
+            // When recovering patterns as expressions, stop parsing when encountering an assignment `=`, an alternative `|`, or a range `..`.
+            (
+                Some(
+                    AssocOp::Assign
+                    | AssocOp::AssignOp(_)
+                    | AssocOp::BitOr
+                    | AssocOp::DotDot
+                    | AssocOp::DotDotEq,
+                ),
+                _,
+            ) if self.restrictions.contains(Restrictions::IS_PAT) => {
+                return None;
+            }
             (Some(op), _) => (op, self.token.span),
             (None, Some((Ident { name: sym::and, span }, false))) if self.may_recover() => {
                 self.dcx().emit_err(errors::InvalidLogicalOperator {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 3bd8ae02586..9a77643f951 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -10,7 +10,7 @@ use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
 use rustc_ast::util::case::Case;
 use rustc_ast::{self as ast};
 use rustc_ast_pretty::pprust;
-use rustc_errors::{struct_span_code_err, Applicability, PResult, StashKey};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability, PResult, StashKey};
 use rustc_span::edit_distance::edit_distance;
 use rustc_span::edition::Edition;
 use rustc_span::source_map;
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index ff2fb6271a8..623407eb380 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -53,6 +53,7 @@ bitflags::bitflags! {
         const CONST_EXPR        = 1 << 2;
         const ALLOW_LET         = 1 << 3;
         const IN_IF_GUARD       = 1 << 4;
+        const IS_PAT            = 1 << 5;
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 7918e03750c..d04921dde54 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,4 +1,4 @@
-use super::{ForceCollect, Parser, PathStyle, TrailingToken};
+use super::{ForceCollect, Parser, PathStyle, Restrictions, TrailingToken};
 use crate::errors::{
     self, AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed,
     DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt,
@@ -6,14 +6,14 @@ use crate::errors::{
     InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern,
     PatternOnWrongSideOfAt, RefMutOrderIncorrect, RemoveLet, RepeatedMutInPattern,
     SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg,
-    TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat,
-    UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam,
-    UnexpectedVertVertInPattern,
+    TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedLifetimeInPattern,
+    UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
+    UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern,
 };
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, Delimiter};
+use rustc_ast::token::{self, BinOpToken, Delimiter, Token};
 use rustc_ast::{
     self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
     PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
@@ -23,7 +23,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use thin_vec::{thin_vec, ThinVec};
 
 #[derive(PartialEq, Copy, Clone)]
@@ -336,6 +336,95 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Ensures that the last parsed pattern (or pattern range bound) is not followed by a method call or an operator.
+    ///
+    /// `is_end_bound` indicates whether the last parsed thing was the end bound of a range pattern (see [`parse_pat_range_end`](Self::parse_pat_range_end))
+    /// in order to say "expected a pattern range bound" instead of "expected a pattern";
+    /// ```text
+    /// 0..=1 + 2
+    ///     ^^^^^
+    /// ```
+    /// Only the end bound is spanned, and this function have no idea if there were a `..=` before `pat_span`, hence the parameter.
+    #[must_use = "the pattern must be discarded as `PatKind::Err` if this function returns Some"]
+    fn maybe_recover_trailing_expr(
+        &mut self,
+        pat_span: Span,
+        is_end_bound: bool,
+    ) -> Option<ErrorGuaranteed> {
+        if self.prev_token.is_keyword(kw::Underscore) || !self.may_recover() {
+            // Don't recover anything after an `_` or if recovery is disabled.
+            return None;
+        }
+
+        // Check for `.hello()`, but allow `.Hello()` to be recovered as `, Hello()` in `parse_seq_to_before_tokens()`.
+        let has_trailing_method = self.check_noexpect(&token::Dot)
+            && self.look_ahead(1, |tok| {
+                tok.ident()
+                    .and_then(|(ident, _)| ident.name.as_str().chars().next())
+                    .is_some_and(char::is_lowercase)
+            })
+            && self.look_ahead(2, |tok| tok.kind == token::OpenDelim(Delimiter::Parenthesis));
+
+        // Check for operators.
+        // `|` is excluded as it is used in pattern alternatives and lambdas,
+        // `?` is included for error propagation,
+        // `[` is included for indexing operations,
+        // `[]` is excluded as `a[]` isn't an expression and should be recovered as `a, []` (cf. `tests/ui/parser/pat-lt-bracket-7.rs`)
+        let has_trailing_operator = matches!(self.token.kind, token::BinOp(op) if op != BinOpToken::Or)
+            || self.token.kind == token::Question
+            || (self.token.kind == token::OpenDelim(Delimiter::Bracket)
+                && self.look_ahead(1, |tok| tok.kind != token::CloseDelim(Delimiter::Bracket)));
+
+        if !has_trailing_method && !has_trailing_operator {
+            // Nothing to recover here.
+            return None;
+        }
+
+        // Let's try to parse an expression to emit a better diagnostic.
+        let mut snapshot = self.create_snapshot_for_diagnostic();
+        snapshot.restrictions.insert(Restrictions::IS_PAT);
+
+        // Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten.
+        if let Ok(expr) = snapshot
+            .parse_expr_dot_or_call_with(
+                self.mk_expr_err(pat_span), // equivalent to transforming the parsed pattern into an `Expr`
+                pat_span,
+                AttrVec::new(),
+            )
+            .map_err(|err| err.cancel())
+        {
+            let non_assoc_span = expr.span;
+
+            // Parse an associative expression such as `+ expr`, `% expr`, ...
+            // Assignements, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
+            if let Ok(expr) =
+                snapshot.parse_expr_assoc_with(0, expr.into()).map_err(|err| err.cancel())
+            {
+                // We got a valid expression.
+                self.restore_snapshot(snapshot);
+                self.restrictions.remove(Restrictions::IS_PAT);
+
+                let is_bound = is_end_bound
+                    // is_start_bound: either `..` or `)..`
+                    || self.token.is_range_separator()
+                    || self.token.kind == token::CloseDelim(Delimiter::Parenthesis)
+                        && self.look_ahead(1, Token::is_range_separator);
+
+                // Check that `parse_expr_assoc_with` didn't eat a rhs.
+                let is_method_call = has_trailing_method && non_assoc_span == expr.span;
+
+                return Some(self.dcx().emit_err(UnexpectedExpressionInPattern {
+                    span: expr.span,
+                    is_bound,
+                    is_method_call,
+                }));
+            }
+        }
+
+        // We got a trailing method/operator, but we couldn't parse an expression.
+        None
+    }
+
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
     /// allowed).
     fn parse_pat_with_range_pat(
@@ -441,7 +530,10 @@ impl<'a> Parser<'a> {
             } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
                 self.parse_pat_tuple_struct(qself, path)?
             } else {
-                PatKind::Path(qself, path)
+                match self.maybe_recover_trailing_expr(span, false) {
+                    Some(guar) => PatKind::Err(guar),
+                    None => PatKind::Path(qself, path),
+                }
             }
         } else if matches!(self.token.kind, token::Lifetime(_))
             // In pattern position, we're totally fine with using "next token isn't colon"
@@ -470,10 +562,17 @@ impl<'a> Parser<'a> {
         } else {
             // Try to parse everything else as literal with optional minus
             match self.parse_literal_maybe_minus() {
-                Ok(begin) => match self.parse_range_end() {
-                    Some(form) => self.parse_pat_range_begin_with(begin, form)?,
-                    None => PatKind::Lit(begin),
-                },
+                Ok(begin) => {
+                    let begin = match self.maybe_recover_trailing_expr(begin.span, false) {
+                        Some(_) => self.mk_expr_err(begin.span),
+                        None => begin,
+                    };
+
+                    match self.parse_range_end() {
+                        Some(form) => self.parse_pat_range_begin_with(begin, form)?,
+                        None => PatKind::Lit(begin),
+                    }
+                }
                 Err(err) => return self.fatal_unexpected_non_pat(err, expected),
             }
         };
@@ -615,6 +714,21 @@ impl<'a> Parser<'a> {
 
                     self.parse_pat_range_begin_with(begin.clone(), form)?
                 }
+                // recover ranges with parentheses around the `(start)..`
+                PatKind::Err(_)
+                    if self.may_recover()
+                        && let Some(form) = self.parse_range_end() =>
+                {
+                    self.dcx().emit_err(UnexpectedParenInRangePat {
+                        span: vec![open_paren, close_paren],
+                        sugg: UnexpectedParenInRangePatSugg {
+                            start_span: open_paren,
+                            end_span: close_paren,
+                        },
+                    });
+
+                    self.parse_pat_range_begin_with(self.mk_expr(pat.span, ExprKind::Err), form)?
+                }
 
                 // (pat) with optional parentheses
                 _ => PatKind::Paren(pat),
@@ -853,6 +967,8 @@ impl<'a> Parser<'a> {
             self.parse_literal_maybe_minus()
         }?;
 
+        let recovered = self.maybe_recover_trailing_expr(bound.span, true);
+
         // recover trailing `)`
         if let Some(open_paren) = open_paren {
             self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
@@ -866,7 +982,10 @@ impl<'a> Parser<'a> {
             });
         }
 
-        Ok(bound)
+        Ok(match recovered {
+            Some(_) => self.mk_expr_err(bound.span),
+            None => bound,
+        })
     }
 
     /// Is this the start of a pattern beginning with a path?
@@ -929,7 +1048,17 @@ impl<'a> Parser<'a> {
                 .create_err(EnumPatternInsteadOfIdentifier { span: self.prev_token.span }));
         }
 
-        Ok(PatKind::Ident(binding_annotation, ident, sub))
+        // Check for method calls after the `ident`,
+        // but not `ident @ subpat` as `subpat` was already checked and `ident` continues with `@`.
+
+        let pat = if sub.is_none()
+            && let Some(guar) = self.maybe_recover_trailing_expr(ident.span, false)
+        {
+            PatKind::Err(guar)
+        } else {
+            PatKind::Ident(binding_annotation, ident, sub)
+        };
+        Ok(pat)
     }
 
     /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`).
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 25ca685cbfa..97c70e327f0 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,6 +1,6 @@
 use rustc_ast::attr;
 use rustc_ast::entry::EntryPointType;
-use rustc_errors::error_code;
+use rustc_errors::codes::*;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::{ItemId, Node, CRATE_HIR_ID};
@@ -180,8 +180,8 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
         Default::default()
     });
     let main_def_opt = tcx.resolutions(()).main_def;
-    let code = error_code!(E0601);
-    let add_teach_note = tcx.sess.teach(&code);
+    let code = E0601;
+    let add_teach_note = tcx.sess.teach(code);
     // The file may be empty, which leads to the diagnostic machinery not emitting this
     // note. This is a relatively simple way to detect that case and emit a span-less
     // note instead.
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index cf3c7cc4ace..77bfe57e370 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -6,7 +6,7 @@ use std::{
 use crate::fluent_generated as fluent;
 use rustc_ast::Label;
 use rustc_errors::{
-    error_code, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
     DiagnosticSymbolList, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan,
 };
 use rustc_hir::{self as hir, ExprKind, Target};
@@ -55,7 +55,7 @@ pub struct IgnoredInlineAttrFnProto;
 pub struct IgnoredInlineAttrConstants;
 
 #[derive(Diagnostic)]
-#[diag(passes_inline_not_fn_or_closure, code = "E0518")]
+#[diag(passes_inline_not_fn_or_closure, code = E0518)]
 pub struct InlineNotFnOrClosure {
     #[primary_span]
     pub attr_span: Span,
@@ -76,7 +76,7 @@ pub struct IgnoredCoveragePropagate;
 pub struct IgnoredCoverageFnDefn;
 
 #[derive(Diagnostic)]
-#[diag(passes_coverage_not_coverable, code = "E0788")]
+#[diag(passes_coverage_not_coverable, code = E0788)]
 pub struct IgnoredCoverageNotCoverable {
     #[primary_span]
     pub attr_span: Span,
@@ -95,14 +95,14 @@ pub struct AttrShouldBeAppliedToFn {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_tracked_caller, code = "E0736")]
+#[diag(passes_naked_tracked_caller, code = E0736)]
 pub struct NakedTrackedCaller {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_fn, code = "E0739")]
+#[diag(passes_should_be_applied_to_fn, code = E0739)]
 pub struct TrackedCallerWrongLocation {
     #[primary_span]
     pub attr_span: Span,
@@ -112,7 +112,7 @@ pub struct TrackedCallerWrongLocation {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_should_be_applied_to_struct_enum, code = "E0701")]
+#[diag(passes_should_be_applied_to_struct_enum, code = E0701)]
 pub struct NonExhaustiveWrongLocation {
     #[primary_span]
     pub attr_span: Span,
@@ -370,28 +370,28 @@ pub struct HasIncoherentInherentImpl {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_both_ffi_const_and_pure, code = "E0757")]
+#[diag(passes_both_ffi_const_and_pure, code = E0757)]
 pub struct BothFfiConstAndPure {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_ffi_pure_invalid_target, code = "E0755")]
+#[diag(passes_ffi_pure_invalid_target, code = E0755)]
 pub struct FfiPureInvalidTarget {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_ffi_const_invalid_target, code = "E0756")]
+#[diag(passes_ffi_const_invalid_target, code = E0756)]
 pub struct FfiConstInvalidTarget {
     #[primary_span]
     pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_ffi_returns_twice_invalid_target, code = "E0724")]
+#[diag(passes_ffi_returns_twice_invalid_target, code = E0724)]
 pub struct FfiReturnsTwiceInvalidTarget {
     #[primary_span]
     pub attr_span: Span,
@@ -552,21 +552,21 @@ pub struct NoMangle {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_repr_ident, code = "E0565")]
+#[diag(passes_repr_ident, code = E0565)]
 pub struct ReprIdent {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_repr_conflicting, code = "E0566")]
+#[diag(passes_repr_conflicting, code = E0566)]
 pub struct ReprConflicting {
     #[primary_span]
     pub hint_spans: Vec<Span>,
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_repr_conflicting, code = "E0566")]
+#[diag(passes_repr_conflicting, code = E0566)]
 pub struct ReprConflictingLint;
 
 #[derive(Diagnostic)]
@@ -667,7 +667,7 @@ pub(crate) struct EmptyConfusables {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_incorrect_meta_item, code = "E0539")]
+#[diag(passes_incorrect_meta_item, code = E0539)]
 pub(crate) struct IncorrectMetaItem {
     #[primary_span]
     pub span: Span,
@@ -737,7 +737,7 @@ pub struct Unused {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_non_exported_macro_invalid_attrs, code = "E0518")]
+#[diag(passes_non_exported_macro_invalid_attrs, code = E0518)]
 pub struct NonExportedMacroInvalidAttrs {
     #[primary_span]
     #[label]
@@ -801,7 +801,7 @@ pub struct DeprecatedAnnotationHasNoEffect {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unknown_external_lang_item, code = "E0264")]
+#[diag(passes_unknown_external_lang_item, code = E0264)]
 pub struct UnknownExternLangItem {
     #[primary_span]
     pub span: Span,
@@ -837,7 +837,7 @@ pub struct LangItemWithTargetFeature {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_lang_item_on_incorrect_target, code = "E0718")]
+#[diag(passes_lang_item_on_incorrect_target, code = E0718)]
 pub struct LangItemOnIncorrectTarget {
     #[primary_span]
     #[label]
@@ -848,7 +848,7 @@ pub struct LangItemOnIncorrectTarget {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unknown_lang_item, code = "E0522")]
+#[diag(passes_unknown_lang_item, code = E0522)]
 pub struct UnknownLangItem {
     #[primary_span]
     #[label]
@@ -990,7 +990,7 @@ pub struct UnrecognizedField {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_feature_stable_twice, code = "E0711")]
+#[diag(passes_feature_stable_twice, code = E0711)]
 pub struct FeatureStableTwice {
     #[primary_span]
     pub span: Span,
@@ -1000,7 +1000,7 @@ pub struct FeatureStableTwice {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_feature_previously_declared, code = "E0711")]
+#[diag(passes_feature_previously_declared, code = E0711)]
 pub struct FeaturePreviouslyDeclared<'a, 'b> {
     #[primary_span]
     pub span: Span,
@@ -1025,7 +1025,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> {
     fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_break_non_loop);
         diag.span(self.span);
-        diag.code(error_code!(E0571));
+        diag.code(E0571);
         diag.arg("kind", self.kind);
         diag.span_label(self.span, fluent::passes_label);
         if let Some(head) = self.head {
@@ -1063,7 +1063,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'_, G> for BreakNonLoop<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_continue_labeled_block, code = "E0696")]
+#[diag(passes_continue_labeled_block, code = E0696)]
 pub struct ContinueLabeledBlock {
     #[primary_span]
     #[label]
@@ -1073,7 +1073,7 @@ pub struct ContinueLabeledBlock {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_break_inside_closure, code = "E0267")]
+#[diag(passes_break_inside_closure, code = E0267)]
 pub struct BreakInsideClosure<'a> {
     #[primary_span]
     #[label]
@@ -1084,7 +1084,7 @@ pub struct BreakInsideClosure<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_break_inside_async_block, code = "E0267")]
+#[diag(passes_break_inside_async_block, code = E0267)]
 pub struct BreakInsideAsyncBlock<'a> {
     #[primary_span]
     #[label]
@@ -1095,7 +1095,7 @@ pub struct BreakInsideAsyncBlock<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_outside_loop, code = "E0268")]
+#[diag(passes_outside_loop, code = E0268)]
 pub struct OutsideLoop<'a> {
     #[primary_span]
     #[label]
@@ -1115,7 +1115,7 @@ pub struct OutsideLoopSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unlabeled_in_labeled_block, code = "E0695")]
+#[diag(passes_unlabeled_in_labeled_block, code = E0695)]
 pub struct UnlabeledInLabeledBlock<'a> {
     #[primary_span]
     #[label]
@@ -1124,7 +1124,7 @@ pub struct UnlabeledInLabeledBlock<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unlabeled_cf_in_while_condition, code = "E0590")]
+#[diag(passes_unlabeled_cf_in_while_condition, code = E0590)]
 pub struct UnlabeledCfInWhileCondition<'a> {
     #[primary_span]
     #[label]
@@ -1169,7 +1169,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for NakedFunctionsAsmBlock {
     fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_naked_functions_asm_block);
         diag.span(self.span);
-        diag.code(error_code!(E0787));
+        diag.code(E0787);
         for span in self.multiple_asms.iter() {
             diag.span_label(*span, fluent::passes_label_multiple_asm);
         }
@@ -1181,14 +1181,14 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for NakedFunctionsAsmBlock {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_operands, code = "E0787")]
+#[diag(passes_naked_functions_operands, code = E0787)]
 pub struct NakedFunctionsOperands {
     #[primary_span]
     pub unsupported_operands: Vec<Span>,
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_asm_options, code = "E0787")]
+#[diag(passes_naked_functions_asm_options, code = E0787)]
 pub struct NakedFunctionsAsmOptions {
     #[primary_span]
     pub span: Span,
@@ -1196,7 +1196,7 @@ pub struct NakedFunctionsAsmOptions {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_must_use_noreturn, code = "E0787")]
+#[diag(passes_naked_functions_must_use_noreturn, code = E0787)]
 pub struct NakedFunctionsMustUseNoreturn {
     #[primary_span]
     pub span: Span,
@@ -1229,7 +1229,7 @@ pub struct AttrOnlyInFunctions {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_multiple_rustc_main, code = "E0137")]
+#[diag(passes_multiple_rustc_main, code = E0137)]
 pub struct MultipleRustcMain {
     #[primary_span]
     pub span: Span,
@@ -1240,7 +1240,7 @@ pub struct MultipleRustcMain {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_multiple_start_functions, code = "E0138")]
+#[diag(passes_multiple_start_functions, code = E0138)]
 pub struct MultipleStartFunctions {
     #[primary_span]
     pub span: Span,
@@ -1280,7 +1280,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for NoMainErr {
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
         let mut diag = DiagnosticBuilder::new(dcx, level, fluent::passes_no_main_function);
         diag.span(DUMMY_SP);
-        diag.code(error_code!(E0601));
+        diag.code(E0601);
         diag.arg("crate_name", self.crate_name);
         diag.arg("filename", self.filename);
         diag.arg("has_filename", self.has_filename);
@@ -1345,7 +1345,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for DuplicateLangItem {
                 Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends,
             },
         );
-        diag.code(error_code!(E0152));
+        diag.code(E0152);
         diag.arg("lang_item_name", self.lang_item_name);
         diag.arg("crate_name", self.crate_name);
         diag.arg("dependency_of", self.dependency_of);
@@ -1382,7 +1382,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for DuplicateLangItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_incorrect_target, code = "E0718")]
+#[diag(passes_incorrect_target, code = E0718)]
 pub struct IncorrectTarget<'a> {
     #[primary_span]
     pub span: Span,
@@ -1418,7 +1418,7 @@ pub struct ObjectLifetimeErr {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unrecognized_repr_hint, code = "E0552")]
+#[diag(passes_unrecognized_repr_hint, code = E0552)]
 #[help]
 pub struct UnrecognizedReprHint {
     #[primary_span]
@@ -1427,35 +1427,35 @@ pub struct UnrecognizedReprHint {
 
 #[derive(Diagnostic)]
 pub enum AttrApplication {
-    #[diag(passes_attr_application_enum, code = "E0517")]
+    #[diag(passes_attr_application_enum, code = E0517)]
     Enum {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct, code = "E0517")]
+    #[diag(passes_attr_application_struct, code = E0517)]
     Struct {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_union, code = "E0517")]
+    #[diag(passes_attr_application_struct_union, code = E0517)]
     StructUnion {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_enum_union, code = "E0517")]
+    #[diag(passes_attr_application_struct_enum_union, code = E0517)]
     StructEnumUnion {
         #[primary_span]
         hint_span: Span,
         #[label]
         span: Span,
     },
-    #[diag(passes_attr_application_struct_enum_function_method_union, code = "E0517")]
+    #[diag(passes_attr_application_struct_enum_function_method_union, code = E0517)]
     StructEnumFunctionMethodUnion {
         #[primary_span]
         hint_span: Span,
@@ -1465,7 +1465,7 @@ pub enum AttrApplication {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_transparent_incompatible, code = "E0692")]
+#[diag(passes_transparent_incompatible, code = E0692)]
 pub struct TransparentIncompatible {
     #[primary_span]
     pub hint_spans: Vec<Span>,
@@ -1473,7 +1473,7 @@ pub struct TransparentIncompatible {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_deprecated_attribute, code = "E0549")]
+#[diag(passes_deprecated_attribute, code = E0549)]
 pub struct DeprecatedAttribute {
     #[primary_span]
     pub span: Span,
@@ -1524,7 +1524,7 @@ pub struct TraitImplConstStable {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_feature_only_on_nightly, code = "E0554")]
+#[diag(passes_feature_only_on_nightly, code = E0554)]
 pub struct FeatureOnlyOnNightly {
     #[primary_span]
     pub span: Span,
@@ -1532,7 +1532,7 @@ pub struct FeatureOnlyOnNightly {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unknown_feature, code = "E0635")]
+#[diag(passes_unknown_feature, code = E0635)]
 pub struct UnknownFeature {
     #[primary_span]
     pub span: Span,
@@ -1549,7 +1549,7 @@ pub struct ImpliedFeatureNotExist {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_duplicate_feature_err, code = "E0636")]
+#[diag(passes_duplicate_feature_err, code = E0636)]
 pub struct DuplicateFeatureErr {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_pattern_analysis/Cargo.toml b/compiler/rustc_pattern_analysis/Cargo.toml
index 1d0e1cb7e6a..b9bdcb41929 100644
--- a/compiler/rustc_pattern_analysis/Cargo.toml
+++ b/compiler/rustc_pattern_analysis/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
-derivative = "2.2.0"
 rustc-hash = "1.1.0"
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena", optional = true }
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index e94a0373c79..4996015f863 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -151,6 +151,7 @@
 use std::cmp::{self, max, min, Ordering};
 use std::fmt;
 use std::iter::once;
+use std::mem;
 
 use smallvec::SmallVec;
 
@@ -648,8 +649,6 @@ impl OpaqueId {
 /// `specialize_constructor` returns the list of fields corresponding to a pattern, given a
 /// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
 /// `Fields`.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""), PartialEq(bound = ""))]
 pub enum Constructor<Cx: TypeCx> {
     /// Tuples and structs.
     Struct,
@@ -692,6 +691,101 @@ pub enum Constructor<Cx: TypeCx> {
     Missing,
 }
 
+impl<Cx: TypeCx> Clone for Constructor<Cx> {
+    fn clone(&self) -> Self {
+        match self {
+            Constructor::Struct => Constructor::Struct,
+            Constructor::Variant(idx) => Constructor::Variant(idx.clone()),
+            Constructor::Ref => Constructor::Ref,
+            Constructor::Slice(slice) => Constructor::Slice(slice.clone()),
+            Constructor::UnionField => Constructor::UnionField,
+            Constructor::Bool(b) => Constructor::Bool(b.clone()),
+            Constructor::IntRange(range) => Constructor::IntRange(range.clone()),
+            Constructor::F32Range(lo, hi, end) => {
+                Constructor::F32Range(lo.clone(), hi.clone(), end.clone())
+            }
+            Constructor::F64Range(lo, hi, end) => {
+                Constructor::F64Range(lo.clone(), hi.clone(), end.clone())
+            }
+            Constructor::Str(value) => Constructor::Str(value.clone()),
+            Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
+            Constructor::Or => Constructor::Or,
+            Constructor::Wildcard => Constructor::Wildcard,
+            Constructor::NonExhaustive => Constructor::NonExhaustive,
+            Constructor::Hidden => Constructor::Hidden,
+            Constructor::Missing => Constructor::Missing,
+        }
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for Constructor<Cx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Constructor::Struct => f.debug_tuple("Struct").finish(),
+            Constructor::Variant(idx) => f.debug_tuple("Variant").field(idx).finish(),
+            Constructor::Ref => f.debug_tuple("Ref").finish(),
+            Constructor::Slice(slice) => f.debug_tuple("Slice").field(slice).finish(),
+            Constructor::UnionField => f.debug_tuple("UnionField").finish(),
+            Constructor::Bool(b) => f.debug_tuple("Bool").field(b).finish(),
+            Constructor::IntRange(range) => f.debug_tuple("IntRange").field(range).finish(),
+            Constructor::F32Range(lo, hi, end) => {
+                f.debug_tuple("F32Range").field(lo).field(hi).field(end).finish()
+            }
+            Constructor::F64Range(lo, hi, end) => {
+                f.debug_tuple("F64Range").field(lo).field(hi).field(end).finish()
+            }
+            Constructor::Str(value) => f.debug_tuple("Str").field(value).finish(),
+            Constructor::Opaque(inner) => f.debug_tuple("Opaque").field(inner).finish(),
+            Constructor::Or => f.debug_tuple("Or").finish(),
+            Constructor::Wildcard => f.debug_tuple("Wildcard").finish(),
+            Constructor::NonExhaustive => f.debug_tuple("NonExhaustive").finish(),
+            Constructor::Hidden => f.debug_tuple("Hidden").finish(),
+            Constructor::Missing => f.debug_tuple("Missing").finish(),
+        }
+    }
+}
+
+impl<Cx: TypeCx> PartialEq for Constructor<Cx> {
+    fn eq(&self, other: &Self) -> bool {
+        (mem::discriminant(self) == mem::discriminant(other))
+            && match (self, other) {
+                (Constructor::Struct, Constructor::Struct) => true,
+                (Constructor::Variant(self_variant), Constructor::Variant(other_variant)) => {
+                    self_variant == other_variant
+                }
+                (Constructor::Ref, Constructor::Ref) => true,
+                (Constructor::Slice(self_slice), Constructor::Slice(other_slice)) => {
+                    self_slice == other_slice
+                }
+                (Constructor::UnionField, Constructor::UnionField) => true,
+                (Constructor::Bool(self_b), Constructor::Bool(other_b)) => self_b == other_b,
+                (Constructor::IntRange(self_range), Constructor::IntRange(other_range)) => {
+                    self_range == other_range
+                }
+                (
+                    Constructor::F32Range(self_lo, self_hi, self_end),
+                    Constructor::F32Range(other_lo, other_hi, other_end),
+                ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
+                (
+                    Constructor::F64Range(self_lo, self_hi, self_end),
+                    Constructor::F64Range(other_lo, other_hi, other_end),
+                ) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
+                (Constructor::Str(self_value), Constructor::Str(other_value)) => {
+                    self_value == other_value
+                }
+                (Constructor::Opaque(self_inner), Constructor::Opaque(other_inner)) => {
+                    self_inner == other_inner
+                }
+                (Constructor::Or, Constructor::Or) => true,
+                (Constructor::Wildcard, Constructor::Wildcard) => true,
+                (Constructor::NonExhaustive, Constructor::NonExhaustive) => true,
+                (Constructor::Hidden, Constructor::Hidden) => true,
+                (Constructor::Missing, Constructor::Missing) => true,
+                _ => unreachable!(),
+            }
+    }
+}
+
 impl<Cx: TypeCx> Constructor<Cx> {
     pub(crate) fn is_non_exhaustive(&self) -> bool {
         matches!(self, NonExhaustive)
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index 6374874165f..a53d7a0d809 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -136,23 +136,35 @@ pub trait TypeCx: Sized + fmt::Debug {
 }
 
 /// Context that provides information global to a match.
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""), Copy(bound = ""))]
 pub struct MatchCtxt<'a, Cx: TypeCx> {
     /// The context for type information.
     pub tycx: &'a Cx,
 }
 
+impl<'a, Cx: TypeCx> Clone for MatchCtxt<'a, Cx> {
+    fn clone(&self) -> Self {
+        Self { tycx: self.tycx }
+    }
+}
+
+impl<'a, Cx: TypeCx> Copy for MatchCtxt<'a, Cx> {}
+
 /// The arm of a match expression.
 #[derive(Debug)]
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""), Copy(bound = ""))]
 pub struct MatchArm<'p, Cx: TypeCx> {
     pub pat: &'p DeconstructedPat<'p, Cx>,
     pub has_guard: bool,
     pub arm_data: Cx::ArmData,
 }
 
+impl<'p, Cx: TypeCx> Clone for MatchArm<'p, Cx> {
+    fn clone(&self) -> Self {
+        Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data }
+    }
+}
+
+impl<'p, Cx: TypeCx> Copy for MatchArm<'p, Cx> {}
+
 /// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are
 /// useful, and runs some lints.
 #[cfg(feature = "rustc")]
diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs
index 1cc31074556..d476766d466 100644
--- a/compiler/rustc_pattern_analysis/src/pat.rs
+++ b/compiler/rustc_pattern_analysis/src/pat.rs
@@ -218,8 +218,6 @@ impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
 /// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input.
 ///
 /// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard.
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""), Copy(bound = ""))]
 pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
     /// A non-user-provided wildcard, created during specialization.
     Wild,
@@ -227,6 +225,17 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
     Pat(&'p DeconstructedPat<'p, Cx>),
 }
 
+impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
+    fn clone(&self) -> Self {
+        match self {
+            PatOrWild::Wild => PatOrWild::Wild,
+            PatOrWild::Pat(pat) => PatOrWild::Pat(pat),
+        }
+    }
+}
+
+impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {}
+
 impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
     pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
         match self {
@@ -289,14 +298,28 @@ impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> {
 
 /// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
 /// purposes. As such they don't use interning and can be cloned.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""))]
 pub struct WitnessPat<Cx: TypeCx> {
     ctor: Constructor<Cx>,
     pub(crate) fields: Vec<WitnessPat<Cx>>,
     ty: Cx::Ty,
 }
 
+impl<Cx: TypeCx> Clone for WitnessPat<Cx> {
+    fn clone(&self) -> Self {
+        Self { ctor: self.ctor.clone(), fields: self.fields.clone(), ty: self.ty.clone() }
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for WitnessPat<Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_struct("WitnessPat")
+            .field("ctor", &self.ctor)
+            .field("fields", &self.fields)
+            .field("ty", &self.ty)
+            .finish()
+    }
+}
+
 impl<Cx: TypeCx> WitnessPat<Cx> {
     pub(crate) fn new(ctor: Constructor<Cx>, fields: Vec<Self>, ty: Cx::Ty) -> Self {
         Self { ctor, fields, ty }
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index ef90d24b0bf..223d6cefc83 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -46,11 +46,15 @@ pub type WitnessPat<'p, 'tcx> = crate::pat::WitnessPat<RustcMatchCheckCtxt<'p, '
 ///
 /// Use `.inner()` or deref to get to the `Ty<'tcx>`.
 #[repr(transparent)]
-#[derive(derivative::Derivative)]
 #[derive(Clone, Copy)]
-#[derivative(Debug = "transparent")]
 pub struct RevealedTy<'tcx>(Ty<'tcx>);
 
+impl<'tcx> fmt::Debug for RevealedTy<'tcx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(fmt)
+    }
+}
+
 impl<'tcx> std::ops::Deref for RevealedTy<'tcx> {
     type Target = Ty<'tcx>;
     fn deref(&self) -> &Self::Target {
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index a627bdeef81..b15de1c0ca9 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -731,16 +731,26 @@ pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
 }
 
 /// Context that provides information local to a place under investigation.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""), Copy(bound = ""))]
 pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
-    #[derivative(Debug = "ignore")]
     pub(crate) mcx: MatchCtxt<'a, Cx>,
     /// Type of the place under investigation.
-    #[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90
     pub(crate) ty: &'a Cx::Ty,
 }
 
+impl<'a, Cx: TypeCx> Clone for PlaceCtxt<'a, Cx> {
+    fn clone(&self) -> Self {
+        Self { mcx: self.mcx, ty: self.ty }
+    }
+}
+
+impl<'a, Cx: TypeCx> Copy for PlaceCtxt<'a, Cx> {}
+
+impl<'a, Cx: TypeCx> fmt::Debug for PlaceCtxt<'a, Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_struct("PlaceCtxt").field("ty", self.ty).finish()
+    }
+}
+
 impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
     /// A `PlaceCtxt` when code other than `is_useful` needs one.
     #[cfg_attr(not(feature = "rustc"), allow(dead_code))]
@@ -813,8 +823,6 @@ impl fmt::Display for ValidityConstraint {
 // The three lifetimes are:
 // - 'p coming from the input
 // - Cx global compilation context
-#[derive(derivative::Derivative)]
-#[derivative(Clone(bound = ""))]
 struct PatStack<'p, Cx: TypeCx> {
     // Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
     pats: SmallVec<[PatOrWild<'p, Cx>; 2]>,
@@ -824,6 +832,12 @@ struct PatStack<'p, Cx: TypeCx> {
     relevant: bool,
 }
 
+impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> {
+    fn clone(&self) -> Self {
+        Self { pats: self.pats.clone(), relevant: self.relevant }
+    }
+}
+
 impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
     fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
         PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
@@ -1184,10 +1198,20 @@ impl<'p, Cx: TypeCx> fmt::Debug for Matrix<'p, Cx> {
 /// The final `Pair(Some(_), true)` is then the resulting witness.
 ///
 /// See the top of the file for more detailed explanations and examples.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""))]
 struct WitnessStack<Cx: TypeCx>(Vec<WitnessPat<Cx>>);
 
+impl<Cx: TypeCx> Clone for WitnessStack<Cx> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for WitnessStack<Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_tuple("WitnessStack").field(&self.0).finish()
+    }
+}
+
 impl<Cx: TypeCx> WitnessStack<Cx> {
     /// Asserts that the witness contains a single pattern, and returns it.
     fn single_pattern(self) -> WitnessPat<Cx> {
@@ -1232,18 +1256,28 @@ impl<Cx: TypeCx> WitnessStack<Cx> {
 ///
 /// Just as the `Matrix` starts with a single column, by the end of the algorithm, this has a single
 /// column, which contains the patterns that are missing for the match to be exhaustive.
-#[derive(derivative::Derivative)]
-#[derivative(Debug(bound = ""), Clone(bound = ""))]
 struct WitnessMatrix<Cx: TypeCx>(Vec<WitnessStack<Cx>>);
 
+impl<Cx: TypeCx> Clone for WitnessMatrix<Cx> {
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+impl<Cx: TypeCx> fmt::Debug for WitnessMatrix<Cx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt.debug_tuple("WitnessMatrix").field(&self.0).finish()
+    }
+}
+
 impl<Cx: TypeCx> WitnessMatrix<Cx> {
     /// New matrix with no witnesses.
     fn empty() -> Self {
-        WitnessMatrix(vec![])
+        WitnessMatrix(Vec::new())
     }
     /// New matrix with one `()` witness, i.e. with no columns.
     fn unit_witness() -> Self {
-        WitnessMatrix(vec![WitnessStack(vec![])])
+        WitnessMatrix(vec![WitnessStack(Vec::new())])
     }
 
     /// Whether this has any witnesses.
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index b1242f82f4f..01c6d18c0e1 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -1,9 +1,9 @@
-use rustc_errors::DiagnosticArgFromDisplay;
+use rustc_errors::{codes::*, DiagnosticArgFromDisplay};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_span::{Span, Symbol};
 
 #[derive(Diagnostic)]
-#[diag(privacy_field_is_private, code = "E0451")]
+#[diag(privacy_field_is_private, code = E0451)]
 pub struct FieldIsPrivate {
     #[primary_span]
     pub span: Span,
@@ -48,7 +48,7 @@ pub struct UnnamedItemIsPrivate {
 }
 
 #[derive(Diagnostic)]
-#[diag(privacy_in_public_interface, code = "E0446")]
+#[diag(privacy_in_public_interface, code = E0446)]
 pub struct InPublicInterface<'a> {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_query_system/src/error.rs b/compiler/rustc_query_system/src/error.rs
index 5829e17ec16..9db6fac8036 100644
--- a/compiler/rustc_query_system/src/error.rs
+++ b/compiler/rustc_query_system/src/error.rs
@@ -1,3 +1,4 @@
+use rustc_errors::codes::*;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::Limit;
 use rustc_span::{Span, Symbol};
@@ -45,7 +46,7 @@ pub struct CycleUsage {
 }
 
 #[derive(Diagnostic)]
-#[diag(query_system_cycle, code = "E0391")]
+#[diag(query_system_cycle, code = E0391)]
 pub struct Cycle {
     #[primary_span]
     pub span: Span,
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index b855ec8f920..7eb7c8c2bca 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -19,7 +19,7 @@ use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
 use rustc_ast::{Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId};
 use rustc_attr as attr;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{struct_span_code_err, Applicability};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability};
 use rustc_expand::expand::AstFragment;
 use rustc_hir::def::{self, *};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 66dfee6c062..f3a6eb65a72 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -6,8 +6,8 @@ use rustc_ast::{MetaItemKind, NestedMetaItem};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt, Diagnostic,
-    DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle,
+    codes::*, pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt,
+    Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle,
 };
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 821b1e946f3..50ff09feb4d 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -1,3 +1,4 @@
+use rustc_errors::codes::*;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{
     symbol::{Ident, Symbol},
@@ -7,16 +8,16 @@ use rustc_span::{
 use crate::{late::PatternSource, Res};
 
 #[derive(Diagnostic)]
-#[diag(resolve_parent_module_reset_for_binding, code = "E0637")]
+#[diag(resolve_parent_module_reset_for_binding, code = E0637)]
 pub(crate) struct ParentModuleResetForBinding;
 
 #[derive(Diagnostic)]
-#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = "E0637")]
+#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = E0637)]
 #[note]
 pub(crate) struct AmpersandUsedWithoutExplicitLifetimeName(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
-#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = "E0637")]
+#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = E0637)]
 #[note]
 pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(crate) Span);
 
@@ -33,7 +34,7 @@ pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate)
 pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
-#[diag(resolve_generic_params_from_outer_item, code = "E0401")]
+#[diag(resolve_generic_params_from_outer_item, code = E0401)]
 pub(crate) struct GenericParamsFromOuterItem {
     #[primary_span]
     #[label]
@@ -67,7 +68,7 @@ pub(crate) struct GenericParamsFromOuterItemSugg {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")]
+#[diag(resolve_name_is_already_used_as_generic_parameter, code = E0403)]
 pub(crate) struct NameAlreadyUsedInParameterList {
     #[primary_span]
     #[label]
@@ -78,7 +79,7 @@ pub(crate) struct NameAlreadyUsedInParameterList {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_method_not_member_of_trait, code = "E0407")]
+#[diag(resolve_method_not_member_of_trait, code = E0407)]
 pub(crate) struct MethodNotMemberOfTrait {
     #[primary_span]
     #[label]
@@ -102,7 +103,7 @@ pub(crate) struct AssociatedFnWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_type_not_member_of_trait, code = "E0437")]
+#[diag(resolve_type_not_member_of_trait, code = E0437)]
 pub(crate) struct TypeNotMemberOfTrait {
     #[primary_span]
     #[label]
@@ -126,7 +127,7 @@ pub(crate) struct AssociatedTypeWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_const_not_member_of_trait, code = "E0438")]
+#[diag(resolve_const_not_member_of_trait, code = E0438)]
 pub(crate) struct ConstNotMemberOfTrait {
     #[primary_span]
     #[label]
@@ -150,7 +151,7 @@ pub(crate) struct AssociatedConstWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_variable_bound_with_different_mode, code = "E0409")]
+#[diag(resolve_variable_bound_with_different_mode, code = E0409)]
 pub(crate) struct VariableBoundWithDifferentMode {
     #[primary_span]
     #[label]
@@ -161,7 +162,7 @@ pub(crate) struct VariableBoundWithDifferentMode {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = "E0415")]
+#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = E0415)]
 pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
     #[primary_span]
     #[label]
@@ -170,7 +171,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInParameterList {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = "E0416")]
+#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = E0416)]
 pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
     #[primary_span]
     #[label]
@@ -179,7 +180,7 @@ pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_undeclared_label, code = "E0426")]
+#[diag(resolve_undeclared_label, code = E0426)]
 pub(crate) struct UndeclaredLabel {
     #[primary_span]
     #[label]
@@ -217,7 +218,7 @@ pub(crate) struct UnreachableLabelWithSimilarNameExists {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = "E0430")]
+#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = E0430)]
 pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
     #[primary_span]
     #[label]
@@ -225,7 +226,7 @@ pub(crate) struct SelfImportCanOnlyAppearOnceInTheList {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = "E0431")]
+#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = E0431)]
 pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
     #[primary_span]
     #[label]
@@ -233,7 +234,7 @@ pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = "E0434")]
+#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = E0434)]
 #[help]
 pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
     #[primary_span]
@@ -241,7 +242,7 @@ pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = "E0435")]
+#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = E0435)]
 pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> {
     #[primary_span]
     pub(crate) span: Span,
@@ -283,7 +284,7 @@ pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_imports_only_allowed_within, code = "E0429")]
+#[diag(resolve_self_imports_only_allowed_within, code = E0429)]
 pub(crate) struct SelfImportsOnlyAllowedWithin {
     #[primary_span]
     pub(crate) span: Span,
@@ -317,7 +318,7 @@ pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_binding_shadows_something_unacceptable, code = "E0530")]
+#[diag(resolve_binding_shadows_something_unacceptable, code = E0530)]
 pub(crate) struct BindingShadowsSomethingUnacceptable<'a> {
     #[primary_span]
     #[label]
@@ -346,7 +347,7 @@ pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_forward_declared_generic_param, code = "E0128")]
+#[diag(resolve_forward_declared_generic_param, code = E0128)]
 pub(crate) struct ForwardDeclaredGenericParam {
     #[primary_span]
     #[label]
@@ -354,7 +355,7 @@ pub(crate) struct ForwardDeclaredGenericParam {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_param_in_ty_of_const_param, code = "E0770")]
+#[diag(resolve_param_in_ty_of_const_param, code = E0770)]
 pub(crate) struct ParamInTyOfConstParam {
     #[primary_span]
     #[label]
@@ -376,7 +377,7 @@ pub(crate) enum ParamKindInTyOfConstParam {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_self_in_generic_param_default, code = "E0735")]
+#[diag(resolve_self_in_generic_param_default, code = E0735)]
 pub(crate) struct SelfInGenericParamDefault {
     #[primary_span]
     #[label]
@@ -412,7 +413,7 @@ pub(crate) enum ParamKindInNonTrivialAnonConst {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_unreachable_label, code = "E0767")]
+#[diag(resolve_unreachable_label, code = E0767)]
 #[note]
 pub(crate) struct UnreachableLabel {
     #[primary_span]
@@ -456,7 +457,7 @@ pub(crate) struct UnreachableLabelSubLabelUnreachable {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_trait_impl_mismatch, code = "{code}")]
+#[diag(resolve_trait_impl_mismatch)]
 pub(crate) struct TraitImplMismatch {
     #[primary_span]
     #[label]
@@ -466,7 +467,6 @@ pub(crate) struct TraitImplMismatch {
     #[label(resolve_label_trait_item)]
     pub(crate) trait_item_span: Span,
     pub(crate) trait_path: String,
-    pub(crate) code: String,
 }
 
 #[derive(Diagnostic)]
@@ -496,7 +496,7 @@ pub(crate) struct BindingInNeverPattern {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_trait_impl_duplicate, code = "E0201")]
+#[diag(resolve_trait_impl_duplicate, code = E0201)]
 pub(crate) struct TraitImplDuplicate {
     #[primary_span]
     #[label]
@@ -519,11 +519,11 @@ pub(crate) struct Relative2018 {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_ancestor_only, code = "E0742")]
+#[diag(resolve_ancestor_only, code = E0742)]
 pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
-#[diag(resolve_expected_found, code = "E0577")]
+#[diag(resolve_expected_found, code = E0577)]
 pub(crate) struct ExpectedFound {
     #[primary_span]
     #[label]
@@ -533,7 +533,7 @@ pub(crate) struct ExpectedFound {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_indeterminate, code = "E0578")]
+#[diag(resolve_indeterminate, code = E0578)]
 pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);
 
 #[derive(Diagnostic)]
@@ -715,7 +715,7 @@ pub(crate) struct CannotDetermineMacroResolution {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_private, code = "E0364")]
+#[diag(resolve_cannot_be_reexported_private, code = E0364)]
 pub(crate) struct CannotBeReexportedPrivate {
     #[primary_span]
     pub(crate) span: Span,
@@ -723,7 +723,7 @@ pub(crate) struct CannotBeReexportedPrivate {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_crate_public, code = "E0364")]
+#[diag(resolve_cannot_be_reexported_crate_public, code = E0364)]
 pub(crate) struct CannotBeReexportedCratePublic {
     #[primary_span]
     pub(crate) span: Span,
@@ -731,7 +731,7 @@ pub(crate) struct CannotBeReexportedCratePublic {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_private, code = "E0365")]
+#[diag(resolve_cannot_be_reexported_private, code = E0365)]
 #[note(resolve_consider_declaring_with_pub)]
 pub(crate) struct CannotBeReexportedPrivateNS {
     #[primary_span]
@@ -741,7 +741,7 @@ pub(crate) struct CannotBeReexportedPrivateNS {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_cannot_be_reexported_crate_public, code = "E0365")]
+#[diag(resolve_cannot_be_reexported_crate_public, code = E0365)]
 #[note(resolve_consider_declaring_with_pub)]
 pub(crate) struct CannotBeReexportedCratePublicNS {
     #[primary_span]
@@ -780,7 +780,7 @@ pub(crate) struct ItemsInTraitsAreNotImportable {
 }
 
 #[derive(Diagnostic)]
-#[diag(resolve_is_not_directly_importable, code = "E0253")]
+#[diag(resolve_is_not_directly_importable, code = E0253)]
 pub(crate) struct IsNotDirectlyImportable {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index ad60caed354..30fb35238c3 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -17,7 +17,7 @@ use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult};
 use rustc_ast::NodeId;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::intern::Interned;
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, MultiSpan};
 use rustc_hir::def::{self, DefKind, PartialRes};
 use rustc_middle::metadata::ModChild;
 use rustc_middle::metadata::Reexport;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 18926463d6b..0743ff03864 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -16,7 +16,9 @@ use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
 use rustc_ast::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
-use rustc_errors::{Applicability, DiagnosticArgValue, IntoDiagnosticArg};
+use rustc_errors::{
+    codes::*, struct_span_code_err, Applicability, DiagnosticArgValue, ErrCode, IntoDiagnosticArg,
+};
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -533,21 +535,20 @@ impl<'a> PathSource<'a> {
         }
     }
 
-    fn error_code(self, has_unexpected_resolution: bool) -> String {
-        use rustc_errors::error_code;
+    fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {
         match (self, has_unexpected_resolution) {
-            (PathSource::Trait(_), true) => error_code!(E0404),
-            (PathSource::Trait(_), false) => error_code!(E0405),
-            (PathSource::Type, true) => error_code!(E0573),
-            (PathSource::Type, false) => error_code!(E0412),
-            (PathSource::Struct, true) => error_code!(E0574),
-            (PathSource::Struct, false) => error_code!(E0422),
-            (PathSource::Expr(..), true) | (PathSource::Delegation, true) => error_code!(E0423),
-            (PathSource::Expr(..), false) | (PathSource::Delegation, false) => error_code!(E0425),
-            (PathSource::Pat | PathSource::TupleStruct(..), true) => error_code!(E0532),
-            (PathSource::Pat | PathSource::TupleStruct(..), false) => error_code!(E0531),
-            (PathSource::TraitItem(..), true) => error_code!(E0575),
-            (PathSource::TraitItem(..), false) => error_code!(E0576),
+            (PathSource::Trait(_), true) => E0404,
+            (PathSource::Trait(_), false) => E0405,
+            (PathSource::Type, true) => E0573,
+            (PathSource::Type, false) => E0412,
+            (PathSource::Struct, true) => E0574,
+            (PathSource::Struct, false) => E0422,
+            (PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
+            (PathSource::Expr(..), false) | (PathSource::Delegation, false) => E0425,
+            (PathSource::Pat | PathSource::TupleStruct(..), true) => E0532,
+            (PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
+            (PathSource::TraitItem(..), true) => E0575,
+            (PathSource::TraitItem(..), false) => E0576,
         }
     }
 }
@@ -1673,13 +1674,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     } else {
                         ("`'_` cannot be used here", "`'_` is a reserved lifetime name")
                     };
-                    let mut diag = rustc_errors::struct_span_code_err!(
-                        self.r.dcx(),
-                        lifetime.ident.span,
-                        E0637,
-                        "{}",
-                        msg,
-                    );
+                    let mut diag =
+                        struct_span_code_err!(self.r.dcx(), lifetime.ident.span, E0637, "{}", msg,);
                     diag.span_label(lifetime.ident.span, note);
                     if elided {
                         for rib in self.lifetime_ribs[i..].iter().rev() {
@@ -1863,7 +1859,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     LifetimeRibKind::AnonymousCreateParameter { report_in_path: true, .. }
                     | LifetimeRibKind::AnonymousWarn(_) => {
                         let sess = self.r.tcx.sess;
-                        let mut err = rustc_errors::struct_span_code_err!(
+                        let mut err = struct_span_code_err!(
                             sess.dcx(),
                             path_span,
                             E0726,
@@ -2608,7 +2604,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
 
             if param.ident.name == kw::UnderscoreLifetime {
-                rustc_errors::struct_span_code_err!(
+                struct_span_code_err!(
                     self.r.dcx(),
                     param.ident.span,
                     E0637,
@@ -2622,7 +2618,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
 
             if param.ident.name == kw::StaticLifetime {
-                rustc_errors::struct_span_code_err!(
+                struct_span_code_err!(
                     self.r.dcx(),
                     param.ident.span,
                     E0262,
@@ -3164,10 +3160,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // The method kind does not correspond to what appeared in the trait, report.
         let path = &self.current_trait_ref.as_ref().unwrap().1.path;
         let (code, kind) = match kind {
-            AssocItemKind::Const(..) => (rustc_errors::error_code!(E0323), "const"),
-            AssocItemKind::Fn(..) => (rustc_errors::error_code!(E0324), "method"),
-            AssocItemKind::Type(..) => (rustc_errors::error_code!(E0325), "type"),
-            AssocItemKind::Delegation(..) => (rustc_errors::error_code!(E0324), "method"),
+            AssocItemKind::Const(..) => (E0323, "const"),
+            AssocItemKind::Fn(..) => (E0324, "method"),
+            AssocItemKind::Type(..) => (E0325, "type"),
+            AssocItemKind::Delegation(..) => (E0324, "method"),
             AssocItemKind::MacCall(..) => span_bug!(span, "unexpanded macro"),
         };
         let trait_path = path_names_to_string(path);
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index abb0a7a465a..a4c041f1ff2 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -16,8 +16,8 @@ use rustc_ast::{
 use rustc_ast_pretty::pprust::where_bound_predicate_to_string;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    MultiSpan, SuggestionStyle,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed, MultiSpan, SuggestionStyle,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
@@ -922,8 +922,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         path: &[Segment],
         span: Span,
     ) {
-        if let Some(err_code) = &err.code {
-            if err_code == &rustc_errors::error_code!(E0425) {
+        if let Some(err_code) = err.code {
+            if err_code == E0425 {
                 for label_rib in &self.label_ribs {
                     for (label_ident, node_id) in &label_rib.bindings {
                         let ident = path.last().unwrap().ident;
@@ -946,7 +946,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         }
                     }
                 }
-            } else if err_code == &rustc_errors::error_code!(E0412) {
+            } else if err_code == E0412 {
                 if let Some(correct) = Self::likely_rust_type(path) {
                     err.span_suggestion(
                         span,
@@ -970,7 +970,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         if !is_self_type(path, source.namespace()) {
             return false;
         }
-        err.code(rustc_errors::error_code!(E0411));
+        err.code(E0411);
         err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
         if let Some(item_kind) = self.diagnostic_metadata.current_item {
             if !item_kind.ident.span.is_dummy() {
@@ -999,7 +999,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         }
 
         debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
-        err.code(rustc_errors::error_code!(E0424));
+        err.code(E0424);
         err.span_label(
             span,
             match source {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 925c3c0e27d..9d09d060b59 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -35,7 +35,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
-use rustc_errors::{Applicability, DiagnosticBuilder};
+use rustc_errors::{Applicability, DiagnosticBuilder, ErrCode};
 use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind};
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
@@ -256,7 +256,7 @@ enum ResolutionError<'a> {
         kind: &'static str,
         trait_path: String,
         trait_item_span: Span,
-        code: String,
+        code: ErrCode,
     },
     /// Error E0201: multiple impl items for the same trait item.
     TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span },
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 1c085ddf57b..a6bf289a76a 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust;
 use rustc_attr::StabilityLevel;
 use rustc_data_structures::intern::Interned;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{struct_span_code_err, Applicability};
+use rustc_errors::{codes::*, struct_span_code_err, Applicability};
 use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand};
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::compile_declarative_macro;
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index e19f0fd84de..c36cec6f353 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -3,7 +3,7 @@ use std::num::NonZeroU32;
 use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
 use rustc_errors::{
-    error_code, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, IntoDiagnostic, Level, MultiSpan,
+    codes::*, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, IntoDiagnostic, Level, MultiSpan,
 };
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
@@ -19,9 +19,7 @@ pub struct FeatureGateError {
 impl<'a> IntoDiagnostic<'a> for FeatureGateError {
     #[track_caller]
     fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a> {
-        DiagnosticBuilder::new(dcx, level, self.explain)
-            .with_span(self.span)
-            .with_code(error_code!(E0658))
+        DiagnosticBuilder::new(dcx, level, self.explain).with_span(self.span).with_code(E0658)
     }
 }
 
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index 891a83ce80c..7cd76ad7293 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -22,7 +22,7 @@ use rustc_errors::emitter::{DynEmitter, HumanEmitter, HumanReadableErrorType};
 use rustc_errors::json::JsonEmitter;
 use rustc_errors::registry::Registry;
 use rustc_errors::{
-    error_code, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticMessage,
+    codes::*, fallback_fluent_bundle, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrCode,
     ErrorGuaranteed, FatalAbort, FluentBundle, IntoDiagnostic, LazyFallbackBundle, TerminalUrl,
 };
 use rustc_macros::HashStable_Generic;
@@ -316,7 +316,7 @@ impl Session {
     ) -> DiagnosticBuilder<'a> {
         let mut err = self.dcx().create_err(err);
         if err.code.is_none() {
-            err.code(error_code!(E0658));
+            err.code(E0658);
         }
         add_feature_diagnostics(&mut err, self, feature);
         err
@@ -893,7 +893,7 @@ impl Session {
         CodegenUnits::Default(16)
     }
 
-    pub fn teach(&self, code: &str) -> bool {
+    pub fn teach(&self, code: ErrCode) -> bool {
         self.opts.unstable_opts.teach && self.dcx().must_teach(code)
     }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 514d65abbe3..a54b928b908 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -246,17 +246,7 @@ symbols! {
         MutexGuard,
         N,
         NonNull,
-        NonZeroI128,
-        NonZeroI16,
-        NonZeroI32,
-        NonZeroI64,
-        NonZeroI8,
-        NonZeroU128,
-        NonZeroU16,
-        NonZeroU32,
-        NonZeroU64,
-        NonZeroU8,
-        NonZeroUsize,
+        NonZero,
         None,
         Normal,
         Ok,
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 5eff52afbca..7894f8dd98f 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -1,7 +1,7 @@
 use crate::fluent_generated as fluent;
 use rustc_errors::{
-    AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee,
-    IntoDiagnostic, Level, SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    EmissionGuarantee, IntoDiagnostic, Level, SubdiagnosticMessage,
 };
 use rustc_macros::Diagnostic;
 use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
@@ -25,7 +25,7 @@ pub struct UnableToConstructConstantValue<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+#[diag(trait_selection_empty_on_clause_in_rustc_on_unimplemented, code = E0232)]
 pub struct EmptyOnClauseInOnUnimplemented {
     #[primary_span]
     #[label]
@@ -33,7 +33,7 @@ pub struct EmptyOnClauseInOnUnimplemented {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_invalid_on_clause_in_rustc_on_unimplemented, code = "E0232")]
+#[diag(trait_selection_invalid_on_clause_in_rustc_on_unimplemented, code = E0232)]
 pub struct InvalidOnClauseInOnUnimplemented {
     #[primary_span]
     #[label]
@@ -41,7 +41,7 @@ pub struct InvalidOnClauseInOnUnimplemented {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_no_value_in_rustc_on_unimplemented, code = "E0232")]
+#[diag(trait_selection_no_value_in_rustc_on_unimplemented, code = E0232)]
 #[note]
 pub struct NoValueInOnUnimplemented {
     #[primary_span]
@@ -59,17 +59,13 @@ pub struct NegativePositiveConflict<'tcx> {
 
 impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for NegativePositiveConflict<'_> {
     #[track_caller]
-    fn into_diagnostic(
-        self,
-        dcx: &DiagCtxt,
-        level: Level,
-    ) -> rustc_errors::DiagnosticBuilder<'_, G> {
+    fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
         let mut diag =
             DiagnosticBuilder::new(dcx, level, fluent::trait_selection_negative_positive_conflict);
         diag.arg("trait_desc", self.trait_desc.print_only_trait_path().to_string());
         diag.arg("self_desc", self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string()));
         diag.span(self.impl_span);
-        diag.code(rustc_errors::error_code!(E0751));
+        diag.code(E0751);
         match self.negative_impl_span {
             Ok(span) => {
                 diag.span_label(span, fluent::trait_selection_negative_implementation_here);
@@ -132,7 +128,7 @@ impl AddToDiagnostic for AdjustSignatureBorrow {
 }
 
 #[derive(Diagnostic)]
-#[diag(trait_selection_closure_kind_mismatch, code = "E0525")]
+#[diag(trait_selection_closure_kind_mismatch, code = E0525)]
 pub struct ClosureKindMismatch {
     #[primary_span]
     #[label]
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
index 864580afe62..ca43436848b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs
@@ -1,7 +1,7 @@
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxt;
 use crate::traits::{Obligation, ObligationCause, ObligationCtxt};
-use rustc_errors::{pluralize, struct_span_code_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::Node;
 use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
index bb1b6ec1390..972da180a33 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs
@@ -6,7 +6,7 @@ use rustc_ast::AttrKind;
 use rustc_ast::{Attribute, MetaItem, NestedMetaItem};
 use rustc_attr as attr;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{struct_span_code_err, ErrorGuaranteed};
+use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::GenericArgsRef;
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 6a40ffebdad..cdf99870006 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -13,7 +13,7 @@ use hir::def::CtorOf;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
-    error_code, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
     MultiSpan, Style, SuggestionStyle,
 };
 use rustc_hir as hir;
@@ -2014,7 +2014,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             return false;
         };
 
-        err.code(error_code!(E0746));
+        err.code(E0746);
         err.primary_message("return type cannot have an unboxed trait object");
         err.children.clear();
 
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 149dcffe333..2a09e95b2c5 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -19,8 +19,8 @@ use crate::traits::{
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::{
-    pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
-    MultiSpan, StashKey, Style,
+    codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
+    ErrorGuaranteed, MultiSpan, StashKey, Style,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace, Res};
@@ -2529,7 +2529,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                  corresponding `impl` type",
                             ),
                         );
-                        err.code(rustc_errors::error_code!(E0790));
+                        err.code(E0790);
 
                         if let Some(local_def_id) = data.trait_ref.def_id.as_local()
                             && let Some(hir::Node::Item(hir::Item {
@@ -3162,7 +3162,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             | ObligationCauseCode::ItemObligation(def_id)
                 if self.tcx.is_fn_trait(*def_id) =>
             {
-                err.code(rustc_errors::error_code!(E0059));
+                err.code(E0059);
                 err.primary_message(format!(
                     "type parameter to bare `{}` trait must be a tuple",
                     self.tcx.def_path_str(*def_id)
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index bfc6937a3eb..de08e7d2f03 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -20,7 +20,7 @@ use crate::traits::{
     self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
 };
 use rustc_data_structures::fx::FxIndexSet;
-use rustc_errors::{error_code, DelayDm, Diagnostic};
+use rustc_errors::{codes::*, DelayDm, Diagnostic};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArgs, GenericArgsRef};
@@ -449,7 +449,7 @@ fn report_conflicting_impls<'tcx>(
                 || tcx.orphan_check_impl(impl_def_id).is_ok()
             {
                 let mut err = tcx.dcx().struct_span_err(impl_span, msg);
-                err.code(error_code!(E0119));
+                err.code(E0119);
                 decorate(tcx, &overlap, impl_span, &mut err);
                 err.emit()
             } else {
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index 947d4bbe86e..bfbb45f0cb5 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -1,5 +1,6 @@
 //! Errors emitted by ty_utils
 
+use rustc_errors::codes::*;
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_middle::ty::{GenericArg, Ty};
 use rustc_span::Span;
@@ -113,7 +114,7 @@ pub struct DuplicateArg<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ty_utils_impl_trait_not_param, code = "E0792")]
+#[diag(ty_utils_impl_trait_not_param, code = E0792)]
 pub struct NotParam<'tcx> {
     pub arg: GenericArg<'tcx>,
     #[primary_span]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 7705c86001e..0338565980c 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -939,8 +939,11 @@ impl<T, A: Allocator> Rc<T, A> {
     /// it is guaranteed that exactly one of the calls returns the inner value.
     /// This means in particular that the inner value is not dropped.
     ///
-    /// This is equivalent to `Rc::try_unwrap(this).ok()`. (Note that these are not equivalent for
-    /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`.)
+    /// [`Rc::try_unwrap`] is conceptually similar to `Rc::into_inner`.
+    /// And while they are meant for different use-cases, `Rc::into_inner(this)`
+    /// is in fact equivalent to <code>[Rc::try_unwrap]\(this).[ok][Result::ok]()</code>.
+    /// (Note that the same kind of equivalence does **not** hold true for
+    /// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`!)
     #[inline]
     #[stable(feature = "rc_into_inner", since = "1.70.0")]
     pub fn into_inner(this: Self) -> Option<T> {
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 48c8d9d113b..d0f98f9c7db 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -983,9 +983,13 @@ impl<T, A: Allocator> Arc<T, A> {
     /// it is guaranteed that exactly one of the calls returns the inner value.
     /// This means in particular that the inner value is not dropped.
     ///
-    /// The similar expression `Arc::try_unwrap(this).ok()` does not
-    /// offer such a guarantee. See the last example below
-    /// and the documentation of [`Arc::try_unwrap`].
+    /// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it
+    /// is meant for different use-cases. If used as a direct replacement
+    /// for `Arc::into_inner` anyway, such as with the expression
+    /// <code>[Arc::try_unwrap]\(this).[ok][Result::ok]()</code>, then it does
+    /// **not** give the same guarantee as described in the previous paragraph.
+    /// For more information, see the examples below and read the documentation
+    /// of [`Arc::try_unwrap`].
     ///
     /// # Examples
     ///
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index c2b646b9b3e..03c977abbbb 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -61,7 +61,15 @@ pub use dec2flt::ParseFloatError;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use error::ParseIntError;
 
-pub(crate) use nonzero::NonZero;
+#[unstable(
+    feature = "nonzero_internals",
+    reason = "implementation detail which may disappear or be replaced at any time",
+    issue = "none"
+)]
+pub use nonzero::ZeroablePrimitive;
+
+#[unstable(feature = "generic_nonzero", issue = "120257")]
+pub use nonzero::NonZero;
 
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 45ac544ceaa..1124719fc8d 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -3,6 +3,8 @@
 use crate::cmp::Ordering;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
+#[cfg(bootstrap)]
+use crate::marker::StructuralEq;
 use crate::marker::StructuralPartialEq;
 use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
 use crate::str::FromStr;
@@ -30,9 +32,7 @@ mod private {
     issue = "none"
 )]
 #[const_trait]
-pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {
-    type NonZero;
-}
+pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {}
 
 macro_rules! impl_zeroable_primitive {
     ($NonZero:ident ( $primitive:ty )) => {
@@ -48,9 +48,7 @@ macro_rules! impl_zeroable_primitive {
             reason = "implementation detail which may disappear or be replaced at any time",
             issue = "none"
         )]
-        impl const ZeroablePrimitive for $primitive {
-            type NonZero = $NonZero;
-        }
+        impl const ZeroablePrimitive for $primitive {}
     };
 }
 
@@ -67,12 +65,23 @@ impl_zeroable_primitive!(NonZeroI64(i64));
 impl_zeroable_primitive!(NonZeroI128(i128));
 impl_zeroable_primitive!(NonZeroIsize(isize));
 
-#[unstable(
-    feature = "nonzero_internals",
-    reason = "implementation detail which may disappear or be replaced at any time",
-    issue = "none"
-)]
-pub(crate) type NonZero<T> = <T as ZeroablePrimitive>::NonZero;
+/// A value that is known not to equal zero.
+///
+/// This enables some memory layout optimization.
+/// For example, `Option<NonZero<u32>>` is the same size as `u32`:
+///
+/// ```
+/// #![feature(generic_nonzero)]
+/// use core::mem::size_of;
+///
+/// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
+/// ```
+#[unstable(feature = "generic_nonzero", issue = "120257")]
+#[repr(transparent)]
+#[rustc_layout_scalar_valid_range_start(1)]
+#[rustc_nonnull_optimization_guaranteed]
+#[rustc_diagnostic_item = "NonZero"]
+pub struct NonZero<T: ZeroablePrimitive>(T);
 
 macro_rules! impl_nonzero_fmt {
     ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
@@ -131,12 +140,7 @@ macro_rules! nonzero_integer {
         ///
         /// [null pointer optimization]: crate::option#representation
         #[$stability]
-        #[derive(Copy, Eq)]
-        #[repr(transparent)]
-        #[rustc_layout_scalar_valid_range_start(1)]
-        #[rustc_nonnull_optimization_guaranteed]
-        #[rustc_diagnostic_item = stringify!($Ty)]
-        pub struct $Ty($Int);
+        pub type $Ty = NonZero<$Int>;
 
         impl $Ty {
             /// Creates a non-zero without checking whether the value is non-zero.
@@ -544,6 +548,9 @@ macro_rules! nonzero_integer {
         }
 
         #[$stability]
+        impl Copy for $Ty {}
+
+        #[$stability]
         impl PartialEq for $Ty {
             #[inline]
             fn eq(&self, other: &Self) -> bool {
@@ -560,6 +567,13 @@ macro_rules! nonzero_integer {
         impl StructuralPartialEq for $Ty {}
 
         #[$stability]
+        impl Eq for $Ty {}
+
+        #[unstable(feature = "structural_match", issue = "31434")]
+        #[cfg(bootstrap)]
+        impl StructuralEq for $Ty {}
+
+        #[$stability]
         impl PartialOrd for $Ty {
             #[inline]
             fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 7dee30585e9..bf47d767a92 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1384,6 +1384,30 @@ mod prim_usize {}
 /// work on references as well as they do on owned values! The implementations described here are
 /// meant for generic contexts, where the final type `T` is a type parameter or otherwise not
 /// locally known.
+///
+/// # Safety
+///
+/// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API
+/// boundary, the following invariants must generally be upheld:
+///
+/// * `t` is aligned to `align_of_val(t)`
+/// * `t` is dereferenceable for `size_of_val(t)` many bytes
+///
+/// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range
+/// `[a, a + N)` is all contained within a single [allocated object].
+///
+/// For instance, this means that unsafe code in a safe function may assume these invariants are
+/// ensured of arguments passed by the caller, and it may assume that these invariants are ensured
+/// of return values from any safe functions it calls. In most cases, the inverse is also true:
+/// unsafe code must not violate these invariants when passing arguments to safe functions or
+/// returning values from safe functions; such violations may result in undefined behavior. Where
+/// exceptions to this latter requirement exist, they will be called out explicitly in documentation.
+///
+/// It is not decided yet whether unsafe code may violate these invariants temporarily on internal
+/// data. As a consequence, unsafe code which violates these invariants temporarily on internal data
+/// may become unsound in future versions of Rust depending on how this question is decided.
+///
+/// [allocated object]: ptr#allocated-object
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_ref {}
 
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 751e988a99b..2e458562744 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -323,6 +323,7 @@
 #![feature(float_gamma)]
 #![feature(float_minimum_maximum)]
 #![feature(float_next_up_down)]
+#![feature(generic_nonzero)]
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(hint_assert_unchecked)]
diff --git a/library/std/src/num.rs b/library/std/src/num.rs
index 55f6ddcf77f..1343fdfd1df 100644
--- a/library/std/src/num.rs
+++ b/library/std/src/num.rs
@@ -16,6 +16,16 @@ pub use core::num::Wrapping;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError};
 
+#[unstable(
+    feature = "nonzero_internals",
+    reason = "implementation detail which may disappear or be replaced at any time",
+    issue = "none"
+)]
+pub use core::num::ZeroablePrimitive;
+
+#[unstable(feature = "generic_nonzero", issue = "120257")]
+pub use core::num::NonZero;
+
 #[stable(feature = "signed_nonzero", since = "1.34.0")]
 pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
 #[stable(feature = "nonzero", since = "1.28.0")]
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 42484543686..2bdd3d96fa4 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -112,6 +112,13 @@ impl fmt::Debug for ReadDir {
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
+        if self.handle.0 == c::INVALID_HANDLE_VALUE {
+            // This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle.
+            // Simply return `None` because this is only the case when `FindFirstFileW` in
+            // the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means
+            // no matchhing files can be found.
+            return None;
+        }
         if let Some(first) = self.first.take() {
             if let Some(e) = DirEntry::new(&self.root, &first) {
                 return Some(Ok(e));
@@ -1068,6 +1075,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
     unsafe {
         let mut wfd = mem::zeroed();
         let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
+
         if find_handle != c::INVALID_HANDLE_VALUE {
             Ok(ReadDir {
                 handle: FindNextFileHandle(find_handle),
@@ -1075,7 +1083,31 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
                 first: Some(wfd),
             })
         } else {
-            Err(Error::last_os_error())
+            // The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function
+            // if no matching files can be found, but not necessarily that the path to find the
+            // files in does not exist.
+            //
+            // Hence, a check for whether the path to search in exists is added when the last
+            // os error returned by Windows is `ERROR_FILE_NOT_FOUND` to handle this scenario.
+            // If that is the case, an empty `ReadDir` iterator is returned as it returns `None`
+            // in the initial `.next()` invocation because `ERROR_NO_MORE_FILES` would have been
+            // returned by the `FindNextFileW` function.
+            //
+            // See issue #120040: https://github.com/rust-lang/rust/issues/120040.
+            let last_error = api::get_last_error();
+            if last_error.code == c::ERROR_FILE_NOT_FOUND {
+                return Ok(ReadDir {
+                    handle: FindNextFileHandle(find_handle),
+                    root: Arc::new(root),
+                    first: None,
+                });
+            }
+
+            // Just return the error constructed from the raw OS error if the above is not the case.
+            //
+            // Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileW` function
+            // when the path to search in does not exist in the first place.
+            Err(Error::from_raw_os_error(last_error.code as i32))
         }
     }
 }
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 55eed95492d..0db61204f77 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -74,25 +74,6 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
 
       cksum=$(sha512sum $hash_key | \
         awk '{print $1}')
-
-      url="https://$CACHE_DOMAIN/docker/$cksum"
-
-      echo "Attempting to download $url"
-      rm -f /tmp/rustci_docker_cache
-      set +e
-      retry curl --max-time 600 -y 30 -Y 10 --connect-timeout 30 -f -L -C - \
-        -o /tmp/rustci_docker_cache "$url"
-
-      docker_archive_hash=$(sha512sum /tmp/rustci_docker_cache | awk '{print $1}')
-      echo "Downloaded archive hash: ${docker_archive_hash}"
-
-      echo "Loading images into docker"
-      # docker load sometimes hangs in the CI, so time out after 10 minutes with TERM,
-      # KILL after 12 minutes
-      loaded_images=$(/usr/bin/timeout -k 720 600 docker load -i /tmp/rustci_docker_cache \
-        | sed 's/.* sha/sha/')
-      set -e
-      printf "Downloaded containers:\n$loaded_images\n"
     fi
 
     dockerfile="$docker_dir/$image/Dockerfile"
@@ -103,46 +84,65 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
         context="$script_dir"
     fi
     echo "::group::Building docker image for $image"
-
-    # As of August 2023, Github Actions have updated Docker to 23.X,
-    # which uses the BuildKit by default. It currently throws aways all
-    # intermediate layers, which breaks our usage of S3 layer caching.
-    # Therefore we opt-in to the old build backend for now.
-    export DOCKER_BUILDKIT=0
-    retry docker \
-      build \
-      --rm \
-      -t rust-ci \
-      -f "$dockerfile" \
-      "$context"
-    echo "::endgroup::"
-
-    if [ "$CI" != "" ]; then
-      s3url="s3://$SCCACHE_BUCKET/docker/$cksum"
-      upload="aws s3 cp - $s3url"
-      digest=$(docker inspect rust-ci --format '{{.Id}}')
-      echo "Built container $digest"
-      if ! grep -q "$digest" <(echo "$loaded_images"); then
-        echo "Uploading finished image $digest to $url"
-        set +e
-        # Print image history for easier debugging of layer SHAs
-        docker history rust-ci
-        docker history -q rust-ci | \
-          grep -v missing | \
-          xargs docker save | \
-          gzip | \
-          $upload
-        set -e
-      else
-        echo "Looks like docker image is the same as before, not uploading"
-      fi
-      # Record the container image for reuse, e.g. by rustup.rs builds
-      info="$dist/image-$image.txt"
-      mkdir -p "$dist"
-      echo "$url" >"$info"
-      echo "$digest" >>"$info"
-      cat "$info"
+    echo "Image input"
+    cat $hash_key
+    echo "Image input checksum ${cksum}"
+
+    # Print docker version
+    docker --version
+
+    # On non-CI or PR jobs, we don't have permissions to write to the registry cache, so we should
+    # not use `docker login` nor caching.
+    if [[ "$CI" == "" ]] || [[ "$PR_CI_JOB" == "1" ]];
+    then
+        retry docker build --rm -t rust-ci -f "$dockerfile" "$context"
+    else
+        REGISTRY=ghcr.io
+        # Most probably rust-lang-ci, but in general the owner of the repository where CI runs
+        REGISTRY_USERNAME=${GITHUB_REPOSITORY_OWNER}
+        # Tag used to push the final Docker image, so that it can be pulled by e.g. rustup
+        IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci:${cksum}
+        # Tag used to cache the Docker build
+        # It seems that it cannot be the same as $IMAGE_TAG, otherwise it overwrites the cache
+        CACHE_IMAGE_TAG=${REGISTRY}/${REGISTRY_USERNAME}/rust-ci-cache:${cksum}
+
+        # Log into the Docker registry, so that we can read/write cache and the final image
+        echo ${DOCKER_TOKEN} | docker login ${REGISTRY} \
+            --username ${REGISTRY_USERNAME} \
+            --password-stdin
+
+        # Enable a new Docker driver so that --cache-from/to works with a registry backend
+        docker buildx create --use --driver docker-container
+
+        # Build the image using registry caching backend
+        retry docker \
+          buildx \
+          build \
+          --rm \
+          -t rust-ci \
+          -f "$dockerfile" \
+          --cache-from type=registry,ref=${CACHE_IMAGE_TAG} \
+          --cache-to type=registry,ref=${CACHE_IMAGE_TAG},compression=zstd \
+          --output=type=docker \
+          "$context"
+
+        # Print images for debugging purposes
+        docker images
+
+        # Tag the built image and push it to the registry
+        docker tag rust-ci "${IMAGE_TAG}"
+        docker push "${IMAGE_TAG}"
+
+        # Record the container registry tag/url for reuse, e.g. by rustup.rs builds
+        # It should be possible to run `docker pull <$IMAGE_TAG>` to download the image
+        info="$dist/image-$image.txt"
+        mkdir -p "$dist"
+        echo "${IMAGE_TAG}" > "$info"
+        cat "$info"
+
+        echo "To download the image, run docker pull ${IMAGE_TAG}"
     fi
+    echo "::endgroup::"
 elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
     if isCI; then
         echo Cannot run disabled images on CI!
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 68a3afc910f..ceee4690004 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -34,6 +34,7 @@ x--expand-yaml-anchors--remove:
     CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
     # commit of PR sha or commit sha. `GITHUB_SHA` is not accurate for PRs.
     HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
+    DOCKER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
   - &public-variables
     SCCACHE_BUCKET: rust-lang-ci-sccache2
@@ -301,6 +302,7 @@ on:
 
 permissions:
   contents: read
+  packages: write
 
 defaults:
   run:
diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis
index f8569ef2594..5e0c21a13a9 100644
--- a/src/etc/natvis/libcore.natvis
+++ b/src/etc/natvis/libcore.natvis
@@ -41,40 +41,7 @@
     </Expand>
   </Type>
 
-  <Type Name="core::num::nonzero::NonZeroI8">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI16">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI32">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI64">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroI128">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroIsize">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU8">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU16">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU32">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU64">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroU128">
-    <DisplayString>{__0}</DisplayString>
-  </Type>
-  <Type Name="core::num::nonzero::NonZeroUsize">
+  <Type Name="core::num::nonzero::NonZero&lt;*&gt;">
     <DisplayString>{__0}</DisplayString>
   </Type>
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bc3c455f398..1e718c70c3c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -15,6 +15,7 @@ use rustc_ast::token::{Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_attr as attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, IndexEntry};
+use rustc_errors::{codes::*, struct_span_code_err, FatalError};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
@@ -2271,7 +2272,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
         ty::Placeholder(..) => panic!("Placeholder"),
         ty::CoroutineWitness(..) => panic!("CoroutineWitness"),
         ty::Infer(..) => panic!("Infer"),
-        ty::Error(_) => rustc_errors::FatalError.raise(),
+        ty::Error(_) => FatalError.raise(),
     }
 }
 
@@ -2995,7 +2996,7 @@ fn clean_use_statement_inner<'tcx>(
         visibility.is_accessible_from(parent_mod, cx.tcx) && !current_mod.is_top_level_module();
 
     if pub_underscore && let Some(ref inline) = inline_attr {
-        rustc_errors::struct_span_code_err!(
+        struct_span_code_err!(
             cx.tcx.dcx(),
             inline.span(),
             E0780,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7cf385de6b7..9eb62c25892 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::emitter::{DynEmitter, HumanEmitter};
 use rustc_errors::json::JsonEmitter;
-use rustc_errors::TerminalUrl;
+use rustc_errors::{codes::*, TerminalUrl};
 use rustc_feature::UnstableFeatures;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 929efb6c574..96ea063aa74 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -1,11 +1,11 @@
 use super::ARITHMETIC_SIDE_EFFECTS;
 use clippy_utils::consts::{constant, constant_simple, Constant};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::type_diagnostic_name;
+use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
@@ -88,37 +88,44 @@ impl ArithmeticSideEffects {
     }
 
     /// Verifies built-in types that have specific allowed operations
-    fn has_specific_allowed_type_and_operation(
-        cx: &LateContext<'_>,
-        lhs_ty: Ty<'_>,
+    fn has_specific_allowed_type_and_operation<'tcx>(
+        cx: &LateContext<'tcx>,
+        lhs_ty: Ty<'tcx>,
         op: &Spanned<hir::BinOpKind>,
-        rhs_ty: Ty<'_>,
+        rhs_ty: Ty<'tcx>,
     ) -> bool {
         let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
-        let is_non_zero_u = |symbol: Option<Symbol>| {
-            matches!(
-                symbol,
-                Some(
-                    sym::NonZeroU128
-                        | sym::NonZeroU16
-                        | sym::NonZeroU32
-                        | sym::NonZeroU64
-                        | sym::NonZeroU8
-                        | sym::NonZeroUsize
-                )
-            )
+        let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| {
+            let tcx = cx.tcx;
+
+            let ty::Adt(adt, substs) = ty.kind() else { return false };
+
+            if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
+                return false;
+            };
+
+            let int_type = substs.type_at(0);
+            let unsigned_int_types = [
+                tcx.types.u8,
+                tcx.types.u16,
+                tcx.types.u32,
+                tcx.types.u64,
+                tcx.types.u128,
+                tcx.types.usize,
+            ];
+
+            unsigned_int_types.contains(&int_type)
         };
         let is_sat_or_wrap = |ty: Ty<'_>| {
-            let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating);
-            let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping);
-            is_sat || is_wrap
+            is_type_diagnostic_item(cx, ty, sym::Saturating) || is_type_diagnostic_item(cx, ty, sym::Wrapping)
         };
 
-        // If the RHS is NonZeroU*, then division or module by zero will never occur
-        if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem {
+        // If the RHS is `NonZero<u*>`, then division or module by zero will never occur.
+        if is_non_zero_u(cx, rhs_ty) && is_div_or_rem {
             return true;
         }
-        // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module
+
+        // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module.
         if is_sat_or_wrap(lhs_ty) {
             return !is_div_or_rem;
         }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
index 5df645491ff..97068efd43c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
@@ -16,40 +16,55 @@ pub(super) fn check<'tcx>(
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
 ) -> bool {
-    let (ty::Int(_) | ty::Uint(_), Some(to_ty_adt)) = (&from_ty.kind(), to_ty.ty_adt_def()) else {
+    let tcx = cx.tcx;
+
+    let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
         return false;
     };
-    let Some(to_type_sym) = cx.tcx.get_diagnostic_name(to_ty_adt.did()) else {
+
+    if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
         return false;
     };
 
-    if !matches!(
-        to_type_sym,
-        sym::NonZeroU8
-            | sym::NonZeroU16
-            | sym::NonZeroU32
-            | sym::NonZeroU64
-            | sym::NonZeroU128
-            | sym::NonZeroI8
-            | sym::NonZeroI16
-            | sym::NonZeroI32
-            | sym::NonZeroI64
-            | sym::NonZeroI128
-    ) {
+    // FIXME: This can be simplified once `NonZero<T>` is stable.
+    let coercable_types = [
+        ("NonZeroU8", tcx.types.u8),
+        ("NonZeroU16", tcx.types.u16),
+        ("NonZeroU32", tcx.types.u32),
+        ("NonZeroU64", tcx.types.u64),
+        ("NonZeroU128", tcx.types.u128),
+        ("NonZeroUsize", tcx.types.usize),
+        ("NonZeroI8", tcx.types.i8),
+        ("NonZeroI16", tcx.types.i16),
+        ("NonZeroI32", tcx.types.i32),
+        ("NonZeroI64", tcx.types.i64),
+        ("NonZeroI128", tcx.types.i128),
+        ("NonZeroIsize", tcx.types.isize),
+    ];
+
+    let int_type = substs.type_at(0);
+
+    let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
+        if *t == int_type && *t == from_ty {
+            Some(nonzero_alias)
+        } else {
+            None
+        }
+    }) else {
         return false;
-    }
+    };
 
     span_lint_and_then(
         cx,
         TRANSMUTE_INT_TO_NON_ZERO,
         e.span,
-        &format!("transmute from a `{from_ty}` to a `{to_type_sym}`"),
+        &format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
         |diag| {
             let arg = sugg::Sugg::hir(cx, arg, "..");
             diag.span_suggestion(
                 e.span,
                 "consider using",
-                format!("{to_type_sym}::{}({arg})", sym::new_unchecked),
+                format!("{nonzero_alias}::{}({arg})", sym::new_unchecked),
                 Applicability::Unspecified,
             );
         },
diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml
index 76c2e330b21..f4dac6e947e 100644
--- a/src/tools/error_index_generator/Cargo.toml
+++ b/src/tools/error_index_generator/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
 
 [dependencies]
 mdbook = { version = "0.4", default-features = false, features = ["search"] }
-rustc_error_codes = { version = "0.0.0", path = "../../../compiler/rustc_error_codes" }
 
 [[bin]]
 name = "error_index_generator"
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 865d7172cd3..2de2d959a95 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -4,13 +4,15 @@ extern crate rustc_driver;
 extern crate rustc_log;
 extern crate rustc_session;
 
+extern crate rustc_errors;
+use rustc_errors::codes::DIAGNOSTICS;
+
 use std::env;
 use std::error::Error;
 use std::fs::{self, File};
 use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
-
 use std::str::FromStr;
 
 use mdbook::book::{parse_summary, BookItem, Chapter};
@@ -38,7 +40,7 @@ fn render_markdown(output_path: &Path) -> Result<(), Box<dyn Error>> {
 
     write!(output_file, "# Rust Compiler Error Index\n")?;
 
-    for (err_code, description) in rustc_error_codes::DIAGNOSTICS.iter() {
+    for (err_code, description) in DIAGNOSTICS.iter() {
         write!(output_file, "## {}\n{}\n", err_code, description)?
     }
 
@@ -85,7 +87,7 @@ This page lists all the error codes emitted by the Rust compiler.
 "
     );
 
-    let err_codes = rustc_error_codes::DIAGNOSTICS;
+    let err_codes = DIAGNOSTICS;
     let mut chapters = Vec::with_capacity(err_codes.len());
 
     for (err_code, explanation) in err_codes.iter() {
diff --git a/src/tools/miri/.github/workflows/sysroots.yml b/src/tools/miri/.github/workflows/sysroots.yml
index 509521e7478..96d7d4d1118 100644
--- a/src/tools/miri/.github/workflows/sysroots.yml
+++ b/src/tools/miri/.github/workflows/sysroots.yml
@@ -1,8 +1,8 @@
 name: Tier 2 sysroots
 
-on: push
-#  schedule:
-#    - cron: '44 4 * * *' # At 4:44 UTC every day.
+on:
+  schedule:
+    - cron: '44 4 * * *' # At 4:44 UTC every day.
 
 defaults:
   run:
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index 6cd22a91518..8cd996d8564 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -486,9 +486,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
 
 [[package]]
 name = "measureme"
-version = "10.1.2"
+version = "11.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45e381dcdad44c3c435f8052b08c5c4a1449c48ab56f312345eae12d7a693dbe"
+checksum = "dfa4a40f09af7aa6faef38285402a78847d0d72bf8827006cd2a332e1e6e4a8d"
 dependencies = [
  "log",
  "memmap2",
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 3dee742fa0d..6695f123c78 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -590,6 +590,7 @@ Definite bugs found:
 * [Incorrect use of `compare_exchange_weak` in `once_cell`](https://github.com/matklad/once_cell/issues/186)
 * [Dropping with unaligned pointers in `vec::IntoIter`](https://github.com/rust-lang/rust/pull/106084)
 * [Deallocating with the wrong layout in new specializations for in-place `Iterator::collect`](https://github.com/rust-lang/rust/pull/118460)
+* [Incorrect offset computation for highly-aligned types in `portable-atomic-util`](https://github.com/taiki-e/portable-atomic/pull/138)
 
 Violations of [Stacked Borrows] found that are likely bugs (but Stacked Borrows is currently just an experiment):
 
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index a7412f90c85..79ce1f4ca32 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -501,11 +501,10 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
     // Set missing env vars. We prefer build-time env vars over run-time ones; see
     // <https://github.com/rust-lang/miri/issues/1661> for the kind of issue that fixes.
     for (name, val) in info.env {
-        // `CARGO_MAKEFLAGS` contains information about how to reach the
-        // jobserver, but by the time the program is being run, that jobserver
-        // no longer exists. Hence we shouldn't forward this.
-        // FIXME: Miri builds the final crate without a jobserver.
-        // This may be fixed with github.com/rust-lang/cargo/issues/12597.
+        // `CARGO_MAKEFLAGS` contains information about how to reach the jobserver, but by the time
+        // the program is being run, that jobserver no longer exists (cargo only runs the jobserver
+        // for the build portion of `cargo run`/`cargo test`). Hence we shouldn't forward this.
+        // Also see <https://github.com/rust-lang/rust/pull/113730>.
         if name == "CARGO_MAKEFLAGS" {
             continue;
         }
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 548e12ffdea..6624672775f 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-5bcd86d89b2b7b6a490f7e075dd4eb346deb5f98
+dd2559e08e1530806740931037d6bb83ef956161
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 905b2fc4d60..d6b1e135808 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -217,7 +217,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
     /// Helper function to get a `windows` constant as a `Scalar`.
     fn eval_windows(&self, module: &str, name: &str) -> Scalar<Provenance> {
-        self.eval_context_ref().eval_path_scalar(&["std", "sys", "pal","windows", module, name])
+        self.eval_context_ref().eval_path_scalar(&["std", "sys", "pal", "windows", module, name])
     }
 
     /// Helper function to get a `windows` constant as a `u32`.
@@ -249,7 +249,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn windows_ty_layout(&self, name: &str) -> TyAndLayout<'tcx> {
         let this = self.eval_context_ref();
         let ty = this
-            .resolve_path(&["std", "sys", "pal","windows", "c", name], Namespace::TypeNS)
+            .resolve_path(&["std", "sys", "pal", "windows", "c", name], Namespace::TypeNS)
             .ty(*this.tcx, ty::ParamEnv::reveal_all());
         this.layout_of(ty).unwrap()
     }
@@ -270,6 +270,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         bug!("No field named {} in type {}", name, base.layout().ty);
     }
 
+    /// Search if `base` (which must be a struct or union type) contains the `name` field.
+    fn projectable_has_field<P: Projectable<'tcx, Provenance>>(
+        &self,
+        base: &P,
+        name: &str,
+    ) -> bool {
+        let adt = base.layout().ty.ty_adt_def().unwrap();
+        for field in adt.non_enum_variant().fields.iter() {
+            if field.name.as_str() == name {
+                return true;
+            }
+        }
+        false
+    }
+
     /// Write an int of the appropriate size to `dest`. The target type may be signed or unsigned,
     /// we try to do the right thing anyway. `i128` can fit all integer types except for `u128` so
     /// this method is fine for almost all integer types.
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index b0b6d994366..057b883a3bf 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -94,7 +94,6 @@ pub use crate::shims::os_str::EvalContextExt as _;
 pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
 pub use crate::shims::time::EvalContextExt as _;
 pub use crate::shims::tls::TlsData;
-pub use crate::shims::EvalContextExt as _;
 
 pub use crate::borrow_tracker::stacked_borrows::{
     EvalContextExt as _, Item, Permission, Stack, Stacks,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 4cd48b2e5a3..946887637ff 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -10,8 +10,8 @@ use std::process;
 
 use either::Either;
 use rand::rngs::StdRng;
-use rand::SeedableRng;
 use rand::Rng;
+use rand::SeedableRng;
 
 use rustc_ast::ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -83,7 +83,8 @@ pub struct FrameExtra<'tcx> {
 impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         // Omitting `timing`, it does not support `Debug`.
-        let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant: _, salt: _ } = self;
+        let FrameExtra { borrow_tracker, catch_unwind, timing: _, is_user_relevant: _, salt: _ } =
+            self;
         f.debug_struct("FrameData")
             .field("borrow_tracker", borrow_tracker)
             .field("catch_unwind", catch_unwind)
@@ -93,7 +94,8 @@ impl<'tcx> std::fmt::Debug for FrameExtra<'tcx> {
 
 impl VisitProvenance for FrameExtra<'_> {
     fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
-        let FrameExtra { catch_unwind, borrow_tracker, timing: _, is_user_relevant: _, salt: _ } = self;
+        let FrameExtra { catch_unwind, borrow_tracker, timing: _, is_user_relevant: _, salt: _ } =
+            self;
 
         catch_unwind.visit_provenance(visit);
         borrow_tracker.visit_provenance(visit);
@@ -710,7 +712,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
         Ok(())
     }
 
-    fn add_extern_static(
+    pub(crate) fn add_extern_static(
         this: &mut MiriInterpCx<'mir, 'tcx>,
         name: &str,
         ptr: Pointer<Option<Provenance>>,
@@ -720,75 +722,6 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
         this.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
     }
 
-    fn alloc_extern_static(
-        this: &mut MiriInterpCx<'mir, 'tcx>,
-        name: &str,
-        val: ImmTy<'tcx, Provenance>,
-    ) -> InterpResult<'tcx> {
-        let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
-        this.write_immediate(*val, &place)?;
-        Self::add_extern_static(this, name, place.ptr());
-        Ok(())
-    }
-
-    /// Sets up the "extern statics" for this machine.
-    fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
-        // "__rust_no_alloc_shim_is_unstable"
-        let val = ImmTy::from_int(0, this.machine.layouts.u8);
-        Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;
-
-        match this.tcx.sess.target.os.as_ref() {
-            "linux" => {
-                // "environ"
-                Self::add_extern_static(
-                    this,
-                    "environ",
-                    this.machine.env_vars.environ.as_ref().unwrap().ptr(),
-                );
-                // A couple zero-initialized pointer-sized extern statics.
-                // Most of them are for weak symbols, which we all set to null (indicating that the
-                // symbol is not supported, and triggering fallback code which ends up calling a
-                // syscall that we do support).
-                for name in &["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"]
-                {
-                    let val = ImmTy::from_int(0, this.machine.layouts.usize);
-                    Self::alloc_extern_static(this, name, val)?;
-                }
-            }
-            "freebsd" => {
-                // "environ"
-                Self::add_extern_static(
-                    this,
-                    "environ",
-                    this.machine.env_vars.environ.as_ref().unwrap().ptr(),
-                );
-            }
-            "android" => {
-                // "signal" -- just needs a non-zero pointer value (function does not even get called),
-                // but we arrange for this to be callable anyway (it will then do nothing).
-                let layout = this.machine.layouts.const_raw_ptr;
-                let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
-                let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
-                Self::alloc_extern_static(this, "signal", val)?;
-                // A couple zero-initialized pointer-sized extern statics.
-                // Most of them are for weak symbols, which we all set to null (indicating that the
-                // symbol is not supported, and triggering fallback code.)
-                for name in &["bsd_signal"] {
-                    let val = ImmTy::from_int(0, this.machine.layouts.usize);
-                    Self::alloc_extern_static(this, name, val)?;
-                }
-            }
-            "windows" => {
-                // "_tls_used"
-                // This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
-                let val = ImmTy::from_int(0, this.machine.layouts.u8);
-                Self::alloc_extern_static(this, "_tls_used", val)?;
-            }
-            _ => {} // No "extern statics" supported on this target
-        }
-        Ok(())
-    }
-
     pub(crate) fn communicate(&self) -> bool {
         self.isolated_op == IsolatedOp::Allow
     }
@@ -1009,7 +942,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
-        ecx.find_mir_or_eval_fn(instance, abi, args, dest, ret, unwind)
+        // For foreign items, try to see if we can emulate them.
+        if ecx.tcx.is_foreign_item(instance.def_id()) {
+            // An external function call that does not have a MIR body. We either find MIR elsewhere
+            // or emulate its effect.
+            // This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
+            // to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
+            // foreign function
+            // Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
+            let args = ecx.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
+            let link_name = ecx.item_link_name(instance.def_id());
+            return ecx.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
+        }
+
+        // Otherwise, load the MIR.
+        Ok(Some((ecx.load_mir(instance.def, None)?, instance)))
     }
 
     #[inline(always)]
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 14076444696..6f19dead2e9 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         Ok(match bin_op {
             Eq | Ne | Lt | Le | Gt | Ge => {
-                assert_eq!(left.layout.abi, right.layout.abi); // types an differ, e.g. fn ptrs with different `for`
+                assert_eq!(left.layout.abi, right.layout.abi); // types can differ, e.g. fn ptrs with different `for`
                 let size = this.pointer_size();
                 // Just compare the bits. ScalarPairs are compared lexicographically.
                 // We thus always compare pairs and simply fill scalars up with 0.
diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs
new file mode 100644
index 00000000000..0284e5b606c
--- /dev/null
+++ b/src/tools/miri/src/shims/extern_static.rs
@@ -0,0 +1,79 @@
+//! Provides the `extern static` that this platform expects.
+
+use crate::*;
+
+impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
+    fn alloc_extern_static(
+        this: &mut MiriInterpCx<'mir, 'tcx>,
+        name: &str,
+        val: ImmTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx> {
+        let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
+        this.write_immediate(*val, &place)?;
+        Self::add_extern_static(this, name, place.ptr());
+        Ok(())
+    }
+
+    /// Zero-initialized pointer-sized extern statics are pretty common.
+    /// Most of them are for weak symbols, which we all set to null (indicating that the
+    /// symbol is not supported, and triggering fallback code which ends up calling a
+    /// syscall that we do support).
+    fn null_ptr_extern_statics(
+        this: &mut MiriInterpCx<'mir, 'tcx>,
+        names: &[&str],
+    ) -> InterpResult<'tcx> {
+        for name in names {
+            let val = ImmTy::from_int(0, this.machine.layouts.usize);
+            Self::alloc_extern_static(this, name, val)?;
+        }
+        Ok(())
+    }
+
+    /// Sets up the "extern statics" for this machine.
+    pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
+        // "__rust_no_alloc_shim_is_unstable"
+        let val = ImmTy::from_int(0, this.machine.layouts.u8);
+        Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;
+
+        match this.tcx.sess.target.os.as_ref() {
+            "linux" => {
+                Self::null_ptr_extern_statics(
+                    this,
+                    &["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"],
+                )?;
+                // "environ"
+                Self::add_extern_static(
+                    this,
+                    "environ",
+                    this.machine.env_vars.environ.as_ref().unwrap().ptr(),
+                );
+            }
+            "freebsd" => {
+                Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?;
+                // "environ"
+                Self::add_extern_static(
+                    this,
+                    "environ",
+                    this.machine.env_vars.environ.as_ref().unwrap().ptr(),
+                );
+            }
+            "android" => {
+                Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
+                // "signal" -- just needs a non-zero pointer value (function does not even get called),
+                // but we arrange for this to call the `signal` function anyway.
+                let layout = this.machine.layouts.const_raw_ptr;
+                let ptr = this.fn_ptr(FnVal::Other(DynSym::from_str("signal")));
+                let val = ImmTy::from_scalar(Scalar::from_pointer(ptr, this), layout);
+                Self::alloc_extern_static(this, "signal", val)?;
+            }
+            "windows" => {
+                // "_tls_used"
+                // This is some obscure hack that is part of the Windows TLS story. It's a `u8`.
+                let val = ImmTy::from_int(0, this.machine.layouts.u8);
+                Self::alloc_extern_static(this, "_tls_used", val)?;
+            }
+            _ => {} // No "extern statics" supported on this target
+        }
+        Ok(())
+    }
+}
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index 8edc0a4220d..e34fb118f72 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -148,7 +148,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // ```
             // Would not be considered UB, or the other way around (`is_val_statically_known(0)`).
             "is_val_statically_known" => {
-                let [_] = check_arg_count(args)?;
+                let [arg] = check_arg_count(args)?;
+                this.validate_operand(arg)?;
                 let branch: bool = this.machine.rng.get_mut().gen();
                 this.write_scalar(Scalar::from_bool(branch), dest)?;
             }
diff --git a/src/tools/miri/src/shims/mod.rs b/src/tools/miri/src/shims/mod.rs
index 1e9d927e1a9..ea6120f7579 100644
--- a/src/tools/miri/src/shims/mod.rs
+++ b/src/tools/miri/src/shims/mod.rs
@@ -10,48 +10,8 @@ pub mod windows;
 mod x86;
 
 pub mod env;
+pub mod extern_static;
 pub mod os_str;
 pub mod panic;
 pub mod time;
 pub mod tls;
-
-// End module management, begin local code
-
-use log::trace;
-
-use rustc_middle::{mir, ty};
-use rustc_target::spec::abi::Abi;
-
-use crate::*;
-
-impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    fn find_mir_or_eval_fn(
-        &mut self,
-        instance: ty::Instance<'tcx>,
-        abi: Abi,
-        args: &[FnArg<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
-        ret: Option<mir::BasicBlock>,
-        unwind: mir::UnwindAction,
-    ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
-        let this = self.eval_context_mut();
-        trace!("eval_fn_call: {:#?}, {:?}", instance, dest);
-
-        // For foreign items, try to see if we can emulate them.
-        if this.tcx.is_foreign_item(instance.def_id()) {
-            // An external function call that does not have a MIR body. We either find MIR elsewhere
-            // or emulate its effect.
-            // This will be Ok(None) if we're emulating the intrinsic entirely within Miri (no need
-            // to run extra MIR), and Ok(Some(body)) if we found MIR to run for the
-            // foreign function
-            // Any needed call to `goto_block` will be performed by `emulate_foreign_item`.
-            let args = this.copy_fn_args(args)?; // FIXME: Should `InPlace` arguments be reset to uninit?
-            let link_name = this.item_link_name(instance.def_id());
-            return this.emulate_foreign_item(link_name, abi, &args, dest, ret, unwind);
-        }
-
-        // Otherwise, load the MIR.
-        Ok(Some((this.load_mir(instance.def, None)?, instance)))
-    }
-}
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 23342c8045e..35036ce078d 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -155,6 +155,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             }
             "lseek64" => {
                 let [fd, offset, whence] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let fd = this.read_scalar(fd)?.to_i32()?;
+                let offset = this.read_scalar(offset)?.to_i64()?;
+                let whence = this.read_scalar(whence)?.to_i32()?;
+                let result = this.lseek64(fd, offset.into(), whence)?;
+                this.write_scalar(result, dest)?;
+            }
+            "lseek" => {
+                let [fd, offset, whence] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let fd = this.read_scalar(fd)?.to_i32()?;
+                let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
+                let whence = this.read_scalar(whence)?.to_i32()?;
                 let result = this.lseek64(fd, offset, whence)?;
                 this.write_scalar(result, dest)?;
             }
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index 7c843e106ea..64094ac307d 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -3,6 +3,7 @@ use rustc_target::spec::abi::Abi;
 
 use crate::*;
 use shims::foreign_items::EmulateForeignItemResult;
+use shims::unix::fs::EvalContextExt as _;
 use shims::unix::thread::EvalContextExt as _;
 
 pub fn is_dyn_sym(_name: &str) -> bool {
@@ -63,6 +64,33 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
             }
 
+            // File related shims
+            // For those, we both intercept `func` and `call@FBSD_1.0` symbols cases
+            // since freebsd 12 the former form can be expected.
+            "stat" | "stat@FBSD_1.0" => {
+                let [path, buf] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.macos_fbsd_stat(path, buf)?;
+                this.write_scalar(result, dest)?;
+            }
+            "lstat" | "lstat@FBSD_1.0" => {
+                let [path, buf] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.macos_fbsd_lstat(path, buf)?;
+                this.write_scalar(result, dest)?;
+            }
+            "fstat" | "fstat@FBSD_1.0" => {
+                let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.macos_fbsd_fstat(fd, buf)?;
+                this.write_scalar(result, dest)?;
+            }
+            "readdir_r" | "readdir_r@FBSD_1.0" => {
+                let [dirp, entry, result] =
+                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
+                this.write_scalar(result, dest)?;
+            }
+
             // errno
             "__error" => {
                 let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index 99d8a3a2c91..53f975baa89 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -813,24 +813,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
     fn lseek64(
         &mut self,
-        fd_op: &OpTy<'tcx, Provenance>,
-        offset_op: &OpTy<'tcx, Provenance>,
-        whence_op: &OpTy<'tcx, Provenance>,
+        fd: i32,
+        offset: i128,
+        whence: i32,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
         // Isolation check is done via `FileDescriptor` trait.
 
-        let fd = this.read_scalar(fd_op)?.to_i32()?;
-        let offset = this.read_scalar(offset_op)?.to_i64()?;
-        let whence = this.read_scalar(whence_op)?.to_i32()?;
-
         let seek_from = if whence == this.eval_libc_i32("SEEK_SET") {
             SeekFrom::Start(u64::try_from(offset).unwrap())
         } else if whence == this.eval_libc_i32("SEEK_CUR") {
-            SeekFrom::Current(offset)
+            SeekFrom::Current(i64::try_from(offset).unwrap())
         } else if whence == this.eval_libc_i32("SEEK_END") {
-            SeekFrom::End(offset)
+            SeekFrom::End(i64::try_from(offset).unwrap())
         } else {
             let einval = this.eval_libc("EINVAL");
             this.set_last_error(einval)?;
@@ -897,13 +893,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         this.try_unwrap_io_result(result)
     }
 
-    fn macos_stat(
+    fn macos_fbsd_stat(
         &mut self,
         path_op: &OpTy<'tcx, Provenance>,
         buf_op: &OpTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
-        this.assert_target_os("macos", "stat");
+
+        if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
+            panic!("`macos_fbsd_stat` should not be called on {}", this.tcx.sess.target.os);
+        }
 
         let path_scalar = this.read_pointer(path_op)?;
         let path = this.read_path_from_c_str(path_scalar)?.into_owned();
@@ -926,13 +925,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     }
 
     // `lstat` is used to get symlink metadata.
-    fn macos_lstat(
+    fn macos_fbsd_lstat(
         &mut self,
         path_op: &OpTy<'tcx, Provenance>,
         buf_op: &OpTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
-        this.assert_target_os("macos", "lstat");
+
+        if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
+            panic!("`macos_fbsd_lstat` should not be called on {}", this.tcx.sess.target.os);
+        }
 
         let path_scalar = this.read_pointer(path_op)?;
         let path = this.read_path_from_c_str(path_scalar)?.into_owned();
@@ -953,14 +955,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(Scalar::from_i32(this.macos_stat_write_buf(metadata, buf_op)?))
     }
 
-    fn macos_fstat(
+    fn macos_fbsd_fstat(
         &mut self,
         fd_op: &OpTy<'tcx, Provenance>,
         buf_op: &OpTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
-        this.assert_target_os("macos", "fstat");
+        if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
+            panic!("`macos_fbsd_fstat` should not be called on {}", this.tcx.sess.target.os);
+        }
 
         let fd = this.read_scalar(fd_op)?.to_i32()?;
 
@@ -1199,7 +1203,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let this = self.eval_context_mut();
 
         #[cfg_attr(not(unix), allow(unused_variables))]
-        let mode = if this.tcx.sess.target.os == "macos" {
+        let mode = if matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
             u32::from(this.read_scalar(mode_op)?.to_u16()?)
         } else {
             this.read_scalar(mode_op)?.to_u32()?
@@ -1371,7 +1375,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         Ok(Scalar::from_maybe_pointer(entry, this))
     }
 
-    fn macos_readdir_r(
+    fn macos_fbsd_readdir_r(
         &mut self,
         dirp_op: &OpTy<'tcx, Provenance>,
         entry_op: &OpTy<'tcx, Provenance>,
@@ -1379,7 +1383,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
-        this.assert_target_os("macos", "readdir_r");
+        if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
+            panic!("`macos_fbsd_readdir_r` should not be called on {}", this.tcx.sess.target.os);
+        }
 
         let dirp = this.read_target_usize(dirp_op)?;
 
@@ -1410,7 +1416,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 // }
 
                 let entry_place = this.deref_pointer_as(entry_op, this.libc_ty_layout("dirent"))?;
-                let name_place = this.project_field(&entry_place, 5)?;
+                let name_place = this.project_field_named(&entry_place, "d_name")?;
 
                 let file_name = dir_entry.file_name(); // not a Path as there are no separators!
                 let (name_fits, file_name_buf_len) = this.write_os_str_to_c_str(
@@ -1434,16 +1440,41 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
                 let file_type = this.file_type_to_d_type(dir_entry.file_type())?;
 
-                this.write_int_fields_named(
-                    &[
-                        ("d_ino", ino.into()),
-                        ("d_seekoff", 0),
-                        ("d_reclen", 0),
-                        ("d_namlen", file_name_len.into()),
-                        ("d_type", file_type.into()),
-                    ],
-                    &entry_place,
-                )?;
+                // macOS offset field is d_seekoff
+                if this.projectable_has_field(&entry_place, "d_seekoff") {
+                    this.write_int_fields_named(
+                        &[
+                            ("d_ino", ino.into()),
+                            ("d_seekoff", 0),
+                            ("d_reclen", 0),
+                            ("d_namlen", file_name_len.into()),
+                            ("d_type", file_type.into()),
+                        ],
+                        &entry_place,
+                    )?;
+                } else if this.projectable_has_field(&entry_place, "d_off") {
+                    // freebsd 12 and onwards had added the d_off field
+                    this.write_int_fields_named(
+                        &[
+                            ("d_fileno", ino.into()),
+                            ("d_off", 0),
+                            ("d_reclen", 0),
+                            ("d_type", file_type.into()),
+                            ("d_namlen", file_name_len.into()),
+                        ],
+                        &entry_place,
+                    )?;
+                } else {
+                    this.write_int_fields_named(
+                        &[
+                            ("d_fileno", ino.into()),
+                            ("d_reclen", 0),
+                            ("d_type", file_type.into()),
+                            ("d_namlen", file_name_len.into()),
+                        ],
+                        &entry_place,
+                    )?;
+                }
 
                 let result_place = this.deref_pointer(result_op)?;
                 this.write_scalar(this.read_scalar(entry_op)?, &result_place)?;
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index 07e19cadd6e..ecc07e28a29 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -40,18 +40,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "stat" | "stat64" | "stat$INODE64" => {
                 let [path, buf] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let result = this.macos_stat(path, buf)?;
+                let result = this.macos_fbsd_stat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "lstat" | "lstat64" | "lstat$INODE64" => {
                 let [path, buf] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let result = this.macos_lstat(path, buf)?;
+                let result = this.macos_fbsd_lstat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "fstat" | "fstat64" | "fstat$INODE64" => {
                 let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let result = this.macos_fstat(fd, buf)?;
+                let result = this.macos_fbsd_fstat(fd, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "opendir$INODE64" => {
@@ -62,14 +62,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "readdir_r" | "readdir_r$INODE64" => {
                 let [dirp, entry, result] =
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                let result = this.macos_readdir_r(dirp, entry, result)?;
-                this.write_scalar(result, dest)?;
-            }
-            "lseek" => {
-                let [fd, offset, whence] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                // macOS is 64bit-only, so this is lseek64
-                let result = this.lseek64(fd, offset, whence)?;
+                let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
                 this.write_scalar(result, dest)?;
             }
             "realpath$DARWIN_EXTSN" => {
diff --git a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
index adfece58661..5185db0b0e2 100644
--- a/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
+++ b/src/tools/miri/tests/pass-dep/shims/libc-fs-with-isolation.rs
@@ -1,5 +1,4 @@
 //@ignore-target-windows: no libc on Windows
-//@ignore-target-freebsd: FIXME needs foreign function `stat@FBSD_1.0`
 //@compile-flags: -Zmiri-isolation-error=warn-nobacktrace
 //@normalize-stderr-test: "(stat(x)?)" -> "$$STAT"
 
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index 094efa981d3..6fc65e56901 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -2,7 +2,7 @@
 //!
 //! Overview of check:
 //!
-//! 1. We create a list of error codes used by the compiler. Error codes are extracted from `compiler/rustc_error_codes/src/error_codes.rs`.
+//! 1. We create a list of error codes used by the compiler. Error codes are extracted from `compiler/rustc_error_codes/src/lib.rs`.
 //!
 //! 2. We check that the error code has a long-form explanation in `compiler/rustc_error_codes/src/error_codes/`.
 //!   - The explanation is expected to contain a `doctest` that fails with the correct error code. (`EXEMPT_FROM_DOCTEST` *currently* bypasses this check)
@@ -22,7 +22,7 @@ use regex::Regex;
 
 use crate::walk::{filter_dirs, walk, walk_many};
 
-const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/error_codes.rs";
+const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/lib.rs";
 const ERROR_DOCS_PATH: &str = "compiler/rustc_error_codes/src/error_codes/";
 const ERROR_TESTS_PATH: &str = "tests/ui/error-codes/";
 
@@ -80,13 +80,14 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
         if line.starts_with('E') {
             let split_line = line.split_once(':');
 
-            // Extract the error code from the line, emitting a fatal error if it is not in a correct format.
+            // Extract the error code from the line. Emit a fatal error if it is not in the correct
+            // format.
             let err_code = if let Some(err_code) = split_line {
                 err_code.0.to_owned()
             } else {
                 errors.push(format!(
-                    "Expected a line with the format `Exxxx: include_str!(\"..\")`, but got \"{}\" \
-                    without a `:` delimiter",
+                    "Expected a line with the format `Eabcd: abcd, \
+                    but got \"{}\" without a `:` delimiter",
                     line,
                 ));
                 continue;
@@ -98,12 +99,16 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String
                 continue;
             }
 
+            let mut chars = err_code.chars();
+            chars.next();
+            let error_num_as_str = chars.as_str();
+
             // Ensure that the line references the correct markdown file.
-            let expected_filename = format!(" include_str!(\"./error_codes/{}.md\"),", err_code);
+            let expected_filename = format!(" {},", error_num_as_str);
             if expected_filename != split_line.unwrap().1 {
                 errors.push(format!(
-                    "Error code `{}` expected to reference docs with `{}` but instead found `{}` in \
-                    `compiler/rustc_error_codes/src/error_codes.rs`",
+                    "`{}:` should be followed by `{}` but instead found `{}` in \
+                    `compiler/rustc_error_codes/src/lib.rs`",
                     err_code,
                     expected_filename,
                     split_line.unwrap().1,
@@ -311,13 +316,8 @@ fn check_error_codes_used(
     no_longer_emitted: &[String],
     verbose: bool,
 ) {
-    // We want error codes which match the following cases:
-    //
-    // * foo(a, E0111, a)
-    // * foo(a, E0111)
-    // * foo(E0111, a)
-    // * #[error = "E0111"]
-    let regex = Regex::new(r#"[(,"\s](E\d{4})[,)"]"#).unwrap();
+    // Search for error codes in the form `E0123`.
+    let regex = Regex::new(r#"\bE\d{4}\b"#).unwrap();
 
     let mut found_codes = Vec::new();
 
@@ -336,12 +336,12 @@ fn check_error_codes_used(
             }
 
             for cap in regex.captures_iter(line) {
-                if let Some(error_code) = cap.get(1) {
+                if let Some(error_code) = cap.get(0) {
                     let error_code = error_code.as_str().to_owned();
 
                     if !error_codes.contains(&error_code) {
                         // This error code isn't properly defined, we must error.
-                        errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/error_codes.rs`.", error_code));
+                        errors.push(format!("Error code `{}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/lib.rs`.", error_code));
                         continue;
                     }
 
diff --git a/tests/debuginfo/msvc-pretty-enums.rs b/tests/debuginfo/msvc-pretty-enums.rs
index d66e4c660f7..400e8801ca2 100644
--- a/tests/debuginfo/msvc-pretty-enums.rs
+++ b/tests/debuginfo/msvc-pretty-enums.rs
@@ -46,12 +46,12 @@
 // cdb-check:    [+0x000] __0              : 0x2a [Type: unsigned int]
 
 // cdb-command: dx niche128_some
-// cdb-check: niche128_some    : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// cdb-check: niche128_some    : Some [Type: enum2$<core::option::Option<core::num::nonzero::NonZero<i128> > >]
 // Note: we can't actually read the value of the field because CDB cannot handle 128 bit integers.
-// cdb-check:    [+0x000] __0 [...] [Type: core::num::nonzero::NonZeroI128]
+// cdb-check:    [+0x000] __0 [...] [Type: core::num::nonzero::NonZero<i128>]
 
 // cdb-command: dx niche128_none
-// cdb-check: niche128_none    : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZeroI128> >]
+// cdb-check: niche128_none    : None [Type: enum2$<core::option::Option<core::num::nonzero::NonZero<i128> > >]
 
 // cdb-command: dx wrapping_niche128_untagged
 // cdb-check: wrapping_niche128_untagged : X [Type: enum2$<msvc_pretty_enums::Wrapping128Niche>]
@@ -84,7 +84,7 @@
 
 // cdb-command: dx niche_w_fields_2_some,d
 // cdb-check: niche_w_fields_2_some,d : A [Type: enum2$<msvc_pretty_enums::NicheLayoutWithFields2>]
-// cdb-check:     [+0x[...]] __0              : 800 [Type: core::num::nonzero::NonZeroU32]
+// cdb-check:     [+0x[...]] __0              : 800 [Type: core::num::nonzero::NonZero<u32>]
 // cdb-check:     [+0x[...]] __1              : 900 [Type: unsigned __int64]
 
 // cdb-command: dx niche_w_fields_2_none,d
diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs
index c122112e6c7..a1b5ae792a1 100644
--- a/tests/debuginfo/numeric-types.rs
+++ b/tests/debuginfo/numeric-types.rs
@@ -3,59 +3,59 @@
 // min-gdb-version: 8.1
 // ignore-windows-gnu // emit_debug_gdb_scripts is disabled on Windows
 
-// Tests the visualizations for `NonZero{I,U}{8,16,32,64,128,size}`, `Wrapping<T>` and
+// Tests the visualizations for `NonZero<T>`, `Wrapping<T>` and
 // `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`.
 
 // === CDB TESTS ==================================================================================
 // cdb-command: g
 
 // cdb-command: dx nz_i8
-// cdb-check:nz_i8            : 11 [Type: core::num::nonzero::NonZeroI8]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI8]
+// cdb-check:nz_i8            : 11 [Type: core::num::nonzero::NonZero<i8>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i8>]
 
 // cdb-command: dx nz_i16
-// cdb-check:nz_i16           : 22 [Type: core::num::nonzero::NonZeroI16]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI16]
+// cdb-check:nz_i16           : 22 [Type: core::num::nonzero::NonZero<i16>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i16>]
 
 // cdb-command: dx nz_i32
-// cdb-check:nz_i32           : 33 [Type: core::num::nonzero::NonZeroI32]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI32]
+// cdb-check:nz_i32           : 33 [Type: core::num::nonzero::NonZero<i32>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i32>]
 
 // cdb-command: dx nz_i64
-// cdb-check:nz_i64           : 44 [Type: core::num::nonzero::NonZeroI64]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI64]
+// cdb-check:nz_i64           : 44 [Type: core::num::nonzero::NonZero<i64>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i64>]
 
 // 128-bit integers don't seem to work in CDB
 // cdb-command: dx nz_i128
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroI128]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<i128>]
 
 // cdb-command: dx nz_isize
-// cdb-check:nz_isize         : 66 [Type: core::num::nonzero::NonZeroIsize]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroIsize]
+// cdb-check:nz_isize         : 66 [Type: core::num::nonzero::NonZero<isize>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<isize>]
 
 // cdb-command: dx nz_u8
-// cdb-check:nz_u8            : 0x4d [Type: core::num::nonzero::NonZeroU8]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU8]
+// cdb-check:nz_u8            : 0x4d [Type: core::num::nonzero::NonZero<u8>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u8>]
 
 // cdb-command: dx nz_u16
-// cdb-check:nz_u16           : 0x58 [Type: core::num::nonzero::NonZeroU16]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU16]
+// cdb-check:nz_u16           : 0x58 [Type: core::num::nonzero::NonZero<u16>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u16>]
 
 // cdb-command: dx nz_u32
-// cdb-check:nz_u32           : 0x63 [Type: core::num::nonzero::NonZeroU32]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU32]
+// cdb-check:nz_u32           : 0x63 [Type: core::num::nonzero::NonZero<u32>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u32>]
 
 // cdb-command: dx nz_u64
-// cdb-check:nz_u64           : 0x64 [Type: core::num::nonzero::NonZeroU64]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU64]
+// cdb-check:nz_u64           : 0x64 [Type: core::num::nonzero::NonZero<u64>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u64>]
 
 // 128-bit integers don't seem to work in CDB
 // cdb-command: dx nz_u128
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroU128]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<u128>]
 
 // cdb-command: dx nz_usize
-// cdb-check:nz_usize         : 0x7a [Type: core::num::nonzero::NonZeroUsize]
-// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZeroUsize]
+// cdb-check:nz_usize         : 0x7a [Type: core::num::nonzero::NonZero<usize>]
+// cdb-check:    [<Raw View>]     [Type: core::num::nonzero::NonZero<usize>]
 
 // cdb-command: dx w_i8
 // cdb-check:w_i8             : 10 [Type: core::num::wrapping::Wrapping<i8>]
diff --git a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff b/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff
index cb623e83f52..be7f9cd4412 100644
--- a/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff
+++ b/tests/mir-opt/instsimplify/combine_transmutes.adt_transmutes.InstSimplify.diff
@@ -4,7 +4,7 @@
   fn adt_transmutes() -> () {
       let mut _0: ();
       let _1: u8;
-      let mut _2: std::option::Option<std::num::NonZeroU8>;
+      let mut _2: std::option::Option<std::num::NonZero<u8>>;
       let mut _4: std::num::Wrapping<i16>;
       let mut _6: std::num::Wrapping<i16>;
       let mut _8: Union32;
@@ -37,7 +37,7 @@
       bb0: {
           StorageLive(_1);
           StorageLive(_2);
-          _2 = Option::<NonZeroU8>::Some(const _);
+          _2 = Option::<NonZero<u8>>::Some(const _);
           _1 = move _2 as u8 (Transmute);
           StorageDead(_2);
           StorageLive(_3);
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index f553aa96505..d3cfd28082d 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -25,22 +25,26 @@ extern crate rustc_middle;
 use rustc_middle::ty::Ty;
 
 extern crate rustc_errors;
-use rustc_errors::{Applicability, DiagnosticMessage, MultiSpan, SubdiagnosticMessage};
+use rustc_errors::{Applicability, DiagnosticMessage, ErrCode, MultiSpan, SubdiagnosticMessage};
 
 extern crate rustc_session;
 
 rustc_fluent_macro::fluent_messages! { "./example.ftl" }
 
+// E0123 and E0456 are no longer used, so we define our own constants here just for this test.
+const E0123: ErrCode = ErrCode::from_u32(0123);
+const E0456: ErrCode = ErrCode::from_u32(0456);
+
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct Hello {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct HelloWarn {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 //~^ ERROR unsupported type attribute for diagnostic derive enum
 enum DiagnosticOnEnum {
     Foo,
@@ -50,53 +54,53 @@ enum DiagnosticOnEnum {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[diag = "E0123"]
 //~^ ERROR failed to resolve: maybe a missing crate `core`
 struct WrongStructAttrStyle {}
 
 #[derive(Diagnostic)]
-#[nonsense(no_crate_example, code = "E0123")]
+#[nonsense(no_crate_example, code = E0123)]
 //~^ ERROR `#[nonsense(...)]` is not a valid attribute
 //~^^ ERROR diagnostic slug not specified
 //~^^^ ERROR cannot find attribute `nonsense` in this scope
 struct InvalidStructAttr {}
 
 #[derive(Diagnostic)]
-#[diag("E0123")]
+#[diag(code = E0123)]
 //~^ ERROR diagnostic slug not specified
 struct InvalidLitNestedAttr {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense, code = "E0123")]
+#[diag(nonsense, code = E0123)]
 //~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated`
 struct InvalidNestedStructAttr {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+#[diag(nonsense("foo"), code = E0123, slug = "foo")]
 //~^ ERROR diagnostic slug must be the first argument
 //~| ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr1 {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense = "...", code = "E0123", slug = "foo")]
+#[diag(nonsense = "...", code = E0123, slug = "foo")]
 //~^ ERROR unknown argument
 //~| ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr2 {}
 
 #[derive(Diagnostic)]
-#[diag(nonsense = 4, code = "E0123", slug = "foo")]
+#[diag(nonsense = 4, code = E0123, slug = "foo")]
 //~^ ERROR unknown argument
 //~| ERROR diagnostic slug not specified
 struct InvalidNestedStructAttr3 {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123", slug = "foo")]
+#[diag(no_crate_example, code = E0123, slug = "foo")]
 //~^ ERROR unknown argument
 struct InvalidNestedStructAttr4 {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct WrongPlaceField {
     #[suggestion = "bar"]
     //~^ ERROR `#[suggestion = ...]` is not a valid attribute
@@ -104,19 +108,19 @@ struct WrongPlaceField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
-#[diag(no_crate_example, code = "E0456")]
+#[diag(no_crate_example, code = E0123)]
+#[diag(no_crate_example, code = E0456)]
 //~^ ERROR specified multiple times
 //~^^ ERROR specified multiple times
 struct DiagSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0456", code = "E0457")]
+#[diag(no_crate_example, code = E0123, code = E0456)]
 //~^ ERROR specified multiple times
 struct CodeSpecifiedTwice {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, no_crate::example, code = "E0456")]
+#[diag(no_crate_example, no_crate::example, code = E0123)]
 //~^ ERROR diagnostic slug must be the first argument
 struct SlugSpecifiedTwice {}
 
@@ -124,7 +128,7 @@ struct SlugSpecifiedTwice {}
 struct KindNotProvided {} //~ ERROR diagnostic slug not specified
 
 #[derive(Diagnostic)]
-#[diag(code = "E0456")]
+#[diag(code = E0123)]
 //~^ ERROR diagnostic slug not specified
 struct SlugNotProvided {}
 
@@ -133,7 +137,7 @@ struct SlugNotProvided {}
 struct CodeNotProvided {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct MessageWrongType {
     #[primary_span]
     //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -141,7 +145,7 @@ struct MessageWrongType {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct InvalidPathFieldAttr {
     #[nonsense]
     //~^ ERROR `#[nonsense]` is not a valid attribute
@@ -150,7 +154,7 @@ struct InvalidPathFieldAttr {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithField {
     name: String,
     #[label(no_crate_label)]
@@ -158,7 +162,7 @@ struct ErrorWithField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithMessageAppliedToField {
     #[label(no_crate_label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -166,7 +170,7 @@ struct ErrorWithMessageAppliedToField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithNonexistentField {
     #[suggestion(no_crate_suggestion, code = "{name}")]
     //~^ ERROR `name` doesn't refer to a field on this type
@@ -175,7 +179,7 @@ struct ErrorWithNonexistentField {
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: expected `'}'`
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorMissingClosingBrace {
     #[suggestion(no_crate_suggestion, code = "{name")]
     suggestion: (Span, Applicability),
@@ -185,7 +189,7 @@ struct ErrorMissingClosingBrace {
 
 #[derive(Diagnostic)]
 //~^ ERROR invalid format string: unmatched `}`
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorMissingOpeningBrace {
     #[suggestion(no_crate_suggestion, code = "name}")]
     suggestion: (Span, Applicability),
@@ -194,14 +198,14 @@ struct ErrorMissingOpeningBrace {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelOnSpan {
     #[label(no_crate_label)]
     sp: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelOnNonSpan {
     #[label(no_crate_label)]
     //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
@@ -209,7 +213,7 @@ struct LabelOnNonSpan {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct Suggest {
     #[suggestion(no_crate_suggestion, code = "This is the suggested code")]
     #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "normal")]
@@ -220,7 +224,7 @@ struct Suggest {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithoutCode {
     #[suggestion(no_crate_suggestion)]
     //~^ ERROR suggestion without `code = "..."`
@@ -228,7 +232,7 @@ struct SuggestWithoutCode {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithBadKey {
     #[suggestion(nonsense = "bar")]
     //~^ ERROR invalid nested attribute
@@ -237,7 +241,7 @@ struct SuggestWithBadKey {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithShorthandMsg {
     #[suggestion(msg = "bar")]
     //~^ ERROR invalid nested attribute
@@ -246,21 +250,21 @@ struct SuggestWithShorthandMsg {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithoutMsg {
     #[suggestion(code = "bar")]
     suggestion: (Span, Applicability),
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithTypesSwapped {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Span),
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithWrongTypeApplicabilityOnly {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     //~^ ERROR wrong field type for suggestion
@@ -268,14 +272,14 @@ struct SuggestWithWrongTypeApplicabilityOnly {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithSpanOnly {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithDuplicateSpanAndApplicability {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Span, Span, Applicability),
@@ -283,7 +287,7 @@ struct SuggestWithDuplicateSpanAndApplicability {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct SuggestWithDuplicateApplicabilityAndSpan {
     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
     suggestion: (Applicability, Applicability, Span),
@@ -291,7 +295,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct WrongKindOfAnnotation {
     #[label = "bar"]
     //~^ ERROR `#[label = ...]` is not a valid attribute
@@ -299,7 +303,7 @@ struct WrongKindOfAnnotation {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct OptionsInErrors {
     #[label(no_crate_label)]
     label: Option<Span>,
@@ -308,7 +312,7 @@ struct OptionsInErrors {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0456")]
+#[diag(no_crate_example, code = E0123)]
 struct MoveOutOfBorrowError<'tcx> {
     name: Ident,
     ty: Ty<'tcx>,
@@ -322,7 +326,7 @@ struct MoveOutOfBorrowError<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithLifetime<'a> {
     #[label(no_crate_label)]
     span: Span,
@@ -330,7 +334,7 @@ struct ErrorWithLifetime<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithDefaultLabelAttr<'a> {
     #[label]
     span: Span,
@@ -338,7 +342,7 @@ struct ErrorWithDefaultLabelAttr<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ArgFieldWithoutSkip {
     #[primary_span]
     span: Span,
@@ -347,7 +351,7 @@ struct ArgFieldWithoutSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ArgFieldWithSkip {
     #[primary_span]
     span: Span,
@@ -358,56 +362,56 @@ struct ArgFieldWithSkip {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedNote {
     #[note]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedNoteCustom {
     #[note(no_crate_note)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[note]
 struct ErrorWithNote {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[note(no_crate_note)]
 struct ErrorWithNoteCustom {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedHelp {
     #[help]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithSpannedHelpCustom {
     #[help(no_crate_help)]
     span: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[help]
 struct ErrorWithHelp {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[help(no_crate_help)]
 struct ErrorWithHelpCustom {
     val: String,
@@ -415,34 +419,34 @@ struct ErrorWithHelpCustom {
 
 #[derive(Diagnostic)]
 #[help]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithHelpWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[help(no_crate_help)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithHelpCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[note]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithNoteWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
 #[note(no_crate_note)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithNoteCustomWrongOrder {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ApplicabilityInBoth {
     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
     //~^ ERROR specified multiple times
@@ -450,7 +454,7 @@ struct ApplicabilityInBoth {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct InvalidApplicability {
     #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")]
     //~^ ERROR invalid applicability
@@ -458,14 +462,14 @@ struct InvalidApplicability {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ValidApplicability {
     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
     suggestion: Span,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct NoApplicability {
     #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: Span,
@@ -483,7 +487,7 @@ struct Subdiagnostic {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct VecField {
     #[primary_span]
     #[label]
@@ -491,7 +495,7 @@ struct VecField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct UnitField {
     #[primary_span]
     spans: Span,
@@ -502,7 +506,7 @@ struct UnitField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct OptUnitField {
     #[primary_span]
     spans: Span,
@@ -526,7 +530,7 @@ struct BoolField {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelWithTrailingPath {
     #[label(no_crate_label, foo)]
     //~^ ERROR a diagnostic slug must be the first argument to the attribute
@@ -534,7 +538,7 @@ struct LabelWithTrailingPath {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelWithTrailingNameValue {
     #[label(no_crate_label, foo = "...")]
     //~^ ERROR only `no_span` is a valid nested attribute
@@ -542,7 +546,7 @@ struct LabelWithTrailingNameValue {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct LabelWithTrailingList {
     #[label(no_crate_label, foo("..."))]
     //~^ ERROR only `no_span` is a valid nested attribute
@@ -562,42 +566,42 @@ struct PrimarySpanOnLint {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct ErrorWithMultiSpan {
     #[primary_span]
     span: MultiSpan,
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[warning]
 struct ErrorWithWarn {
     val: String,
 }
 
 #[derive(Diagnostic)]
-#[error(no_crate_example, code = "E0123")]
+#[error(no_crate_example, code = E0123)]
 //~^ ERROR `#[error(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `error` in this scope
 struct ErrorAttribute {}
 
 #[derive(Diagnostic)]
-#[warn_(no_crate_example, code = "E0123")]
+#[warn_(no_crate_example, code = E0123)]
 //~^ ERROR `#[warn_(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `warn_` in this scope
 struct WarnAttribute {}
 
 #[derive(Diagnostic)]
-#[lint(no_crate_example, code = "E0123")]
+#[lint(no_crate_example, code = E0123)]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
 //~| ERROR cannot find attribute `lint` in this scope
 struct LintAttributeOnSessionDiag {}
 
 #[derive(LintDiagnostic)]
-#[lint(no_crate_example, code = "E0123")]
+#[lint(no_crate_example, code = E0123)]
 //~^ ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR `#[lint(...)]` is not a valid attribute
 //~| ERROR diagnostic slug not specified
@@ -605,7 +609,7 @@ struct LintAttributeOnSessionDiag {}
 struct LintAttributeOnLintDiag {}
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct DuplicatedSuggestionCode {
     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
     //~^ ERROR specified multiple times
@@ -613,7 +617,7 @@ struct DuplicatedSuggestionCode {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct InvalidTypeInSuggestionTuple {
     #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: (Span, usize),
@@ -621,7 +625,7 @@ struct InvalidTypeInSuggestionTuple {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct MissingApplicabilityInSuggestionTuple {
     #[suggestion(no_crate_suggestion, code = "...")]
     suggestion: (Span,),
@@ -629,7 +633,7 @@ struct MissingApplicabilityInSuggestionTuple {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct MissingCodeInSuggestion {
     #[suggestion(no_crate_suggestion)]
     //~^ ERROR suggestion without `code = "..."`
@@ -637,7 +641,7 @@ struct MissingCodeInSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[multipart_suggestion(no_crate_suggestion)]
 //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute
 //~| ERROR cannot find attribute `multipart_suggestion` in this scope
@@ -652,7 +656,7 @@ struct MultipartSuggestion {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[suggestion(no_crate_suggestion, code = "...")]
 //~^ ERROR `#[suggestion(...)]` is not a valid attribute
 struct SuggestionOnStruct {
@@ -661,7 +665,7 @@ struct SuggestionOnStruct {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 #[label]
 //~^ ERROR `#[label]` is not a valid attribute
 struct LabelOnStruct {
@@ -688,7 +692,7 @@ enum ExampleEnum {
 }
 
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct RawIdentDiagnosticArg {
     pub r#type: String,
 }
@@ -762,7 +766,7 @@ struct SubdiagnosticEagerSuggestion {
 
 /// with a doc comment on the type..
 #[derive(Diagnostic)]
-#[diag(no_crate_example, code = "E0123")]
+#[diag(no_crate_example, code = E0123)]
 struct WithDocComment {
     /// ..and the field
     #[primary_span]
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index f376c034587..67257c28b6e 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -1,11 +1,11 @@
 error: unsupported type attribute for diagnostic derive enum
-  --> $DIR/diagnostic-derive.rs:43:1
+  --> $DIR/diagnostic-derive.rs:47:1
    |
-LL | #[diag(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[diag(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:46:5
+  --> $DIR/diagnostic-derive.rs:50:5
    |
 LL |     Foo,
    |     ^^^
@@ -13,7 +13,7 @@ LL |     Foo,
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:48:5
+  --> $DIR/diagnostic-derive.rs:52:5
    |
 LL |     Bar,
    |     ^^^
@@ -21,15 +21,15 @@ LL |     Bar,
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[nonsense(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:59:1
+  --> $DIR/diagnostic-derive.rs:63:1
    |
-LL | #[nonsense(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[nonsense(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:59:1
+  --> $DIR/diagnostic-derive.rs:63:1
    |
-LL | / #[nonsense(no_crate_example, code = "E0123")]
+LL | / #[nonsense(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -39,9 +39,9 @@ LL | | struct InvalidStructAttr {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:66:1
+  --> $DIR/diagnostic-derive.rs:70:1
    |
-LL | / #[diag("E0123")]
+LL | / #[diag(code = E0123)]
 LL | |
 LL | | struct InvalidLitNestedAttr {}
    | |______________________________^
@@ -49,15 +49,15 @@ LL | | struct InvalidLitNestedAttr {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug must be the first argument
-  --> $DIR/diagnostic-derive.rs:76:16
+  --> $DIR/diagnostic-derive.rs:80:16
    |
-LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | #[diag(nonsense("foo"), code = E0123, slug = "foo")]
    |                ^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:76:1
+  --> $DIR/diagnostic-derive.rs:80:1
    |
-LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense("foo"), code = E0123, slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr1 {}
@@ -66,17 +66,17 @@ LL | | struct InvalidNestedStructAttr1 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: unknown argument
-  --> $DIR/diagnostic-derive.rs:82:8
+  --> $DIR/diagnostic-derive.rs:86:8
    |
-LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+LL | #[diag(nonsense = "...", code = E0123, slug = "foo")]
    |        ^^^^^^^^
    |
    = note: only the `code` parameter is valid after the slug
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:82:1
+  --> $DIR/diagnostic-derive.rs:86:1
    |
-LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = "...", code = E0123, slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr2 {}
@@ -85,17 +85,17 @@ LL | | struct InvalidNestedStructAttr2 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: unknown argument
-  --> $DIR/diagnostic-derive.rs:88:8
+  --> $DIR/diagnostic-derive.rs:92:8
    |
-LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+LL | #[diag(nonsense = 4, code = E0123, slug = "foo")]
    |        ^^^^^^^^
    |
    = note: only the `code` parameter is valid after the slug
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:88:1
+  --> $DIR/diagnostic-derive.rs:92:1
    |
-LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")]
+LL | / #[diag(nonsense = 4, code = E0123, slug = "foo")]
 LL | |
 LL | |
 LL | | struct InvalidNestedStructAttr3 {}
@@ -104,63 +104,63 @@ LL | | struct InvalidNestedStructAttr3 {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: unknown argument
-  --> $DIR/diagnostic-derive.rs:94:42
+  --> $DIR/diagnostic-derive.rs:98:40
    |
-LL | #[diag(no_crate_example, code = "E0123", slug = "foo")]
-   |                                          ^^^^
+LL | #[diag(no_crate_example, code = E0123, slug = "foo")]
+   |                                        ^^^^
    |
    = note: only the `code` parameter is valid after the slug
 
 error: `#[suggestion = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:101:5
+  --> $DIR/diagnostic-derive.rs:105:5
    |
 LL |     #[suggestion = "bar"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:108:8
+  --> $DIR/diagnostic-derive.rs:112:8
    |
-LL | #[diag(no_crate_example, code = "E0456")]
+LL | #[diag(no_crate_example, code = E0456)]
    |        ^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:107:8
+  --> $DIR/diagnostic-derive.rs:111:8
    |
-LL | #[diag(no_crate_example, code = "E0123")]
+LL | #[diag(no_crate_example, code = E0123)]
    |        ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:108:26
+  --> $DIR/diagnostic-derive.rs:112:26
    |
-LL | #[diag(no_crate_example, code = "E0456")]
+LL | #[diag(no_crate_example, code = E0456)]
    |                          ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:107:26
+  --> $DIR/diagnostic-derive.rs:111:26
    |
-LL | #[diag(no_crate_example, code = "E0123")]
+LL | #[diag(no_crate_example, code = E0123)]
    |                          ^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:114:42
+  --> $DIR/diagnostic-derive.rs:118:40
    |
-LL | #[diag(no_crate_example, code = "E0456", code = "E0457")]
-   |                                          ^^^^
+LL | #[diag(no_crate_example, code = E0123, code = E0456)]
+   |                                        ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:114:26
+  --> $DIR/diagnostic-derive.rs:118:26
    |
-LL | #[diag(no_crate_example, code = "E0456", code = "E0457")]
+LL | #[diag(no_crate_example, code = E0123, code = E0456)]
    |                          ^^^^
 
 error: diagnostic slug must be the first argument
-  --> $DIR/diagnostic-derive.rs:119:43
+  --> $DIR/diagnostic-derive.rs:123:43
    |
-LL | #[diag(no_crate_example, no_crate::example, code = "E0456")]
+LL | #[diag(no_crate_example, no_crate::example, code = E0123)]
    |                                           ^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:124:1
+  --> $DIR/diagnostic-derive.rs:128:1
    |
 LL | struct KindNotProvided {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,9 +168,9 @@ LL | struct KindNotProvided {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:127:1
+  --> $DIR/diagnostic-derive.rs:131:1
    |
-LL | / #[diag(code = "E0456")]
+LL | / #[diag(code = E0123)]
 LL | |
 LL | | struct SlugNotProvided {}
    | |_________________________^
@@ -178,31 +178,31 @@ LL | | struct SlugNotProvided {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:138:5
+  --> $DIR/diagnostic-derive.rs:142:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
 
 error: `#[nonsense]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:146:5
+  --> $DIR/diagnostic-derive.rs:150:5
    |
 LL |     #[nonsense]
    |     ^^^^^^^^^^^
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:163:5
+  --> $DIR/diagnostic-derive.rs:167:5
    |
 LL |     #[label(no_crate_label)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `name` doesn't refer to a field on this type
-  --> $DIR/diagnostic-derive.rs:171:46
+  --> $DIR/diagnostic-derive.rs:175:46
    |
 LL |     #[suggestion(no_crate_suggestion, code = "{name}")]
    |                                              ^^^^^^^^
 
 error: invalid format string: expected `'}'` but string was terminated
-  --> $DIR/diagnostic-derive.rs:176:10
+  --> $DIR/diagnostic-derive.rs:180:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ expected `'}'` in format string
@@ -211,7 +211,7 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: invalid format string: unmatched `}` found
-  --> $DIR/diagnostic-derive.rs:186:10
+  --> $DIR/diagnostic-derive.rs:190:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ unmatched `}` in format string
@@ -220,19 +220,19 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
-  --> $DIR/diagnostic-derive.rs:206:5
+  --> $DIR/diagnostic-derive.rs:210:5
    |
 LL |     #[label(no_crate_label)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:225:5
+  --> $DIR/diagnostic-derive.rs:229:5
    |
 LL |     #[suggestion(no_crate_suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid nested attribute
-  --> $DIR/diagnostic-derive.rs:233:18
+  --> $DIR/diagnostic-derive.rs:237:18
    |
 LL |     #[suggestion(nonsense = "bar")]
    |                  ^^^^^^^^
@@ -240,13 +240,13 @@ LL |     #[suggestion(nonsense = "bar")]
    = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:233:5
+  --> $DIR/diagnostic-derive.rs:237:5
    |
 LL |     #[suggestion(nonsense = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: invalid nested attribute
-  --> $DIR/diagnostic-derive.rs:242:18
+  --> $DIR/diagnostic-derive.rs:246:18
    |
 LL |     #[suggestion(msg = "bar")]
    |                  ^^^
@@ -254,13 +254,13 @@ LL |     #[suggestion(msg = "bar")]
    = help: only `no_span`, `style`, `code` and `applicability` are valid nested attributes
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:242:5
+  --> $DIR/diagnostic-derive.rs:246:5
    |
 LL |     #[suggestion(msg = "bar")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: wrong field type for suggestion
-  --> $DIR/diagnostic-derive.rs:265:5
+  --> $DIR/diagnostic-derive.rs:269:5
    |
 LL | /     #[suggestion(no_crate_suggestion, code = "This is suggested code")]
 LL | |
@@ -270,79 +270,79 @@ LL | |     suggestion: Applicability,
    = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:281:24
+  --> $DIR/diagnostic-derive.rs:285:24
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                        ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:281:18
+  --> $DIR/diagnostic-derive.rs:285:18
    |
 LL |     suggestion: (Span, Span, Applicability),
    |                  ^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:289:33
+  --> $DIR/diagnostic-derive.rs:293:33
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                                 ^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:289:18
+  --> $DIR/diagnostic-derive.rs:293:18
    |
 LL |     suggestion: (Applicability, Applicability, Span),
    |                  ^^^^^^^^^^^^^
 
 error: `#[label = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:296:5
+  --> $DIR/diagnostic-derive.rs:300:5
    |
 LL |     #[label = "bar"]
    |     ^^^^^^^^^^^^^^^^
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:447:5
+  --> $DIR/diagnostic-derive.rs:451:5
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:449:24
+  --> $DIR/diagnostic-derive.rs:453:24
    |
 LL |     suggestion: (Span, Applicability),
    |                        ^^^^^^^^^^^^^
 
 error: invalid applicability
-  --> $DIR/diagnostic-derive.rs:455:69
+  --> $DIR/diagnostic-derive.rs:459:69
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")]
    |                                                                     ^^^^^^^^
 
 error: the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()`
-  --> $DIR/diagnostic-derive.rs:522:5
+  --> $DIR/diagnostic-derive.rs:526:5
    |
 LL |     #[help(no_crate_help)]
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: a diagnostic slug must be the first argument to the attribute
-  --> $DIR/diagnostic-derive.rs:531:32
+  --> $DIR/diagnostic-derive.rs:535:32
    |
 LL |     #[label(no_crate_label, foo)]
    |                                ^
 
 error: only `no_span` is a valid nested attribute
-  --> $DIR/diagnostic-derive.rs:539:29
+  --> $DIR/diagnostic-derive.rs:543:29
    |
 LL |     #[label(no_crate_label, foo = "...")]
    |                             ^^^
 
 error: only `no_span` is a valid nested attribute
-  --> $DIR/diagnostic-derive.rs:547:29
+  --> $DIR/diagnostic-derive.rs:551:29
    |
 LL |     #[label(no_crate_label, foo("..."))]
    |                             ^^^
 
 error: `#[primary_span]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:559:5
+  --> $DIR/diagnostic-derive.rs:563:5
    |
 LL |     #[primary_span]
    |     ^^^^^^^^^^^^^^^
@@ -350,15 +350,15 @@ LL |     #[primary_span]
    = help: the `primary_span` field attribute is not valid for lint diagnostics
 
 error: `#[error(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:579:1
+  --> $DIR/diagnostic-derive.rs:583:1
    |
-LL | #[error(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[error(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:579:1
+  --> $DIR/diagnostic-derive.rs:583:1
    |
-LL | / #[error(no_crate_example, code = "E0123")]
+LL | / #[error(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -368,15 +368,15 @@ LL | | struct ErrorAttribute {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[warn_(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:586:1
+  --> $DIR/diagnostic-derive.rs:590:1
    |
-LL | #[warn_(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[warn_(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:586:1
+  --> $DIR/diagnostic-derive.rs:590:1
    |
-LL | / #[warn_(no_crate_example, code = "E0123")]
+LL | / #[warn_(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -386,15 +386,15 @@ LL | | struct WarnAttribute {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:593:1
+  --> $DIR/diagnostic-derive.rs:597:1
    |
-LL | #[lint(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:593:1
+  --> $DIR/diagnostic-derive.rs:597:1
    |
-LL | / #[lint(no_crate_example, code = "E0123")]
+LL | / #[lint(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -404,23 +404,23 @@ LL | | struct LintAttributeOnSessionDiag {}
    = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]`
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:600:1
+  --> $DIR/diagnostic-derive.rs:604:1
    |
-LL | #[lint(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[lint(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:600:1
+  --> $DIR/diagnostic-derive.rs:604:1
    |
-LL | #[lint(no_crate_example, code = "E0123")]
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[lint(no_crate_example, code = E0123)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: diagnostic slug not specified
-  --> $DIR/diagnostic-derive.rs:600:1
+  --> $DIR/diagnostic-derive.rs:604:1
    |
-LL | / #[lint(no_crate_example, code = "E0123")]
+LL | / #[lint(no_crate_example, code = E0123)]
 LL | |
 LL | |
 LL | |
@@ -431,19 +431,19 @@ LL | | struct LintAttributeOnLintDiag {}
    = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]`
 
 error: specified multiple times
-  --> $DIR/diagnostic-derive.rs:610:53
+  --> $DIR/diagnostic-derive.rs:614:53
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
    |                                                     ^^^^
    |
 note: previously specified here
-  --> $DIR/diagnostic-derive.rs:610:39
+  --> $DIR/diagnostic-derive.rs:614:39
    |
 LL |     #[suggestion(no_crate_suggestion, code = "...", code = ",,,")]
    |                                       ^^^^
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:619:24
+  --> $DIR/diagnostic-derive.rs:623:24
    |
 LL |     suggestion: (Span, usize),
    |                        ^^^^^
@@ -451,7 +451,7 @@ LL |     suggestion: (Span, usize),
    = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
 
 error: wrong types for suggestion
-  --> $DIR/diagnostic-derive.rs:627:17
+  --> $DIR/diagnostic-derive.rs:631:17
    |
 LL |     suggestion: (Span,),
    |                 ^^^^^^^
@@ -459,13 +459,13 @@ LL |     suggestion: (Span,),
    = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`
 
 error: suggestion without `code = "..."`
-  --> $DIR/diagnostic-derive.rs:634:5
+  --> $DIR/diagnostic-derive.rs:638:5
    |
 LL |     #[suggestion(no_crate_suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:641:1
+  --> $DIR/diagnostic-derive.rs:645:1
    |
 LL | #[multipart_suggestion(no_crate_suggestion)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -473,7 +473,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:644:1
+  --> $DIR/diagnostic-derive.rs:648:1
    |
 LL | #[multipart_suggestion()]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -481,7 +481,7 @@ LL | #[multipart_suggestion()]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[multipart_suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:648:5
+  --> $DIR/diagnostic-derive.rs:652:5
    |
 LL |     #[multipart_suggestion(no_crate_suggestion)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -489,7 +489,7 @@ LL |     #[multipart_suggestion(no_crate_suggestion)]
    = help: consider creating a `Subdiagnostic` instead
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:656:1
+  --> $DIR/diagnostic-derive.rs:660:1
    |
 LL | #[suggestion(no_crate_suggestion, code = "...")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -497,7 +497,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")]
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `#[label]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:665:1
+  --> $DIR/diagnostic-derive.rs:669:1
    |
 LL | #[label]
    | ^^^^^^^^
@@ -505,31 +505,31 @@ LL | #[label]
    = help: `#[label]` and `#[suggestion]` can only be applied to fields
 
 error: `eager` is the only supported nested attribute for `subdiagnostic`
-  --> $DIR/diagnostic-derive.rs:699:7
+  --> $DIR/diagnostic-derive.rs:703:7
    |
 LL |     #[subdiagnostic(bad)]
    |       ^^^^^^^^^^^^^^^^^^
 
 error: `#[subdiagnostic = ...]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:707:5
+  --> $DIR/diagnostic-derive.rs:711:5
    |
 LL |     #[subdiagnostic = "bad"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `eager` is the only supported nested attribute for `subdiagnostic`
-  --> $DIR/diagnostic-derive.rs:715:7
+  --> $DIR/diagnostic-derive.rs:719:7
    |
 LL |     #[subdiagnostic(bad, bad)]
    |       ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `eager` is the only supported nested attribute for `subdiagnostic`
-  --> $DIR/diagnostic-derive.rs:723:7
+  --> $DIR/diagnostic-derive.rs:727:7
    |
 LL |     #[subdiagnostic("bad")]
    |       ^^^^^^^^^^^^^^^^^^^^
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:731:5
+  --> $DIR/diagnostic-derive.rs:735:5
    |
 LL |     #[subdiagnostic(eager)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -537,19 +537,19 @@ LL |     #[subdiagnostic(eager)]
    = help: eager subdiagnostics are not supported on lints
 
 error: expected at least one string literal for `code(...)`
-  --> $DIR/diagnostic-derive.rs:789:23
+  --> $DIR/diagnostic-derive.rs:793:23
    |
 LL |     #[suggestion(code())]
    |                       ^
 
 error: `code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:797:23
+  --> $DIR/diagnostic-derive.rs:801:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^
 
 error: `#[suggestion(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:821:5
+  --> $DIR/diagnostic-derive.rs:825:5
    |
 LL |     #[suggestion(no_crate_suggestion, code = "")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -559,85 +559,85 @@ LL |     #[suggestion(no_crate_suggestion, code = "")]
    = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]`
 
 error[E0433]: failed to resolve: maybe a missing crate `core`?
-  --> $DIR/diagnostic-derive.rs:54:8
+  --> $DIR/diagnostic-derive.rs:58:8
    |
 LL | #[diag = "E0123"]
    |        ^ maybe a missing crate `core`?
 
 error[E0433]: failed to resolve: maybe a missing crate `core`?
-  --> $DIR/diagnostic-derive.rs:797:23
+  --> $DIR/diagnostic-derive.rs:801:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^ maybe a missing crate `core`?
 
 error[E0433]: failed to resolve: maybe a missing crate `core`?
-  --> $DIR/diagnostic-derive.rs:806:25
+  --> $DIR/diagnostic-derive.rs:810:25
    |
 LL |     #[suggestion(code = 3)]
    |                         ^ maybe a missing crate `core`?
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:59:3
+  --> $DIR/diagnostic-derive.rs:63:3
    |
-LL | #[nonsense(no_crate_example, code = "E0123")]
+LL | #[nonsense(no_crate_example, code = E0123)]
    |   ^^^^^^^^
 
 error: cannot find attribute `nonsense` in this scope
-  --> $DIR/diagnostic-derive.rs:146:7
+  --> $DIR/diagnostic-derive.rs:150:7
    |
 LL |     #[nonsense]
    |       ^^^^^^^^
 
 error: cannot find attribute `error` in this scope
-  --> $DIR/diagnostic-derive.rs:579:3
+  --> $DIR/diagnostic-derive.rs:583:3
    |
-LL | #[error(no_crate_example, code = "E0123")]
+LL | #[error(no_crate_example, code = E0123)]
    |   ^^^^^
 
 error: cannot find attribute `warn_` in this scope
-  --> $DIR/diagnostic-derive.rs:586:3
+  --> $DIR/diagnostic-derive.rs:590:3
    |
-LL | #[warn_(no_crate_example, code = "E0123")]
+LL | #[warn_(no_crate_example, code = E0123)]
    |   ^^^^^ help: a built-in attribute with a similar name exists: `warn`
 
 error: cannot find attribute `lint` in this scope
-  --> $DIR/diagnostic-derive.rs:593:3
+  --> $DIR/diagnostic-derive.rs:597:3
    |
-LL | #[lint(no_crate_example, code = "E0123")]
+LL | #[lint(no_crate_example, code = E0123)]
    |   ^^^^ help: a built-in attribute with a similar name exists: `link`
 
 error: cannot find attribute `lint` in this scope
-  --> $DIR/diagnostic-derive.rs:600:3
+  --> $DIR/diagnostic-derive.rs:604:3
    |
-LL | #[lint(no_crate_example, code = "E0123")]
+LL | #[lint(no_crate_example, code = E0123)]
    |   ^^^^ help: a built-in attribute with a similar name exists: `link`
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:641:3
+  --> $DIR/diagnostic-derive.rs:645:3
    |
 LL | #[multipart_suggestion(no_crate_suggestion)]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:644:3
+  --> $DIR/diagnostic-derive.rs:648:3
    |
 LL | #[multipart_suggestion()]
    |   ^^^^^^^^^^^^^^^^^^^^
 
 error: cannot find attribute `multipart_suggestion` in this scope
-  --> $DIR/diagnostic-derive.rs:648:7
+  --> $DIR/diagnostic-derive.rs:652:7
    |
 LL |     #[multipart_suggestion(no_crate_suggestion)]
    |       ^^^^^^^^^^^^^^^^^^^^
 
 error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated`
-  --> $DIR/diagnostic-derive.rs:71:8
+  --> $DIR/diagnostic-derive.rs:75:8
    |
-LL | #[diag(nonsense, code = "E0123")]
+LL | #[diag(nonsense, code = E0123)]
    |        ^^^^^^^^ not found in `crate::fluent_generated`
 
 error[E0425]: cannot find value `__code_34` in this scope
-  --> $DIR/diagnostic-derive.rs:803:10
+  --> $DIR/diagnostic-derive.rs:807:10
    |
 LL | #[derive(Diagnostic)]
    |          ^^^^^^^^^^ not found in this scope
@@ -645,7 +645,7 @@ LL | #[derive(Diagnostic)]
    = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied
-  --> $DIR/diagnostic-derive.rs:345:12
+  --> $DIR/diagnostic-derive.rs:349:12
    |
 LL | #[derive(Diagnostic)]
    |          ---------- required by a bound introduced by this call
diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
index a0a8114e0c5..785da11b9b2 100644
--- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
+++ b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.rs
@@ -19,6 +19,6 @@ use rustc_errors::{Applicability, MultiSpan};
 extern crate rustc_session;
 
 #[derive(Diagnostic)]
-#[diag(compiletest_example, code = "E0123")]
+#[diag(compiletest_example, code = 0123)]
 //~^ ERROR diagnostic slug and crate name do not match
 struct Hello {}
diff --git a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
index 4cdc24e6a6b..eda24a555f8 100644
--- a/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/enforce_slug_naming.stderr
@@ -1,7 +1,7 @@
 error: diagnostic slug and crate name do not match
   --> $DIR/enforce_slug_naming.rs:22:8
    |
-LL | #[diag(compiletest_example, code = "E0123")]
+LL | #[diag(compiletest_example, code = 0123)]
    |        ^^^^^^^^^^^^^^^^^^^
    |
    = note: slug is `compiletest_example` but the crate name is `rustc_dummy`
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
index 55353999b67..0c050c550c4 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.rs
@@ -17,12 +17,18 @@ fn main() {
         }
         match x as i32 {
             0..5+1 => errors_only.push(x),
-            //~^ error: expected one of `=>`, `if`, or `|`, found `+`
+            //~^ error: expected a pattern range bound, found an expression
+            //~| error: exclusive range pattern syntax is experimental
             1 | -3..0 => first_or.push(x),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ (0..5 | 6) => or_two.push(y),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+            //~^ error: exclusive range pattern syntax is experimental
+            //~| error: inline-const in pattern position is experimental
             y @ -5.. => range_from.push(y),
             y @ ..-7 => assert_eq!(y, -8),
+            //~^ error: exclusive range pattern syntax is experimental
             y => bottom.push(y),
         }
     }
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
index cf3bde9705b..cc481f7a79e 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -1,8 +1,8 @@
-error: expected one of `=>`, `if`, or `|`, found `+`
-  --> $DIR/range_pat_interactions1.rs:19:17
+error: expected a pattern range bound, found an expression
+  --> $DIR/range_pat_interactions1.rs:19:16
    |
 LL |             0..5+1 => errors_only.push(x),
-   |                 ^ expected one of `=>`, `if`, or `|`
+   |                ^^^ arbitrary expressions are not allowed in patterns
 
 error[E0408]: variable `n` is not bound in all patterns
   --> $DIR/range_pat_interactions1.rs:10:25
@@ -12,6 +12,16 @@ LL |         if let n @ 2..3|4 = x {
    |                |
    |                variable not in all patterns
 
+error[E0658]: inline-const in pattern position is experimental
+  --> $DIR/range_pat_interactions1.rs:26:20
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                    ^^^^^
+   |
+   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
+   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0658]: exclusive range pattern syntax is experimental
   --> $DIR/range_pat_interactions1.rs:10:20
    |
@@ -34,7 +44,62 @@ LL |         } else if let 2..3 | 4 = x {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
    = help: use an inclusive range pattern, like N..=M
 
-error: aborting due to 4 previous errors
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:19:13
+   |
+LL |             0..5+1 => errors_only.push(x),
+   |             ^^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:22:17
+   |
+LL |             1 | -3..0 => first_or.push(x),
+   |                 ^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:24:18
+   |
+LL |             y @ (0..5 | 6) => or_two.push(y),
+   |                  ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:26:17
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                 ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions1.rs:30:17
+   |
+LL |             y @ ..-7 => assert_eq!(y, -8),
+   |                 ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0408, E0658.
 For more information about an error, try `rustc --explain E0408`.
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
index 0e96cfe7858..068104c4b1b 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.rs
@@ -8,12 +8,18 @@ fn main() {
     for x in -9 + 1..=(9 - 2) {
         match x as i32 {
             0..=(5+1) => errors_only.push(x),
-            //~^ error: expected `)`, found `+`
+            //~^ error: expected a pattern range bound, found an expression
+            //~| error: range pattern bounds cannot have parentheses
             1 | -3..0 => first_or.push(x),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ (0..5 | 6) => or_two.push(y),
+            //~^ error: exclusive range pattern syntax is experimental
             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+            //~^ error: inline-const in pattern position is experimental
+            //~| error: exclusive range pattern syntax is experimental
             y @ -5.. => range_from.push(y),
             y @ ..-7 => assert_eq!(y, -8),
+            //~^ error: exclusive range pattern syntax is experimental
             y => bottom.push(y),
         }
     }
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
index a54f29a3b32..8f21a6149fb 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
@@ -1,8 +1,75 @@
-error: expected `)`, found `+`
-  --> $DIR/range_pat_interactions2.rs:10:19
+error: expected a pattern range bound, found an expression
+  --> $DIR/range_pat_interactions2.rs:10:18
    |
 LL |             0..=(5+1) => errors_only.push(x),
-   |                   ^ expected `)`
+   |                  ^^^ arbitrary expressions are not allowed in patterns
 
-error: aborting due to 1 previous error
+error: range pattern bounds cannot have parentheses
+  --> $DIR/range_pat_interactions2.rs:10:17
+   |
+LL |             0..=(5+1) => errors_only.push(x),
+   |                 ^   ^
+   |
+help: remove these parentheses
+   |
+LL -             0..=(5+1) => errors_only.push(x),
+LL +             0..=5+1 => errors_only.push(x),
+   |
+
+error[E0658]: inline-const in pattern position is experimental
+  --> $DIR/range_pat_interactions2.rs:17:20
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                    ^^^^^
+   |
+   = note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
+   = help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:13:17
+   |
+LL |             1 | -3..0 => first_or.push(x),
+   |                 ^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:15:18
+   |
+LL |             y @ (0..5 | 6) => or_two.push(y),
+   |                  ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:17:17
+   |
+LL |             y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
+   |                 ^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range_pat_interactions2.rs:21:17
+   |
+LL |             y @ ..-7 => assert_eq!(y, -8),
+   |                 ^^^^
+   |
+   = note: see issue #37854 <https://github.com/rust-lang/rust/issues/37854> for more information
+   = help: add `#![feature(exclusive_range_pattern)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: use an inclusive range pattern, like N..=M
+
+error: aborting due to 7 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.rs b/tests/ui/inline-const/const-match-pat-lifetime-err.rs
index 366ad26bb27..ce91e5233bc 100644
--- a/tests/ui/inline-const/const-match-pat-lifetime-err.rs
+++ b/tests/ui/inline-const/const-match-pat-lifetime-err.rs
@@ -1,5 +1,3 @@
-// ignore-test (This is currently broken)
-
 #![allow(incomplete_features)]
 #![feature(const_mut_refs)]
 #![feature(inline_const_pat)]
@@ -9,6 +7,9 @@ use std::marker::PhantomData;
 #[derive(PartialEq, Eq)]
 pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);
 
+#[derive(PartialEq, Eq)]
+pub struct CovariantRef<'a, T: ?Sized>(&'a T);
+
 impl<'a, T: ?Sized> InvariantRef<'a, T> {
     pub const fn new(r: &'a T) -> Self {
         InvariantRef(r, PhantomData)
@@ -19,16 +20,30 @@ impl<'a> InvariantRef<'a, ()> {
     pub const NEW: Self = InvariantRef::new(&());
 }
 
+impl<'a> CovariantRef<'a, ()> {
+    pub const NEW: Self = CovariantRef(&());
+}
+
 fn match_invariant_ref<'a>() {
     let y = ();
     match InvariantRef::new(&y) {
-    //~^ ERROR `y` does not live long enough [E0597]
-        // FIXME(nbdd0121): This should give the same error as `InvariantRef::<'a>::NEW` (without
-        // const block)
+        //~^ ERROR `y` does not live long enough [E0597]
         const { InvariantRef::<'a>::NEW } => (),
     }
 }
 
+fn match_covariant_ref<'a>() {
+    // Unclear if we should error here (should we be able to subtype the type of
+    // `y.0`), but using the associated const directly in the pattern also
+    // errors.
+    let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
+    //~^ ERROR lifetime may not live long enough
+    match y.0 {
+        const { CovariantRef::<'a>::NEW } => (),
+    }
+}
+
 fn main() {
     match_invariant_ref();
+    match_covariant_ref();
 }
diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.stderr b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr
new file mode 100644
index 00000000000..c5760f1027e
--- /dev/null
+++ b/tests/ui/inline-const/const-match-pat-lifetime-err.stderr
@@ -0,0 +1,28 @@
+error[E0597]: `y` does not live long enough
+  --> $DIR/const-match-pat-lifetime-err.rs:29:29
+   |
+LL | fn match_invariant_ref<'a>() {
+   |                        -- lifetime `'a` defined here
+LL |     let y = ();
+   |         - binding `y` declared here
+LL |     match InvariantRef::new(&y) {
+   |                             ^^ borrowed value does not live long enough
+LL |
+LL |         const { InvariantRef::<'a>::NEW } => (),
+   |         --------------------------------- type annotation requires that `y` is borrowed for `'a`
+LL |     }
+LL | }
+   | - `y` dropped here while still borrowed
+
+error: lifetime may not live long enough
+  --> $DIR/const-match-pat-lifetime-err.rs:39:12
+   |
+LL | fn match_covariant_ref<'a>() {
+   |                        -- lifetime `'a` defined here
+...
+LL |     let y: (CovariantRef<'static, _>,) = (CovariantRef(&()),);
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/inline-const/pat-unsafe-err.rs b/tests/ui/inline-const/pat-unsafe-err.rs
index 0db18dd3260..7680c82efb5 100644
--- a/tests/ui/inline-const/pat-unsafe-err.rs
+++ b/tests/ui/inline-const/pat-unsafe-err.rs
@@ -1,5 +1,3 @@
-// ignore-test This is currently broken
-
 #![allow(incomplete_features)]
 #![feature(inline_const_pat)]
 
diff --git a/tests/ui/inline-const/pat-unsafe-err.stderr b/tests/ui/inline-const/pat-unsafe-err.stderr
new file mode 100644
index 00000000000..9b995d6ccf2
--- /dev/null
+++ b/tests/ui/inline-const/pat-unsafe-err.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
+  --> $DIR/pat-unsafe-err.rs:11:13
+   |
+LL |             require_unsafe();
+   |             ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
+  --> $DIR/pat-unsafe-err.rs:18:13
+   |
+LL |             require_unsafe()
+   |             ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/inline-const/pat-unsafe.rs b/tests/ui/inline-const/pat-unsafe.rs
index cfef9ad6a56..f7073ef40eb 100644
--- a/tests/ui/inline-const/pat-unsafe.rs
+++ b/tests/ui/inline-const/pat-unsafe.rs
@@ -1,5 +1,4 @@
 // check-pass
-// ignore-test This is currently broken
 
 #![allow(incomplete_features)]
 #![warn(unused_unsafe)]
diff --git a/tests/ui/inline-const/pat-unsafe.stderr b/tests/ui/inline-const/pat-unsafe.stderr
new file mode 100644
index 00000000000..84dc10c4902
--- /dev/null
+++ b/tests/ui/inline-const/pat-unsafe.stderr
@@ -0,0 +1,20 @@
+warning: unnecessary `unsafe` block
+  --> $DIR/pat-unsafe.rs:16:17
+   |
+LL |                 unsafe {}
+   |                 ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/pat-unsafe.rs:4:9
+   |
+LL | #![warn(unused_unsafe)]
+   |         ^^^^^^^^^^^^^
+
+warning: unnecessary `unsafe` block
+  --> $DIR/pat-unsafe.rs:23:17
+   |
+LL |                 unsafe {}
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index 8161f97dde0..0ed743818c5 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -232,7 +232,7 @@ error: layout_of(MultipleAlignments) = Layout {
 LL | enum MultipleAlignments {
    | ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: layout_of(Result<[u32; 0], Packed<NonZeroU16>>) = Layout {
+error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
            size: Size(4 bytes),
            align: AbiAndPrefAlign {
                abi: Align(4 bytes),
diff --git a/tests/ui/lint/clashing-extern-fn.rs b/tests/ui/lint/clashing-extern-fn.rs
index 09fda33dbec..9740742fbbb 100644
--- a/tests/ui/lint/clashing-extern-fn.rs
+++ b/tests/ui/lint/clashing-extern-fn.rs
@@ -436,7 +436,7 @@ mod hidden_niche {
 
             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
             //~^ WARN redeclared with a different signature
-            //~| WARN block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
+            //~| WARN block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
         }
     }
 }
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
index 0d269e599dd..5b9244b6993 100644
--- a/tests/ui/lint/clashing-extern-fn.stderr
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -8,7 +8,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
    = note: enum has no representation hint
    = note: `#[warn(improper_ctypes)]` on by default
 
-warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
+warning: `extern` block uses type `Option<UnsafeCell<NonZero<usize>>>`, which is not FFI-safe
   --> $DIR/clashing-extern-fn.rs:437:46
    |
 LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
@@ -163,7 +163,7 @@ LL |             fn non_zero_usize() -> core::num::NonZeroUsize;
 LL |             fn non_zero_usize() -> usize;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
-   = note: expected `unsafe extern "C" fn() -> NonZeroUsize`
+   = note: expected `unsafe extern "C" fn() -> NonZero<usize>`
               found `unsafe extern "C" fn() -> usize`
 
 warning: `non_null_ptr` redeclared with a different signature
@@ -224,7 +224,7 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
    = note: expected `unsafe extern "C" fn() -> usize`
-              found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
+              found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
 
 warning: 19 warnings emitted
 
diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr
index 57531b0968f..bdf47343114 100644
--- a/tests/ui/lint/invalid_value.stderr
+++ b/tests/ui/lint/invalid_value.stderr
@@ -316,7 +316,7 @@ LL |         let _val: NonNull<i32> = mem::uninitialized();
    = note: `std::ptr::NonNull<i32>` must be non-null
    = note: raw pointers must be initialized
 
-error: the type `(NonZeroU32, i32)` does not permit zero-initialization
+error: the type `(NonZero<u32>, i32)` does not permit zero-initialization
   --> $DIR/invalid_value.rs:95:39
    |
 LL |         let _val: (NonZeroU32, i32) = mem::zeroed();
@@ -325,9 +325,9 @@ LL |         let _val: (NonZeroU32, i32) = mem::zeroed();
    |                                       this code causes undefined behavior when executed
    |                                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
-   = note: `std::num::NonZeroU32` must be non-null
+   = note: `std::num::NonZero<u32>` must be non-null
 
-error: the type `(NonZeroU32, i32)` does not permit being left uninitialized
+error: the type `(NonZero<u32>, i32)` does not permit being left uninitialized
   --> $DIR/invalid_value.rs:96:39
    |
 LL |         let _val: (NonZeroU32, i32) = mem::uninitialized();
@@ -336,7 +336,7 @@ LL |         let _val: (NonZeroU32, i32) = mem::uninitialized();
    |                                       this code causes undefined behavior when executed
    |                                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
-   = note: `std::num::NonZeroU32` must be non-null
+   = note: `std::num::NonZero<u32>` must be non-null
    = note: integers must be initialized
 
 error: the type `*const dyn Send` does not permit zero-initialization
@@ -417,7 +417,7 @@ LL |         let _val: OneFruitNonZero = mem::zeroed();
    |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: `OneFruitNonZero` must be non-null
-note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
   --> $DIR/invalid_value.rs:39:12
    |
 LL |     Banana(NonZeroU32),
@@ -433,7 +433,7 @@ LL |         let _val: OneFruitNonZero = mem::uninitialized();
    |                                     help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
    = note: `OneFruitNonZero` must be non-null
-note: because `std::num::NonZeroU32` must be non-null (in this field of the only potentially inhabited enum variant)
+note: because `std::num::NonZero<u32>` must be non-null (in this field of the only potentially inhabited enum variant)
   --> $DIR/invalid_value.rs:39:12
    |
 LL |     Banana(NonZeroU32),
@@ -603,7 +603,7 @@ LL |         let _val: &'static [i32] = mem::transmute((0usize, 0usize));
    |
    = note: references must be non-null
 
-error: the type `NonZeroU32` does not permit zero-initialization
+error: the type `NonZero<u32>` does not permit zero-initialization
   --> $DIR/invalid_value.rs:154:32
    |
 LL |         let _val: NonZeroU32 = mem::transmute(0);
@@ -612,7 +612,7 @@ LL |         let _val: NonZeroU32 = mem::transmute(0);
    |                                this code causes undefined behavior when executed
    |                                help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
    |
-   = note: `std::num::NonZeroU32` must be non-null
+   = note: `std::num::NonZero<u32>` must be non-null
 
 error: the type `NonNull<i32>` does not permit zero-initialization
   --> $DIR/invalid_value.rs:157:34
diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr
index 8554e261778..64beefbb757 100644
--- a/tests/ui/lint/lint-ctypes-enum.stderr
+++ b/tests/ui/lint/lint-ctypes-enum.stderr
@@ -61,7 +61,7 @@ LL |    fn nonzero_i128(x: Option<num::NonZeroI128>);
    |
    = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `Option<TransparentUnion<NonZeroU8>>`, which is not FFI-safe
+error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:86:28
    |
 LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
@@ -70,7 +70,7 @@ LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-error: `extern` block uses type `Option<Rust<NonZeroU8>>`, which is not FFI-safe
+error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:88:20
    |
 LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
@@ -79,7 +79,7 @@ LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-error: `extern` block uses type `Result<(), NonZeroI32>`, which is not FFI-safe
+error: `extern` block uses type `Result<(), NonZero<i32>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:89:20
    |
 LL |    fn no_result(x: Result<(), num::NonZeroI32>);
diff --git a/tests/ui/mismatched_types/non_zero_assigned_something.stderr b/tests/ui/mismatched_types/non_zero_assigned_something.stderr
index 57db71f889c..f8e86905ab9 100644
--- a/tests/ui/mismatched_types/non_zero_assigned_something.stderr
+++ b/tests/ui/mismatched_types/non_zero_assigned_something.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/non_zero_assigned_something.rs:2:35
    |
 LL |     let _: std::num::NonZeroU64 = 1;
-   |            --------------------   ^ expected `NonZeroU64`, found integer
+   |            --------------------   ^ expected `NonZero<u64>`, found integer
    |            |
    |            expected due to this
    |
+   = note: expected struct `NonZero<u64>`
+                found type `{integer}`
 help: consider calling `NonZeroU64::new`
    |
 LL |     let _: std::num::NonZeroU64 = NonZeroU64::new(1).unwrap();
@@ -15,11 +17,11 @@ error[E0308]: mismatched types
   --> $DIR/non_zero_assigned_something.rs:6:43
    |
 LL |     let _: Option<std::num::NonZeroU64> = 1;
-   |            ----------------------------   ^ expected `Option<NonZeroU64>`, found integer
+   |            ----------------------------   ^ expected `Option<NonZero<u64>>`, found integer
    |            |
    |            expected due to this
    |
-   = note: expected enum `Option<NonZeroU64>`
+   = note: expected enum `Option<NonZero<u64>>`
               found type `{integer}`
 help: consider calling `NonZeroU64::new`
    |
diff --git a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
index e1825eb5b54..be0fc0f98e2 100644
--- a/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
+++ b/tests/ui/numbers-arithmetic/not-suggest-float-literal.stderr
@@ -124,7 +124,7 @@ LL |     x / 100.0
    = help: the trait `Div<{float}>` is not implemented for `u8`
    = help: the following other types implement trait `Div<Rhs>`:
              <u8 as Div>
-             <u8 as Div<NonZeroU8>>
+             <u8 as Div<NonZero<u8>>>
              <u8 as Div<&u8>>
              <&'a u8 as Div<u8>>
              <&u8 as Div<&u8>>
diff --git a/tests/ui/parser/issues/issue-24197.rs b/tests/ui/parser/issues/issue-24197.rs
index aaf5137461f..9bba16e5596 100644
--- a/tests/ui/parser/issues/issue-24197.rs
+++ b/tests/ui/parser/issues/issue-24197.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let buf[0] = 0; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    let buf[0] = 0; //~ error: expected a pattern, found an expression
 }
diff --git a/tests/ui/parser/issues/issue-24197.stderr b/tests/ui/parser/issues/issue-24197.stderr
index 3ef707f3953..7ebbf4ac370 100644
--- a/tests/ui/parser/issues/issue-24197.stderr
+++ b/tests/ui/parser/issues/issue-24197.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
-  --> $DIR/issue-24197.rs:2:12
+error: expected a pattern, found an expression
+  --> $DIR/issue-24197.rs:2:9
    |
 LL |     let buf[0] = 0;
-   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-24375.rs b/tests/ui/parser/issues/issue-24375.rs
index 1d128d33e4f..a5e256b7f15 100644
--- a/tests/ui/parser/issues/issue-24375.rs
+++ b/tests/ui/parser/issues/issue-24375.rs
@@ -3,7 +3,7 @@ static tmp : [&'static str; 2]  = ["hello", "he"];
 fn main() {
     let z = "hello";
     match z {
-        tmp[0] => {} //~ ERROR expected one of `=>`, `@`, `if`, or `|`, found `[`
+        tmp[0] => {} //~ error: expected a pattern, found an expression
         _ => {}
     }
 }
diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr
index bb1e19e9e6d..e6ef07d13fd 100644
--- a/tests/ui/parser/issues/issue-24375.stderr
+++ b/tests/ui/parser/issues/issue-24375.stderr
@@ -1,8 +1,8 @@
-error: expected one of `=>`, `@`, `if`, or `|`, found `[`
-  --> $DIR/issue-24375.rs:6:12
+error: expected a pattern, found an expression
+  --> $DIR/issue-24375.rs:6:9
    |
 LL |         tmp[0] => {}
-   |            ^ expected one of `=>`, `@`, `if`, or `|`
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/pat-lt-bracket-5.rs b/tests/ui/parser/pat-lt-bracket-5.rs
index aaece1f6bd9..6d784494d56 100644
--- a/tests/ui/parser/pat-lt-bracket-5.rs
+++ b/tests/ui/parser/pat-lt-bracket-5.rs
@@ -1,3 +1,5 @@
 fn main() {
-    let v[0] = v[1]; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    let v[0] = v[1];
+    //~^ error: expected a pattern, found an expression
+    //~| error: cannot find value `v` in this scope
 }
diff --git a/tests/ui/parser/pat-lt-bracket-5.stderr b/tests/ui/parser/pat-lt-bracket-5.stderr
index e556e6c0206..18cf2df0282 100644
--- a/tests/ui/parser/pat-lt-bracket-5.stderr
+++ b/tests/ui/parser/pat-lt-bracket-5.stderr
@@ -1,8 +1,15 @@
-error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
-  --> $DIR/pat-lt-bracket-5.rs:2:10
+error: expected a pattern, found an expression
+  --> $DIR/pat-lt-bracket-5.rs:2:9
    |
 LL |     let v[0] = v[1];
-   |          ^ expected one of `:`, `;`, `=`, `@`, or `|`
+   |         ^^^^ arbitrary expressions are not allowed in patterns
 
-error: aborting due to 1 previous error
+error[E0425]: cannot find value `v` in this scope
+  --> $DIR/pat-lt-bracket-5.rs:2:16
+   |
+LL |     let v[0] = v[1];
+   |                ^ not found in this scope
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/parser/pat-lt-bracket-6.rs b/tests/ui/parser/pat-lt-bracket-6.rs
index 7becffa9fe2..496525ed537 100644
--- a/tests/ui/parser/pat-lt-bracket-6.rs
+++ b/tests/ui/parser/pat-lt-bracket-6.rs
@@ -3,7 +3,8 @@ fn main() {
     let x = Test(&0, []);
 
     let Test(&desc[..]) = x;
-    //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[`
+    //~^ error: expected a pattern, found an expression
+    //~| error: this pattern has 1 field, but the corresponding tuple struct has 2 fields
 }
 
 const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
diff --git a/tests/ui/parser/pat-lt-bracket-6.stderr b/tests/ui/parser/pat-lt-bracket-6.stderr
index 035d0dbfe06..10c638a63e4 100644
--- a/tests/ui/parser/pat-lt-bracket-6.stderr
+++ b/tests/ui/parser/pat-lt-bracket-6.stderr
@@ -1,18 +1,30 @@
-error: expected one of `)`, `,`, `@`, or `|`, found `[`
-  --> $DIR/pat-lt-bracket-6.rs:5:19
+error: expected a pattern, found an expression
+  --> $DIR/pat-lt-bracket-6.rs:5:15
    |
 LL |     let Test(&desc[..]) = x;
-   |                   ^
-   |                   |
-   |                   expected one of `)`, `,`, `@`, or `|`
-   |                   help: missing `,`
+   |               ^^^^^^^^ arbitrary expressions are not allowed in patterns
 
 error[E0308]: mismatched types
-  --> $DIR/pat-lt-bracket-6.rs:9:30
+  --> $DIR/pat-lt-bracket-6.rs:10:30
    |
 LL | const RECOVERY_WITNESS: () = 0;
    |                              ^ expected `()`, found integer
 
-error: aborting due to 2 previous errors
+error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
+  --> $DIR/pat-lt-bracket-6.rs:5:14
+   |
+LL |     struct Test(&'static u8, [u8; 0]);
+   |                 -----------  ------- tuple struct has 2 fields
+...
+LL |     let Test(&desc[..]) = x;
+   |              ^^^^^^^^^ expected 2 fields, found 1
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |     let Test(&desc[..], _) = x;
+   |                       +++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0023, E0308.
+For more information about an error, try `rustc --explain E0023`.
diff --git a/tests/ui/parser/pat-ranges-3.rs b/tests/ui/parser/pat-ranges-3.rs
index 8976dcf0d90..419768a2a20 100644
--- a/tests/ui/parser/pat-ranges-3.rs
+++ b/tests/ui/parser/pat-ranges-3.rs
@@ -1,5 +1,9 @@
 // Parsing of range patterns
 
 fn main() {
-    let 10 ..= 10 + 3 = 12; //~ expected one of `:`, `;`, `=`, or `|`, found `+`
+    let 10 ..= 10 + 3 = 12;
+    //~^ error: expected a pattern range bound, found an expression
+
+    let 10 - 3 ..= 10 = 8;
+    //~^ error: expected a pattern range bound, found an expression
 }
diff --git a/tests/ui/parser/pat-ranges-3.stderr b/tests/ui/parser/pat-ranges-3.stderr
index 611b35a6502..5e1f35d1b6f 100644
--- a/tests/ui/parser/pat-ranges-3.stderr
+++ b/tests/ui/parser/pat-ranges-3.stderr
@@ -1,8 +1,14 @@
-error: expected one of `:`, `;`, `=`, or `|`, found `+`
-  --> $DIR/pat-ranges-3.rs:4:19
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-ranges-3.rs:4:16
    |
 LL |     let 10 ..= 10 + 3 = 12;
-   |                   ^ expected one of `:`, `;`, `=`, or `|`
+   |                ^^^^^^ arbitrary expressions are not allowed in patterns
 
-error: aborting due to 1 previous error
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-ranges-3.rs:7:9
+   |
+LL |     let 10 - 3 ..= 10 = 8;
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/pat-ranges-4.rs b/tests/ui/parser/pat-ranges-4.rs
deleted file mode 100644
index 61188976b02..00000000000
--- a/tests/ui/parser/pat-ranges-4.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-// Parsing of range patterns
-
-fn main() {
-    let 10 - 3 ..= 10 = 8;
-    //~^ error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
-}
diff --git a/tests/ui/parser/pat-ranges-4.stderr b/tests/ui/parser/pat-ranges-4.stderr
deleted file mode 100644
index c30160291d6..00000000000
--- a/tests/ui/parser/pat-ranges-4.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
-  --> $DIR/pat-ranges-4.rs:4:12
-   |
-LL |     let 10 - 3 ..= 10 = 8;
-   |            ^ expected one of 7 possible tokens
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/parser/pat-recover-exprs.rs b/tests/ui/parser/pat-recover-exprs.rs
new file mode 100644
index 00000000000..ecd471467e3
--- /dev/null
+++ b/tests/ui/parser/pat-recover-exprs.rs
@@ -0,0 +1,28 @@
+fn main() {
+    match u8::MAX {
+        u8::MAX.abs() => (),
+        //~^ error: expected a pattern, found a method call
+        x.sqrt() @ .. => (),
+        //~^ error: expected a pattern, found a method call
+        //~| error: left-hand side of `@` must be a binding
+        z @ w @ v.u() => (),
+        //~^ error: expected a pattern, found a method call
+        y.ilog(3) => (),
+        //~^ error: expected a pattern, found a method call
+        n + 1 => (),
+        //~^ error: expected a pattern, found an expression
+        ("".f() + 14 * 8) => (),
+        //~^ error: expected a pattern, found an expression
+        0 | ((1) | 2) | 3 => (),
+        f?() => (),
+        //~^ error: expected a pattern, found an expression
+        (_ + 1) => (),
+        //~^ error: expected one of `)`, `,`, or `|`, found `+`
+    }
+
+    let 1 + 1 = 2;
+    //~^ error: expected a pattern, found an expression
+
+    let b = matches!(x, (x * x | x.f()) | x[0]);
+    //~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
+}
diff --git a/tests/ui/parser/pat-recover-exprs.stderr b/tests/ui/parser/pat-recover-exprs.stderr
new file mode 100644
index 00000000000..787fd03b0c3
--- /dev/null
+++ b/tests/ui/parser/pat-recover-exprs.stderr
@@ -0,0 +1,76 @@
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:3:9
+   |
+LL |         u8::MAX.abs() => (),
+   |         ^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:5:9
+   |
+LL |         x.sqrt() @ .. => (),
+   |         ^^^^^^^^ method calls are not allowed in patterns
+
+error: left-hand side of `@` must be a binding
+  --> $DIR/pat-recover-exprs.rs:5:9
+   |
+LL |         x.sqrt() @ .. => (),
+   |         --------^^^--
+   |         |          |
+   |         |          also a pattern
+   |         interpreted as a pattern, not a binding
+   |
+   = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:8:17
+   |
+LL |         z @ w @ v.u() => (),
+   |                 ^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-exprs.rs:10:9
+   |
+LL |         y.ilog(3) => (),
+   |         ^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:12:9
+   |
+LL |         n + 1 => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:14:10
+   |
+LL |         ("".f() + 14 * 8) => (),
+   |          ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:17:9
+   |
+LL |         f?() => (),
+   |         ^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected one of `)`, `,`, or `|`, found `+`
+  --> $DIR/pat-recover-exprs.rs:19:12
+   |
+LL |         (_ + 1) => (),
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected a pattern, found an expression
+  --> $DIR/pat-recover-exprs.rs:23:9
+   |
+LL |     let 1 + 1 = 2;
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected one of `)`, `,`, `@`, or `|`, found `*`
+  --> $DIR/pat-recover-exprs.rs:26:28
+   |
+LL |     let b = matches!(x, (x * x | x.f()) | x[0]);
+   |                            ^ expected one of `)`, `,`, `@`, or `|`
+  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
+   |
+   = note: while parsing argument for this `pat` macro fragment
+
+error: aborting due to 11 previous errors
+
diff --git a/tests/ui/parser/pat-recover-methodcalls.rs b/tests/ui/parser/pat-recover-methodcalls.rs
new file mode 100644
index 00000000000..54104e9a535
--- /dev/null
+++ b/tests/ui/parser/pat-recover-methodcalls.rs
@@ -0,0 +1,37 @@
+struct Foo(String);
+struct Bar { baz: String }
+
+fn foo(foo: Foo) -> bool {
+    match foo {
+        Foo("hi".to_owned()) => true,
+        //~^ error: expected a pattern, found a method call
+        _ => false
+    }
+}
+
+fn bar(bar: Bar) -> bool {
+    match bar {
+        Bar { baz: "hi".to_owned() } => true,
+        //~^ error: expected a pattern, found a method call
+        _ => false
+    }
+}
+
+fn baz() { // issue #90121
+    let foo = vec!["foo".to_string()];
+
+    match foo.as_slice() {
+        &["foo".to_string()] => {}
+        //~^ error: expected a pattern, found a method call
+        _ => {}
+    };
+}
+
+fn main() {
+    if let (-1.some(4)) = (0, Some(4)) {}
+    //~^ error: expected a pattern, found a method call
+
+    if let (-1.Some(4)) = (0, Some(4)) {}
+    //~^ error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
+    //~| help: missing `,`
+}
diff --git a/tests/ui/parser/pat-recover-methodcalls.stderr b/tests/ui/parser/pat-recover-methodcalls.stderr
new file mode 100644
index 00000000000..1f9ae81dc0c
--- /dev/null
+++ b/tests/ui/parser/pat-recover-methodcalls.stderr
@@ -0,0 +1,35 @@
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:6:13
+   |
+LL |         Foo("hi".to_owned()) => true,
+   |             ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:14:20
+   |
+LL |         Bar { baz: "hi".to_owned() } => true,
+   |                    ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:24:11
+   |
+LL |         &["foo".to_string()] => {}
+   |           ^^^^^^^^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern, found a method call
+  --> $DIR/pat-recover-methodcalls.rs:31:13
+   |
+LL |     if let (-1.some(4)) = (0, Some(4)) {}
+   |             ^^^^^^^^^^ method calls are not allowed in patterns
+
+error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
+  --> $DIR/pat-recover-methodcalls.rs:34:15
+   |
+LL |     if let (-1.Some(4)) = (0, Some(4)) {}
+   |               ^
+   |               |
+   |               expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
+   |               help: missing `,`
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/parser/pat-recover-ranges.rs b/tests/ui/parser/pat-recover-ranges.rs
index 65a6fc6fe21..7d77e950d90 100644
--- a/tests/ui/parser/pat-recover-ranges.rs
+++ b/tests/ui/parser/pat-recover-ranges.rs
@@ -8,6 +8,22 @@ fn main() {
         (0)..=(-4) => (),
         //~^ error: range pattern bounds cannot have parentheses
         //~| error: range pattern bounds cannot have parentheses
+        ..=1 + 2 => (),
+        //~^ error: expected a pattern range bound, found an expression
+        (4).. => (),
+        //~^ error: range pattern bounds cannot have parentheses
+        (-4 + 0).. => (),
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: range pattern bounds cannot have parentheses
+        (1 + 4)...1 * 2 => (),
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: expected a pattern range bound, found an expression
+        //~| error: range pattern bounds cannot have parentheses
+        //~| warning: `...` range patterns are deprecated
+        //~| warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+        0.x()..="y".z() => (),
+        //~^ error: expected a pattern range bound, found a method call
+        //~| error: expected a pattern range bound, found a method call
     };
 }
 
diff --git a/tests/ui/parser/pat-recover-ranges.stderr b/tests/ui/parser/pat-recover-ranges.stderr
index 0d722b5aa95..a7d62bd7f8a 100644
--- a/tests/ui/parser/pat-recover-ranges.stderr
+++ b/tests/ui/parser/pat-recover-ranges.stderr
@@ -46,5 +46,87 @@ LL -         (0)..=(-4) => (),
 LL +         (0)..=-4 => (),
    |
 
-error: aborting due to 4 previous errors
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:11:12
+   |
+LL |         ..=1 + 2 => (),
+   |            ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-ranges.rs:13:9
+   |
+LL |         (4).. => (),
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (4).. => (),
+LL +         4.. => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:15:10
+   |
+LL |         (-4 + 0).. => (),
+   |          ^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-ranges.rs:15:9
+   |
+LL |         (-4 + 0).. => (),
+   |         ^      ^
+   |
+help: remove these parentheses
+   |
+LL -         (-4 + 0).. => (),
+LL +         -4 + 0.. => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:18:10
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |          ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-ranges.rs:18:9
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |         ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         (1 + 4)...1 * 2 => (),
+LL +         1 + 4...1 * 2 => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-ranges.rs:18:19
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |                   ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern range bound, found a method call
+  --> $DIR/pat-recover-ranges.rs:24:9
+   |
+LL |         0.x()..="y".z() => (),
+   |         ^^^^^ method calls are not allowed in patterns
+
+error: expected a pattern range bound, found a method call
+  --> $DIR/pat-recover-ranges.rs:24:17
+   |
+LL |         0.x()..="y".z() => (),
+   |                 ^^^^^^^ method calls are not allowed in patterns
+
+warning: `...` range patterns are deprecated
+  --> $DIR/pat-recover-ranges.rs:18:16
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |                ^^^ help: use `..=` for an inclusive range
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
+
+error: aborting due to 13 previous errors; 1 warning emitted
 
diff --git a/tests/ui/parser/pat-recover-wildcards.rs b/tests/ui/parser/pat-recover-wildcards.rs
new file mode 100644
index 00000000000..f506e2223d6
--- /dev/null
+++ b/tests/ui/parser/pat-recover-wildcards.rs
@@ -0,0 +1,61 @@
+// check that we can't do funny things with wildcards.
+
+fn a() {
+    match 1 {
+        _ + 1 => () //~ error: expected one of `=>`, `if`, or `|`, found `+`
+    }
+}
+
+fn b() {
+    match 2 {
+        (_ % 4) => () //~ error: expected one of `)`, `,`, or `|`, found `%`
+    }
+}
+
+fn c() {
+    match 3 {
+        _.x() => () //~ error: expected one of `=>`, `if`, or `|`, found `.`
+    }
+}
+
+fn d() {
+    match 4 {
+        _..=4 => () //~ error: expected one of `=>`, `if`, or `|`, found `..=`
+    }
+}
+
+fn e() {
+    match 5 {
+        .._ => () //~ error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+    }
+}
+
+fn f() {
+    match 6 {
+        0..._ => ()
+        //~^ error: inclusive range with no end
+        //~| error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+    }
+}
+
+fn g() {
+    match 7 {
+        (_ * 0)..5 => () //~ error: expected one of `)`, `,`, or `|`, found `*`
+    }
+}
+
+fn h() {
+    match 8 {
+        ..(_) => () //~ error: expected one of `=>`, `if`, or `|`, found `(`
+    }
+}
+
+fn i() {
+    match 9 {
+        4..=(2 + _) => ()
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: range pattern bounds cannot have parentheses
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/parser/pat-recover-wildcards.stderr b/tests/ui/parser/pat-recover-wildcards.stderr
new file mode 100644
index 00000000000..2b0c9bbc5be
--- /dev/null
+++ b/tests/ui/parser/pat-recover-wildcards.stderr
@@ -0,0 +1,77 @@
+error: expected one of `=>`, `if`, or `|`, found `+`
+  --> $DIR/pat-recover-wildcards.rs:5:11
+   |
+LL |         _ + 1 => ()
+   |           ^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `)`, `,`, or `|`, found `%`
+  --> $DIR/pat-recover-wildcards.rs:11:12
+   |
+LL |         (_ % 4) => ()
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found `.`
+  --> $DIR/pat-recover-wildcards.rs:17:10
+   |
+LL |         _.x() => ()
+   |          ^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found `..=`
+  --> $DIR/pat-recover-wildcards.rs:23:10
+   |
+LL |         _..=4 => ()
+   |          ^^^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+  --> $DIR/pat-recover-wildcards.rs:29:11
+   |
+LL |         .._ => ()
+   |           ^ expected one of `=>`, `if`, or `|`
+
+error[E0586]: inclusive range with no end
+  --> $DIR/pat-recover-wildcards.rs:35:10
+   |
+LL |         0..._ => ()
+   |          ^^^ help: use `..` instead
+   |
+   = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
+
+error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
+  --> $DIR/pat-recover-wildcards.rs:35:13
+   |
+LL |         0..._ => ()
+   |             ^ expected one of `=>`, `if`, or `|`
+
+error: expected one of `)`, `,`, or `|`, found `*`
+  --> $DIR/pat-recover-wildcards.rs:43:12
+   |
+LL |         (_ * 0)..5 => ()
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected one of `=>`, `if`, or `|`, found `(`
+  --> $DIR/pat-recover-wildcards.rs:49:11
+   |
+LL |         ..(_) => ()
+   |           ^ expected one of `=>`, `if`, or `|`
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/pat-recover-wildcards.rs:55:14
+   |
+LL |         4..=(2 + _) => ()
+   |              ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/pat-recover-wildcards.rs:55:13
+   |
+LL |         4..=(2 + _) => ()
+   |             ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         4..=(2 + _) => ()
+LL +         4..=2 + _ => ()
+   |
+
+error: aborting due to 11 previous errors
+
+For more information about this error, try `rustc --explain E0586`.
diff --git a/tests/ui/print_type_sizes/niche-filling.stdout b/tests/ui/print_type_sizes/niche-filling.stdout
index d1753c26ca8..b53b8936603 100644
--- a/tests/ui/print_type_sizes/niche-filling.stdout
+++ b/tests/ui/print_type_sizes/niche-filling.stdout
@@ -14,17 +14,17 @@ print-type-size         field `.pre`: 1 bytes
 print-type-size         field `.post`: 2 bytes
 print-type-size         field `.val`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<Union1<std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<Union1<std::num::NonZero<u32>>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<Union2<std::num::NonZeroU32, std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<Union2<std::num::NonZero<u32>, std::num::NonZero<u32>>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<Union2<std::num::NonZeroU32, u32>>`: 8 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<Union2<std::num::NonZero<u32>, u32>>`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
@@ -53,22 +53,22 @@ print-type-size type: `MyOption<char>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `MyOption<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `MyOption<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes
 print-type-size     variant `None`: 0 bytes
-print-type-size type: `Union1<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `Union1<std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Union1`: 4 bytes
 print-type-size         field `.a`: 4 bytes
-print-type-size type: `Union2<std::num::NonZeroU32, std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `Union2<std::num::NonZero<u32>, std::num::NonZero<u32>>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Union2`: 4 bytes
 print-type-size         field `.a`: 4 bytes
 print-type-size         field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
-print-type-size type: `Union2<std::num::NonZeroU32, u32>`: 4 bytes, alignment: 4 bytes
+print-type-size type: `Union2<std::num::NonZero<u32>, u32>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Union2`: 4 bytes
 print-type-size         field `.a`: 4 bytes
 print-type-size         field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
-print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes
+print-type-size type: `std::num::NonZero<u32>`: 4 bytes, alignment: 4 bytes
 print-type-size     field `.0`: 4 bytes
 print-type-size type: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes
 print-type-size     variant `Four`: 2 bytes
diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr
index b130b7620fc..bffad037fba 100644
--- a/tests/ui/traits/issue-77982.stderr
+++ b/tests/ui/traits/issue-77982.stderr
@@ -46,7 +46,7 @@ LL |     let ips: Vec<_> = (0..100_000).map(|_| u32::from(0u32.into())).collect(
    = note: multiple `impl`s satisfying `u32: From<_>` found in the `core` crate:
            - impl From<Char> for u32;
            - impl From<Ipv4Addr> for u32;
-           - impl From<NonZeroU32> for u32;
+           - impl From<NonZero<u32>> for u32;
            - impl From<bool> for u32;
            - impl From<char> for u32;
            - impl From<u16> for u32;
diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr
index 4d046635d64..7e5b68353fb 100644
--- a/tests/ui/try-trait/bad-interconversion.stderr
+++ b/tests/ui/try-trait/bad-interconversion.stderr
@@ -11,7 +11,7 @@ LL |     Ok(Err(123_i32)?)
    = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
    = help: the following other types implement trait `From<T>`:
              <u8 as From<bool>>
-             <u8 as From<NonZeroU8>>
+             <u8 as From<NonZero<u8>>>
              <u8 as From<Char>>
    = note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
 
diff --git a/triagebot.toml b/triagebot.toml
index c46f9c90030..e57dd158374 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -476,7 +476,7 @@ of `ObligationCtxt`.
 """
 cc = ["@lcnr", "@compiler-errors"]
 
-[mentions."compiler/rustc_error_codes/src/error_codes.rs"]
+[mentions."compiler/rustc_error_codes/src/lib.rs"]
 message = "Some changes occurred in diagnostic error codes"
 cc = ["@GuillaumeGomez"]