about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-15 18:27:37 +0000
committerbors <bors@rust-lang.org>2022-08-15 18:27:37 +0000
commit40336865fe7d4a01139a3336639c6971647e885c (patch)
treec4a707523bfd7a0b4c4cc5f9da41862e2a885975
parent9b4ea391a132ec5f5de40079597ab7ff2fd691ad (diff)
parente65de39763cc516a92c768c5644d7f86e973fb24 (diff)
downloadrust-40336865fe7d4a01139a3336639c6971647e885c.tar.gz
rust-40336865fe7d4a01139a3336639c6971647e885c.zip
Auto merge of #100595 - matthiaskrgr:rollup-f1zur58, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #100031 (improve "try ignoring the field" diagnostic)
 - #100325 (Rustdoc-Json: Don't remove impls for items imported from private modules)
 - #100377 (Replace - with _ in fluent slugs to improve developer workflows)
 - #100458 (Adjust span of fn argument declaration)
 - #100514 (Delay span bug when failing to normalize negative coherence impl subject due to other malformed impls)
 - #100528 (Support 1st group of RISC-V Bitmanip backend target features)
 - #100559 (Parser simplifications)
 - #100568 (Fix STD build for ESP-IDF)
 - #100582 ([rustdoc] Fix handling of stripped enum variant in JSON output format)
 - #100586 (Reland changes replacing num_cpus with available_parallelism )

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock6
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/borrowck.ftl12
-rw-r--r--compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/const_eval.ftl26
-rw-r--r--compiler/rustc_error_messages/locales/en-US/expand.ftl4
-rw-r--r--compiler/rustc_error_messages/locales/en-US/lint.ftl326
-rw-r--r--compiler/rustc_error_messages/locales/en-US/parser.ftl24
-rw-r--r--compiler/rustc_error_messages/locales/en-US/passes.ftl228
-rw-r--r--compiler/rustc_error_messages/locales/en-US/privacy.ftl18
-rw-r--r--compiler/rustc_error_messages/locales/en-US/typeck.ftl74
-rw-r--r--compiler/rustc_macros/src/diagnostics/fluent.rs32
-rw-r--r--compiler/rustc_macros/src/diagnostics/mod.rs16
-rw-r--r--compiler/rustc_macros/src/lib.rs10
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs12
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs337
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs8
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs8
-rw-r--r--compiler/rustc_parse/src/parser/path.rs7
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs6
-rw-r--r--compiler/rustc_passes/src/liveness.rs34
-rw-r--r--compiler/rustc_session/Cargo.toml1
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_span/src/source_map.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs8
-rw-r--r--src/bootstrap/Cargo.lock1
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/config.rs2
-rw-r--r--src/bootstrap/flags.rs2
-rw-r--r--src/bootstrap/lib.rs4
-rw-r--r--src/librustdoc/json/conversions.rs10
-rw-r--r--src/librustdoc/passes/stripper.rs12
-rw-r--r--src/test/run-make/translation/broken.ftl2
-rw-r--r--src/test/run-make/translation/missing.ftl2
-rw-r--r--src/test/run-make/translation/working.ftl2
-rw-r--r--src/test/rustdoc-json/enum_variant_hidden.rs13
-rw-r--r--src/test/rustdoc-json/impls/import_from_private.rs24
-rw-r--r--src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/missing-message.ftl2
-rw-r--r--src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl1
-rw-r--r--src/test/ui-fulldeps/fluent-messages/test.rs18
-rw-r--r--src/test/ui-fulldeps/fluent-messages/test.stderr24
-rw-r--r--src/test/ui/argument-suggestions/complex.stderr2
-rw-r--r--src/test/ui/c-variadic/issue-86053-1.stderr6
-rw-r--r--src/test/ui/coherence/issue-100191-2.rs12
-rw-r--r--src/test/ui/coherence/issue-100191-2.stderr14
-rw-r--r--src/test/ui/coherence/issue-100191.rs21
-rw-r--r--src/test/ui/coherence/issue-100191.stderr12
-rw-r--r--src/test/ui/suggestions/dont-try-removing-the-field.rs17
-rw-r--r--src/test/ui/suggestions/dont-try-removing-the-field.stderr10
-rw-r--r--src/test/ui/suggestions/suggest-ref-macro.stderr10
-rw-r--r--src/test/ui/suggestions/try-removing-the-field.rs17
-rw-r--r--src/test/ui/suggestions/try-removing-the-field.stderr12
-rw-r--r--src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr16
-rw-r--r--src/tools/build-manifest/Cargo.toml1
-rw-r--r--src/tools/build-manifest/src/main.rs2
57 files changed, 841 insertions, 644 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b480c42fa82..395f5a127bd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -257,7 +257,6 @@ dependencies = [
  "anyhow",
  "flate2",
  "hex 0.4.2",
- "num_cpus",
  "rayon",
  "serde",
  "serde_json",
@@ -2140,9 +2139,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.129"
+version = "0.2.131"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64de3cc433455c14174d42e554d4027ee631c4d046d43e3ecc6efc4636cdc7a7"
+checksum = "04c3b4822ccebfa39c02fc03d1534441b22ead323fa0f48bb7ddd8e6ba076a40"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -4442,7 +4441,6 @@ name = "rustc_session"
 version = "0.0.0"
 dependencies = [
  "getopts",
- "num_cpus",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_errors",
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index ecad0518533..9062a83b8be 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -227,6 +227,10 @@ const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     ("zhinxmin", Some(sym::riscv_target_feature)),
     ("zfh", Some(sym::riscv_target_feature)),
     ("zfhmin", Some(sym::riscv_target_feature)),
+    ("zba", Some(sym::riscv_target_feature)),
+    ("zbb", Some(sym::riscv_target_feature)),
+    ("zbc", Some(sym::riscv_target_feature)),
+    ("zbs", Some(sym::riscv_target_feature)),
     ("zbkb", Some(sym::riscv_target_feature)),
     ("zbkc", Some(sym::riscv_target_feature)),
     ("zbkx", Some(sym::riscv_target_feature)),
diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
index 645673ef47a..4af40d2062d 100644
--- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
@@ -1,18 +1,18 @@
-borrowck-move-unsized =
+borrowck_move_unsized =
     cannot move a value of type `{$ty}`
     .label = the size of `{$ty}` cannot be statically determined
 
-borrowck-higher-ranked-lifetime-error =
+borrowck_higher_ranked_lifetime_error =
     higher-ranked lifetime error
 
-borrowck-could-not-prove =
+borrowck_could_not_prove =
     could not prove `{$predicate}`
 
-borrowck-could-not-normalize =
+borrowck_could_not_normalize =
     could not normalize `{$value}`
 
-borrowck-higher-ranked-subtype-error =
+borrowck_higher_ranked_subtype_error =
     higher-ranked subtype error
   
-generic-does-not-live-long-enough =
+generic_does_not_live_long_enough =
     `{$kind}` does not live long enough
\ No newline at end of file
diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
index 1d3e33c8185..4d088e27b36 100644
--- a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl
@@ -1,5 +1,5 @@
-builtin-macros-requires-cfg-pattern =
+builtin_macros_requires_cfg_pattern =
     macro requires a cfg-pattern as an argument
     .label = cfg-pattern required
 
-builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
+builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
index 3f2ff861001..341f05efefd 100644
--- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/const_eval.ftl
@@ -1,31 +1,31 @@
-const-eval-unstable-in-stable =
+const_eval_unstable_in_stable =
     const-stable function cannot use `#[feature({$gate})]`
-    .unstable-sugg = if it is not part of the public API, make this function unstably const
-    .bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
+    .unstable_sugg = if it is not part of the public API, make this function unstably const
+    .bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
 
-const-eval-thread-local-access =
+const_eval_thread_local_access =
     thread-local statics cannot be accessed at compile-time
 
-const-eval-static-access =
+const_eval_static_access =
     {$kind}s cannot refer to statics
     .help = consider extracting the value of the `static` to a `const`, and referring to that
-    .teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
-    .teach-help = To fix this, the value can be extracted to a `const` and then used.
+    .teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
+    .teach_help = To fix this, the value can be extracted to a `const` and then used.
 
-const-eval-raw-ptr-to-int =
+const_eval_raw_ptr_to_int =
     pointers cannot be cast to integers during const eval
     .note = at compile-time, pointers do not have an integer value
     .note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
 
-const-eval-raw-ptr-comparison =
+const_eval_raw_ptr_comparison =
     pointers cannot be reliably compared during const eval
     .note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
 
-const-eval-panic-non-str = argument to `panic!()` in a const context must have type `&str`
+const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
 
-const-eval-mut-deref =
+const_eval_mut_deref =
     mutation through a reference is not allowed in {$kind}s
 
-const-eval-transient-mut-borrow = mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s
 
-const-eval-transient-mut-borrow-raw = raw mutable references are not allowed in {$kind}s
+const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s
diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_error_messages/locales/en-US/expand.ftl
index 8d506a3ea8b..bdfa22e77eb 100644
--- a/compiler/rustc_error_messages/locales/en-US/expand.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/expand.ftl
@@ -1,5 +1,5 @@
-expand-explain-doc-comment-outer =
+expand_explain_doc_comment_outer =
     outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
 
-expand-explain-doc-comment-inner =
+expand_explain_doc_comment_inner =
     inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl
index 55e96e58e46..97317114716 100644
--- a/compiler/rustc_error_messages/locales/en-US/lint.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl
@@ -1,22 +1,22 @@
-lint-array-into-iter =
+lint_array_into_iter =
     this method call resolves to `<&{$target} as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to <{$target} as IntoIterator>::into_iter in Rust 2021
-    .use-iter-suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
-    .remove-into-iter-suggestion = or remove `.into_iter()` to iterate by value
-    .use-explicit-into-iter-suggestion =
+    .use_iter_suggestion = use `.iter()` instead of `.into_iter()` to avoid ambiguity
+    .remove_into_iter_suggestion = or remove `.into_iter()` to iterate by value
+    .use_explicit_into_iter_suggestion =
         or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value
 
-lint-enum-intrinsics-mem-discriminant =
+lint_enum_intrinsics_mem_discriminant =
     the return value of `mem::discriminant` is unspecified when called with a non-enum type
     .note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
 
-lint-enum-intrinsics-mem-variant =
+lint_enum_intrinsics_mem_variant =
     the return value of `mem::variant_count` is unspecified when called with a non-enum type
     .note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
 
-lint-expectation = this lint expectation is unfulfilled
+lint_expectation = this lint expectation is unfulfilled
     .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
 
-lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of text present in {$label}
+lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of text present in {$label}
     .label = this {$label} contains {$count ->
         [one] an invisible
         *[other] invisible
@@ -25,68 +25,68 @@ lint-hidden-unicode-codepoints = unicode codepoint changing visible direction of
         *[other] codepoints
     }
     .note = these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen
-    .suggestion-remove = if their presence wasn't intentional, you can remove them
-    .suggestion-escape = if you want to keep them but make them visible in your source code, you can escape them
-    .no-suggestion-note-escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
+    .suggestion_remove = if their presence wasn't intentional, you can remove them
+    .suggestion_escape = if you want to keep them but make them visible in your source code, you can escape them
+    .no_suggestion_note_escape = if you want to keep them but make them visible in your source code, you can escape them: {$escaped}
 
-lint-default-hash-types = prefer `{$preferred}` over `{$used}`, it has better performance
+lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance
     .note = a `use rustc_data_structures::fx::{$preferred}` may be necessary
 
-lint-query-instability = using `{$query}` can result in unstable query results
+lint_query_instability = using `{$query}` can result in unstable query results
     .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
-lint-tykind-kind = usage of `ty::TyKind::<kind>`
+lint_tykind_kind = usage of `ty::TyKind::<kind>`
     .suggestion = try using `ty::<kind>` directly
 
-lint-tykind = usage of `ty::TyKind`
+lint_tykind = usage of `ty::TyKind`
     .help = try using `Ty` instead
 
-lint-ty-qualified = usage of qualified `ty::{$ty}`
+lint_ty_qualified = usage of qualified `ty::{$ty}`
     .suggestion = try importing it and using it unqualified
 
-lint-lintpass-by-hand = implementing `LintPass` by hand
+lint_lintpass_by_hand = implementing `LintPass` by hand
     .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
-lint-non-existant-doc-keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
+lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
     .help = only existing keywords are allowed in core/std
 
-lint-diag-out-of-impl =
+lint_diag_out_of_impl =
     diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
 
-lint-untranslatable-diag = diagnostics should be created using translatable messages
+lint_untranslatable_diag = diagnostics should be created using translatable messages
 
-lint-cstring-ptr = getting the inner pointer of a temporary `CString`
-    .as-ptr-label = this pointer will be invalid
-    .unwrap-label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
+lint_cstring_ptr = getting the inner pointer of a temporary `CString`
+    .as_ptr_label = this pointer will be invalid
+    .unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
     .note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
     .help = for more information, see https://doc.rust-lang.org/reference/destructors.html
 
-lint-identifier-non-ascii-char = identifier contains non-ASCII characters
+lint_identifier_non_ascii_char = identifier contains non-ASCII characters
 
-lint-identifier-uncommon-codepoints = identifier contains uncommon Unicode codepoints
+lint_identifier_uncommon_codepoints = identifier contains uncommon Unicode codepoints
 
-lint-confusable-identifier-pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
+lint_confusable_identifier_pair = identifier pair considered confusable between `{$existing_sym}` and `{$sym}`
     .label = this is where the previous identifier occurred
 
-lint-mixed-script-confusables =
+lint_mixed_script_confusables =
     the usage of Script Group `{$set}` in this crate consists solely of mixed script confusables
-    .includes-note = the usage includes {$includes}
+    .includes_note = the usage includes {$includes}
     .note = please recheck to make sure their usages are indeed what you want
 
-lint-non-fmt-panic = panic message is not a string literal
+lint_non_fmt_panic = panic message is not a string literal
     .note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
-    .more-info-note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
-    .supports-fmt-note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
-    .supports-fmt-suggestion = remove the `format!(..)` macro call
-    .display-suggestion = add a "{"{"}{"}"}" format string to `Display` the message
-    .debug-suggestion =
+    .more_info_note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+    .supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
+    .supports_fmt_suggestion = remove the `format!(..)` macro call
+    .display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message
+    .debug_suggestion =
         add a "{"{"}:?{"}"}" format string to use the `Debug` implementation of `{$ty}`
-    .panic-suggestion = {$already_suggested ->
+    .panic_suggestion = {$already_suggested ->
         [true] or use
         *[false] use
     } std::panic::panic_any instead
 
-lint-non-fmt-panic-unused =
+lint_non_fmt_panic_unused =
     panic message contains {$count ->
         [one] an unused
         *[other] unused
@@ -95,13 +95,13 @@ lint-non-fmt-panic-unused =
         *[other] placeholders
     }
     .note = this message is not used as a format string when given without arguments, but will be in Rust 2021
-    .add-args-suggestion = add the missing {$count ->
+    .add_args_suggestion = add the missing {$count ->
         [one] argument
         *[other] arguments
     }
-    .add-fmt-suggestion = or add a "{"{"}{"}"}" format string to use the message literally
+    .add_fmt_suggestion = or add a "{"{"}{"}"}" format string to use the message literally
 
-lint-non-fmt-panic-braces =
+lint_non_fmt_panic_braces =
     panic message contains {$count ->
         [one] a brace
         *[other] braces
@@ -109,30 +109,30 @@ lint-non-fmt-panic-braces =
     .note = this message is not used as a format string, but will be in Rust 2021
     .suggestion = add a "{"{"}{"}"}" format string to use the message literally
 
-lint-non-camel-case-type = {$sort} `{$name}` should have an upper camel case name
+lint_non_camel_case_type = {$sort} `{$name}` should have an upper camel case name
     .suggestion = convert the identifier to upper camel case
     .label = should have an UpperCamelCase name
 
-lint-non-snake-case = {$sort} `{$name}` should have a snake case name
-    .rename-or-convert-suggestion = rename the identifier or convert it to a snake case raw identifier
-    .cannot-convert-note = `{$sc}` cannot be used as a raw identifier
-    .rename-suggestion = rename the identifier
-    .convert-suggestion = convert the identifier to snake case
+lint_non_snake_case = {$sort} `{$name}` should have a snake case name
+    .rename_or_convert_suggestion = rename the identifier or convert it to a snake case raw identifier
+    .cannot_convert_note = `{$sc}` cannot be used as a raw identifier
+    .rename_suggestion = rename the identifier
+    .convert_suggestion = convert the identifier to snake case
     .help = convert the identifier to snake case: `{$sc}`
     .label = should have a snake_case name
 
-lint-non-upper_case-global = {$sort} `{$name}` should have an upper case name
+lint_non_upper_case_global = {$sort} `{$name}` should have an upper case name
     .suggestion = convert the identifier to upper case
     .label = should have an UPPER_CASE name
 
-lint-noop-method-call = call to `.{$method}()` on a reference in this situation does nothing
+lint_noop_method_call = call to `.{$method}()` on a reference in this situation does nothing
     .label = unnecessary method call
     .note = the type `{$receiver_ty}` which `{$method}` is being called on is the same as the type returned from `{$method}`, so the method call does not do anything and can be removed
 
-lint-pass-by-value = passing `{$ty}` by reference
+lint_pass_by_value = passing `{$ty}` by reference
     .suggestion = try passing by value
 
-lint-redundant-semicolons =
+lint_redundant_semicolons =
     unnecessary trailing {$multiple ->
         [true] semicolons
         *[false] semicolon
@@ -142,254 +142,254 @@ lint-redundant-semicolons =
         *[false] this semicolon
     }
 
-lint-drop-trait-constraints =
+lint_drop_trait_constraints =
     bounds on `{$predicate}` are most likely incorrect, consider instead using `{$needs_drop}` to detect whether a type can be trivially dropped
 
-lint-drop-glue =
+lint_drop_glue =
     types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped
 
-lint-range-endpoint-out-of-range = range endpoint is out of range for `{$ty}`
+lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
     .suggestion = use an inclusive range instead
 
-lint-overflowing-bin-hex = literal out of range for `{$ty}`
-    .negative-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
-    .negative-becomes-note = and the value `-{$lit}` will become `{$actually}{$ty}`
-    .positive-note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
+lint_overflowing_bin_hex = literal out of range for `{$ty}`
+    .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
+    .negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
+    .positive_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` and will become `{$actually}{$ty}`
     .suggestion = consider using the type `{$suggestion_ty}` instead
     .help = consider using the type `{$suggestion_ty}` instead
 
-lint-overflowing-int = literal out of range for `{$ty}`
+lint_overflowing_int = literal out of range for `{$ty}`
     .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
     .help = consider using the type `{$suggestion_ty}` instead
 
-lint-only-cast-u8-to-char = only `u8` can be cast into `char`
+lint_only_cast_u8_to_char = only `u8` can be cast into `char`
     .suggestion = use a `char` literal instead
 
-lint-overflowing-uint = literal out of range for `{$ty}`
+lint_overflowing_uint = literal out of range for `{$ty}`
     .note = the literal `{$lit}` does not fit into the type `{$ty}` whose range is `{$min}..={$max}`
 
-lint-overflowing-literal = literal out of range for `{$ty}`
+lint_overflowing_literal = literal out of range for `{$ty}`
     .note = the literal `{$lit}` does not fit into the type `{$ty}` and will be converted to `{$ty}::INFINITY`
 
-lint-unused-comparisons = comparison is useless due to type limits
+lint_unused_comparisons = comparison is useless due to type limits
 
-lint-improper-ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
+lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
     .label = not FFI-safe
     .note = the type is defined here
 
-lint-improper-ctypes-opaque = opaque types have no C equivalent
+lint_improper_ctypes_opaque = opaque types have no C equivalent
 
-lint-improper-ctypes-fnptr-reason = this function pointer has Rust-specific calling convention
-lint-improper-ctypes-fnptr-help = consider using an `extern fn(...) -> ...` function pointer instead
+lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
+lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
 
-lint-improper-ctypes-tuple-reason = tuples have unspecified layout
-lint-improper-ctypes-tuple-help = consider using a struct instead
+lint_improper_ctypes_tuple_reason = tuples have unspecified layout
+lint_improper_ctypes_tuple_help = consider using a struct instead
 
-lint-improper-ctypes-str-reason = string slices have no C equivalent
-lint-improper-ctypes-str-help = consider using `*const u8` and a length instead
+lint_improper_ctypes_str_reason = string slices have no C equivalent
+lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
 
-lint-improper-ctypes-dyn = trait objects have no C equivalent
+lint_improper_ctypes_dyn = trait objects have no C equivalent
 
-lint-improper-ctypes-slice-reason = slices have no C equivalent
-lint-improper-ctypes-slice-help = consider using a raw pointer instead
+lint_improper_ctypes_slice_reason = slices have no C equivalent
+lint_improper_ctypes_slice_help = consider using a raw pointer instead
 
-lint-improper-ctypes-128bit = 128-bit integers don't currently have a known stable ABI
+lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stable ABI
 
-lint-improper-ctypes-char-reason = the `char` type has no C equivalent
-lint-improper-ctypes-char-help = consider using `u32` or `libc::wchar_t` instead
+lint_improper_ctypes_char_reason = the `char` type has no C equivalent
+lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
 
-lint-improper-ctypes-non-exhaustive = this enum is non-exhaustive
-lint-improper-ctypes-non-exhaustive-variant = this enum has non-exhaustive variants
+lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
+lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
 
-lint-improper-ctypes-enum-repr-reason = enum has no representation hint
-lint-improper-ctypes-enum-repr-help =
+lint_improper_ctypes_enum_repr_reason = enum has no representation hint
+lint_improper_ctypes_enum_repr_help =
     consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
-lint-improper-ctypes-struct-fieldless-reason = this struct has no fields
-lint-improper-ctypes-struct-fieldless-help = consider adding a member to this struct
+lint_improper_ctypes_struct_fieldless_reason = this struct has no fields
+lint_improper_ctypes_struct_fieldless_help = consider adding a member to this struct
 
-lint-improper-ctypes-union-fieldless-reason = this union has no fields
-lint-improper-ctypes-union-fieldless-help = consider adding a member to this union
+lint_improper_ctypes_union_fieldless_reason = this union has no fields
+lint_improper_ctypes_union_fieldless_help = consider adding a member to this union
 
-lint-improper-ctypes-struct-non-exhaustive = this struct is non-exhaustive
-lint-improper-ctypes-union-non-exhaustive = this union is non-exhaustive
+lint_improper_ctypes_struct_non_exhaustive = this struct is non-exhaustive
+lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
 
-lint-improper-ctypes-struct-layout-reason = this struct has unspecified layout
-lint-improper-ctypes-struct-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+lint_improper_ctypes_struct_layout_reason = this struct has unspecified layout
+lint_improper_ctypes_struct_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 
-lint-improper-ctypes-union-layout-reason = this union has unspecified layout
-lint-improper-ctypes-union-layout-help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
+lint_improper_ctypes_union_layout_reason = this union has unspecified layout
+lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
 
-lint-improper-ctypes-box = box cannot be represented as a single pointer
+lint_improper_ctypes_box = box cannot be represented as a single pointer
 
-lint-improper-ctypes-enum-phantomdata = this enum contains a PhantomData field
+lint_improper_ctypes_enum_phantomdata = this enum contains a PhantomData field
 
-lint-improper-ctypes-struct-zst = this struct contains only zero-sized fields
+lint_improper_ctypes_struct_zst = this struct contains only zero-sized fields
 
-lint-improper-ctypes-array-reason = passing raw arrays by value is not FFI-safe
-lint-improper-ctypes-array-help = consider passing a pointer to the array
+lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
+lint_improper_ctypes_array_help = consider passing a pointer to the array
 
-lint-improper-ctypes-only-phantomdata = composed only of `PhantomData`
+lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
 
-lint-variant-size-differences =
+lint_variant_size_differences =
     enum variant is more than three times larger ({$largest} bytes) than the next largest
 
-lint-atomic-ordering-load = atomic loads cannot have `Release` or `AcqRel` ordering
+lint_atomic_ordering_load = atomic loads cannot have `Release` or `AcqRel` ordering
     .help = consider using ordering modes `Acquire`, `SeqCst` or `Relaxed`
 
-lint-atomic-ordering-store = atomic stores cannot have `Acquire` or `AcqRel` ordering
+lint_atomic_ordering_store = atomic stores cannot have `Acquire` or `AcqRel` ordering
     .help = consider using ordering modes `Release`, `SeqCst` or `Relaxed`
 
-lint-atomic-ordering-fence = memory fences cannot have `Relaxed` ordering
+lint_atomic_ordering_fence = memory fences cannot have `Relaxed` ordering
     .help = consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst`
 
-lint-atomic-ordering-invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
+lint_atomic_ordering_invalid = `{$method}`'s failure ordering may not be `Release` or `AcqRel`, since a failed `{$method}` does not result in a write
     .label = invalid failure ordering
     .help = consider using `Acquire` or `Relaxed` failure ordering instead
 
-lint-unused-op = unused {$op} that must be used
+lint_unused_op = unused {$op} that must be used
     .label = the {$op} produces a value
     .suggestion = use `let _ = ...` to ignore the resulting value
 
-lint-unused-result = unused result of type `{$ty}`
+lint_unused_result = unused result of type `{$ty}`
 
-lint-unused-closure =
+lint_unused_closure =
     unused {$pre}{$count ->
         [one] closure
         *[other] closures
     }{$post} that must be used
     .note = closures are lazy and do nothing unless called
 
-lint-unused-generator =
+lint_unused_generator =
     unused {$pre}{$count ->
         [one] generator
         *[other] generator
     }{$post} that must be used
     .note = generators are lazy and do nothing unless resumed
 
-lint-unused-def = unused {$pre}`{$def}`{$post} that must be used
+lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
 
-lint-path-statement-drop = path statement drops value
+lint_path_statement_drop = path statement drops value
     .suggestion = use `drop` to clarify the intent
 
-lint-path-statement-no-effect = path statement with no effect
+lint_path_statement_no_effect = path statement with no effect
 
-lint-unused-delim = unnecessary {$delim} around {$item}
+lint_unused_delim = unnecessary {$delim} around {$item}
     .suggestion = remove these {$delim}
 
-lint-unused-import-braces = braces around {$node} is unnecessary
+lint_unused_import_braces = braces around {$node} is unnecessary
 
-lint-unused-allocation = unnecessary allocation, use `&` instead
-lint-unused-allocation-mut = unnecessary allocation, use `&mut` instead
+lint_unused_allocation = unnecessary allocation, use `&` instead
+lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead
 
-lint-builtin-while-true = denote infinite loops with `loop {"{"} ... {"}"}`
+lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}`
     .suggestion = use `loop`
 
-lint-builtin-box-pointers = type uses owned (Box type) pointers: {$ty}
+lint_builtin_box_pointers = type uses owned (Box type) pointers: {$ty}
 
-lint-builtin-non-shorthand-field-patterns = the `{$ident}:` in this pattern is redundant
+lint_builtin_non_shorthand_field_patterns = the `{$ident}:` in this pattern is redundant
     .suggestion = use shorthand field pattern
 
-lint-builtin-overridden-symbol-name =
+lint_builtin_overridden_symbol_name =
     the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them
 
-lint-builtin-overridden-symbol-section =
+lint_builtin_overridden_symbol_section =
     the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them
 
-lint-builtin-allow-internal-unsafe =
+lint_builtin_allow_internal_unsafe =
     `allow_internal_unsafe` allows defining macros using unsafe without triggering the `unsafe_code` lint at their call site
 
-lint-builtin-unsafe-block = usage of an `unsafe` block
+lint_builtin_unsafe_block = usage of an `unsafe` block
 
-lint-builtin-unsafe-trait = declaration of an `unsafe` trait
+lint_builtin_unsafe_trait = declaration of an `unsafe` trait
 
-lint-builtin-unsafe-impl = implementation of an `unsafe` trait
+lint_builtin_unsafe_impl = implementation of an `unsafe` trait
 
-lint-builtin-no-mangle-fn = declaration of a `no_mangle` function
-lint-builtin-export-name-fn = declaration of a function with `export_name`
-lint-builtin-link-section-fn = declaration of a function with `link_section`
+lint_builtin_no_mangle_fn = declaration of a `no_mangle` function
+lint_builtin_export_name_fn = declaration of a function with `export_name`
+lint_builtin_link_section_fn = declaration of a function with `link_section`
 
-lint-builtin-no-mangle-static = declaration of a `no_mangle` static
-lint-builtin-export-name-static = declaration of a static with `export_name`
-lint-builtin-link-section-static = declaration of a static with `link_section`
+lint_builtin_no_mangle_static = declaration of a `no_mangle` static
+lint_builtin_export_name_static = declaration of a static with `export_name`
+lint_builtin_link_section_static = declaration of a static with `link_section`
 
-lint-builtin-no-mangle-method = declaration of a `no_mangle` method
-lint-builtin-export-name-method = declaration of a method with `export_name`
+lint_builtin_no_mangle_method = declaration of a `no_mangle` method
+lint_builtin_export_name_method = declaration of a method with `export_name`
 
-lint-builtin-decl-unsafe-fn = declaration of an `unsafe` function
-lint-builtin-decl-unsafe-method = declaration of an `unsafe` method
-lint-builtin-impl-unsafe-method = implementation of an `unsafe` method
+lint_builtin_decl_unsafe_fn = declaration of an `unsafe` function
+lint_builtin_decl_unsafe_method = declaration of an `unsafe` method
+lint_builtin_impl_unsafe_method = implementation of an `unsafe` method
 
-lint-builtin-missing-doc = missing documentation for {$article} {$desc}
+lint_builtin_missing_doc = missing documentation for {$article} {$desc}
 
-lint-builtin-missing-copy-impl = type could implement `Copy`; consider adding `impl Copy`
+lint_builtin_missing_copy_impl = type could implement `Copy`; consider adding `impl Copy`
 
-lint-builtin-missing-debug-impl =
+lint_builtin_missing_debug_impl =
     type does not implement `{$debug}`; consider adding `#[derive(Debug)]` or a manual implementation
 
-lint-builtin-anonymous-params = anonymous parameters are deprecated and will be removed in the next edition
+lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition
     .suggestion = try naming the parameter or explicitly ignoring it
 
-lint-builtin-deprecated-attr-link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
-lint-builtin-deprecated-attr-used = use of deprecated attribute `{$name}`: no longer used.
-lint-builtin-deprecated-attr-default-suggestion = remove this attribute
+lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
+lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
+lint_builtin_deprecated_attr_default_suggestion = remove this attribute
 
-lint-builtin-unused-doc-comment = unused doc comment
+lint_builtin_unused_doc_comment = unused doc comment
     .label = rustdoc does not generate documentation for {$kind}
-    .plain-help = use `//` for a plain comment
-    .block-help = use `/* */` for a plain comment
+    .plain_help = use `//` for a plain comment
+    .block_help = use `/* */` for a plain comment
 
-lint-builtin-no-mangle-generic = functions generic over types or consts must be mangled
+lint_builtin_no_mangle_generic = functions generic over types or consts must be mangled
     .suggestion = remove this attribute
 
-lint-builtin-const-no-mangle = const items should never be `#[no_mangle]`
+lint_builtin_const_no_mangle = const items should never be `#[no_mangle]`
     .suggestion = try a static value
 
-lint-builtin-mutable-transmutes =
+lint_builtin_mutable_transmutes =
     transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
 
-lint-builtin-unstable-features = unstable feature
+lint_builtin_unstable_features = unstable feature
 
-lint-builtin-unreachable-pub = unreachable `pub` {$what}
+lint_builtin_unreachable_pub = unreachable `pub` {$what}
     .suggestion = consider restricting its visibility
     .help = or consider exporting it for use by other crates
 
-lint-builtin-type-alias-bounds-help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
+lint_builtin_type_alias_bounds_help = use fully disambiguated paths (i.e., `<T as Trait>::Assoc`) to refer to associated types in type aliases
 
-lint-builtin-type-alias-where-clause = where clauses are not enforced in type aliases
+lint_builtin_type_alias_where_clause = where clauses are not enforced in type aliases
     .suggestion = the clause will not be checked when the type alias is used, and should be removed
 
-lint-builtin-type-alias-generic-bounds = bounds on generic parameters are not enforced in type aliases
+lint_builtin_type_alias_generic_bounds = bounds on generic parameters are not enforced in type aliases
     .suggestion = the bound will not be checked when the type alias is used, and should be removed
 
-lint-builtin-trivial-bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
+lint_builtin_trivial_bounds = {$predicate_kind_name} bound {$predicate} does not depend on any type or lifetime parameters
 
-lint-builtin-ellipsis-inclusive-range-patterns = `...` range patterns are deprecated
+lint_builtin_ellipsis_inclusive_range_patterns = `...` range patterns are deprecated
     .suggestion = use `..=` for an inclusive range
 
-lint-builtin-unnameable-test-items = cannot test inner items
+lint_builtin_unnameable_test_items = cannot test inner items
 
-lint-builtin-keyword-idents = `{$kw}` is a keyword in the {$next} edition
+lint_builtin_keyword_idents = `{$kw}` is a keyword in the {$next} edition
     .suggestion = you can use a raw identifier to stay compatible
 
-lint-builtin-explicit-outlives = outlives requirements can be inferred
+lint_builtin_explicit_outlives = outlives requirements can be inferred
     .suggestion = remove {$count ->
         [one] this bound
         *[other] these bounds
     }
 
-lint-builtin-incomplete-features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
+lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may not be safe to use and/or cause compiler crashes
     .note = see issue #{$n} <https://github.com/rust-lang/rust/issues/{$n}> for more information
     .help = consider using `min_{$name}` instead, which is more stable and complete
 
-lint-builtin-clashing-extern-same-name = `{$this_fi}` redeclared with a different signature
-    .previous-decl-label = `{$orig}` previously declared here
-    .mismatch-label = this signature doesn't match the previous declaration
-lint-builtin-clashing-extern-diff-name = `{$this_fi}` redeclares `{$orig}` with a different signature
-    .previous-decl-label = `{$orig}` previously declared here
-    .mismatch-label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_same_name = `{$this_fi}` redeclared with a different signature
+    .previous_decl_label = `{$orig}` previously declared here
+    .mismatch_label = this signature doesn't match the previous declaration
+lint_builtin_clashing_extern_diff_name = `{$this_fi}` redeclares `{$orig}` with a different signature
+    .previous_decl_label = `{$orig}` previously declared here
+    .mismatch_label = this signature doesn't match the previous declaration
 
-lint-builtin-deref-nullptr = dereferencing a null pointer
+lint_builtin_deref_nullptr = dereferencing a null pointer
     .label = this code causes undefined behavior when executed
 
-lint-builtin-asm-labels = avoid using named labels in inline assembly
+lint_builtin_asm_labels = avoid using named labels in inline assembly
diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl
index 076b1b1caed..7e583753618 100644
--- a/compiler/rustc_error_messages/locales/en-US/parser.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl
@@ -1,34 +1,34 @@
-parser-struct-literal-body-without-path =
+parser_struct_literal_body_without_path =
     struct literal body without path
     .suggestion = you might have forgotten to add the struct literal inside the block
 
-parser-maybe-report-ambiguous-plus =
+parser_maybe_report_ambiguous_plus =
     ambiguous `+` in a type
     .suggestion = use parentheses to disambiguate
 
-parser-maybe-recover-from-bad-type-plus =
+parser_maybe_recover_from_bad_type_plus =
     expected a path on the left-hand side of `+`, not `{$ty}`
 
-parser-add-paren = try adding parentheses
+parser_add_paren = try adding parentheses
 
-parser-forgot-paren = perhaps you forgot parentheses?
+parser_forgot_paren = perhaps you forgot parentheses?
 
-parser-expect-path = expected a path
+parser_expect_path = expected a path
 
-parser-maybe-recover-from-bad-qpath-stage-2 =
+parser_maybe_recover_from_bad_qpath_stage_2 =
     missing angle brackets in associated item path
     .suggestion = try: `{$ty}`
 
-parser-incorrect-semicolon =
+parser_incorrect_semicolon =
     expected item, found `;`
     .suggestion = remove this semicolon
     .help = {$name} declarations are not followed by a semicolon
 
-parser-incorrect-use-of-await =
+parser_incorrect_use_of_await =
     incorrect use of `await`
-    .parentheses-suggestion = `await` is not a method call, remove the parentheses
-    .postfix-suggestion = `await` is a postfix operation
+    .parentheses_suggestion = `await` is not a method call, remove the parentheses
+    .postfix_suggestion = `await` is a postfix operation
 
-parser-in-in-typo =
+parser_in_in_typo =
     expected iterable, found keyword `in`
     .suggestion = remove the duplicated `in`
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl
index d8056c77f0f..7374f6d3f27 100644
--- a/compiler/rustc_error_messages/locales/en-US/passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl
@@ -1,178 +1,178 @@
--passes-previously-accepted =
+-passes_previously_accepted =
     this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
--passes-see-issue =
+-passes_see_issue =
     see issue #{$issue} <https://github.com/rust-lang/rust/issues/{$issue}> for more information
 
-passes-outer-crate-level-attr =
+passes_outer_crate_level_attr =
     crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
 
-passes-inner-crate-level-attr =
+passes_inner_crate_level_attr =
     crate-level attribute should be in the root module
 
-passes-ignored-attr-with-macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
-    .warn = {-passes-previously-accepted}
-    .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr_with_macro = `#[{$sym}]` is ignored on struct fields, match arms and macro defs
+    .warn = {-passes_previously_accepted}
+    .note = {-passes_see_issue(issue: "80564")}
 
-passes-ignored-attr = `#[{$sym}]` is ignored on struct fields and match arms
-    .warn = {-passes-previously-accepted}
-    .note = {-passes-see-issue(issue: "80564")}
+passes_ignored_attr = `#[{$sym}]` is ignored on struct fields and match arms
+    .warn = {-passes_previously_accepted}
+    .note = {-passes_see_issue(issue: "80564")}
 
-passes-inline-ignored-function-prototype = `#[inline]` is ignored on function prototypes
+passes_inline_ignored_function_prototype = `#[inline]` is ignored on function prototypes
 
-passes-inline-ignored-constants = `#[inline]` is ignored on constants
-    .warn = {-passes-previously-accepted}
-    .note = {-passes-see-issue(issue: "65833")}
+passes_inline_ignored_constants = `#[inline]` is ignored on constants
+    .warn = {-passes_previously_accepted}
+    .note = {-passes_see_issue(issue: "65833")}
 
-passes-inline-not-fn-or-closure = attribute should be applied to function or closure
+passes_inline_not_fn_or_closure = attribute should be applied to function or closure
     .label = not a function or closure
 
-passes-no-coverage-ignored-function-prototype = `#[no_coverage]` is ignored on function prototypes
+passes_no_coverage_ignored_function_prototype = `#[no_coverage]` is ignored on function prototypes
 
-passes-no-coverage-propagate =
+passes_no_coverage_propagate =
     `#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
 
-passes-no-coverage-fn-defn = `#[no_coverage]` may only be applied to function definitions
+passes_no_coverage_fn_defn = `#[no_coverage]` may only be applied to function definitions
 
-passes-no-coverage-not-coverable = `#[no_coverage]` must be applied to coverable code
+passes_no_coverage_not_coverable = `#[no_coverage]` must be applied to coverable code
     .label = not coverable code
 
-passes-should-be-applied-to-fn = attribute should be applied to a function definition
+passes_should_be_applied_to_fn = attribute should be applied to a function definition
     .label = not a function definition
 
-passes-naked-tracked-caller = cannot use `#[track_caller]` with `#[naked]`
+passes_naked_tracked_caller = cannot use `#[track_caller]` with `#[naked]`
 
-passes-should-be-applied-to-struct-enum = attribute should be applied to a struct or enum
+passes_should_be_applied_to_struct_enum = attribute should be applied to a struct or enum
     .label = not a struct or enum
 
-passes-should-be-applied-to-trait = attribute should be applied to a trait
+passes_should_be_applied_to_trait = attribute should be applied to a trait
     .label = not a trait
 
-passes-target-feature-on-statement = {passes-should-be-applied-to-fn}
-    .warn = {-passes-previously-accepted}
-    .label = {passes-should-be-applied-to-fn.label}
+passes_target_feature_on_statement = {passes_should_be_applied_to_fn}
+    .warn = {-passes_previously_accepted}
+    .label = {passes_should_be_applied_to_fn.label}
 
-passes-should-be-applied-to-static = attribute should be applied to a static
+passes_should_be_applied_to_static = attribute should be applied to a static
     .label = not a static
 
-passes-doc-expect-str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
+passes_doc_expect_str = doc {$attr_name} attribute expects a string: #[doc({$attr_name} = "a")]
 
-passes-doc-alias-empty = {$attr_str} attribute cannot have empty value
+passes_doc_alias_empty = {$attr_str} attribute cannot have empty value
 
-passes-doc-alias-bad-char = {$char_} character isn't allowed in {$attr_str}
+passes_doc_alias_bad_char = {$char_} character isn't allowed in {$attr_str}
 
-passes-doc-alias-start-end = {$attr_str} cannot start or end with ' '
+passes_doc_alias_start_end = {$attr_str} cannot start or end with ' '
 
-passes-doc-alias-bad-location = {$attr_str} isn't allowed on {$location}
+passes_doc_alias_bad_location = {$attr_str} isn't allowed on {$location}
 
-passes-doc-alias-not-an-alias = {$attr_str} is the same as the item's name
+passes_doc_alias_not_an_alias = {$attr_str} is the same as the item's name
 
-passes-doc-alias-duplicated = doc alias is duplicated
+passes_doc_alias_duplicated = doc alias is duplicated
     .label = first defined here
 
-passes-doc-alias-not-string-literal = `#[doc(alias("a"))]` expects string literals
+passes_doc_alias_not_string_literal = `#[doc(alias("a"))]` expects string literals
 
-passes-doc-alias-malformed =
+passes_doc_alias_malformed =
     doc alias attribute expects a string `#[doc(alias = "a")]` or a list of strings `#[doc(alias("a", "b"))]`
 
-passes-doc-keyword-empty-mod = `#[doc(keyword = "...")]` should be used on empty modules
+passes_doc_keyword_empty_mod = `#[doc(keyword = "...")]` should be used on empty modules
 
-passes-doc-keyword-not-mod = `#[doc(keyword = "...")]` should be used on modules
+passes_doc_keyword_not_mod = `#[doc(keyword = "...")]` should be used on modules
 
-passes-doc-keyword-invalid-ident = `{$doc_keyword}` is not a valid identifier
+passes_doc_keyword_invalid_ident = `{$doc_keyword}` is not a valid identifier
 
-passes-doc-fake-variadic-not-valid =
+passes_doc_fake_variadic_not_valid =
     `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity
 
-passes-doc-keyword-only-impl = `#[doc(keyword = "...")]` should be used on impl blocks
+passes_doc_keyword_only_impl = `#[doc(keyword = "...")]` should be used on impl blocks
 
-passes-doc-inline-conflict-first = this attribute...
-passes-doc-inline-conflict-second = ...conflicts with this attribute
-passes-doc-inline-conflict = conflicting doc inlining attributes
+passes_doc_inline_conflict_first = this attribute...
+passes_doc_inline_conflict_second = ...conflicts with this attribute
+passes_doc_inline_conflict = conflicting doc inlining attributes
     .help = remove one of the conflicting attributes
 
-passes-doc-inline-only-use = this attribute can only be applied to a `use` item
+passes_doc_inline_only_use = this attribute can only be applied to a `use` item
     .label = only applicable on `use` items
-    .not-a-use-item-label = not a `use` item
+    .not_a_use_item_label = not a `use` item
     .note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> for more information
 
-passes-doc-attr-not-crate-level =
+passes_doc_attr_not_crate_level =
     `#![doc({$attr_name} = "...")]` isn't allowed as a crate-level attribute
 
-passes-attr-crate-level = this attribute can only be applied at the crate level
+passes_attr_crate_level = this attribute can only be applied at the crate level
     .suggestion = to apply to the crate, use an inner attribute
     .help = to apply to the crate, use an inner attribute
     .note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
 
-passes-doc-test-unknown = unknown `doc(test)` attribute `{$path}`
+passes_doc_test_unknown = unknown `doc(test)` attribute `{$path}`
 
-passes-doc-test-takes-list = `#[doc(test(...)]` takes a list of attributes
+passes_doc_test_takes_list = `#[doc(test(...)]` takes a list of attributes
 
-passes-doc-primitive = `doc(primitive)` should never have been stable
+passes_doc_primitive = `doc(primitive)` should never have been stable
 
-passes-doc-test-unknown-any = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_any = unknown `doc` attribute `{$path}`
 
-passes-doc-test-unknown-spotlight = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_spotlight = unknown `doc` attribute `{$path}`
     .note = `doc(spotlight)` was renamed to `doc(notable_trait)`
     .suggestion = use `notable_trait` instead
-    .no-op-note = `doc(spotlight)` is now a no-op
+    .no_op_note = `doc(spotlight)` is now a no-op
 
-passes-doc-test-unknown-include = unknown `doc` attribute `{$path}`
+passes_doc_test_unknown_include = unknown `doc` attribute `{$path}`
     .suggestion = use `doc = include_str!` instead
 
-passes-doc-invalid = invalid `doc` attribute
+passes_doc_invalid = invalid `doc` attribute
 
-passes-pass-by-value = `pass_by_value` attribute should be applied to a struct, enum or type alias
+passes_pass_by_value = `pass_by_value` attribute should be applied to a struct, enum or type alias
     .label = is not a struct, enum or type alias
 
-passes-allow-incoherent-impl =
+passes_allow_incoherent_impl =
     `rustc_allow_incoherent_impl` attribute should be applied to impl items.
     .label = the only currently supported targets are inherent methods
 
-passes-has-incoherent-inherent-impl =
+passes_has_incoherent_inherent_impl =
     `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
     .label = only adts, extern types and traits are supported
 
-passes-must-use-async =
+passes_must_use_async =
     `must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
     .label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
 
-passes-must-use-no-effect = `#[must_use]` has no effect when applied to {$article} {$target}
+passes_must_use_no_effect = `#[must_use]` has no effect when applied to {$article} {$target}
 
-passes-must-not-suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
+passes_must_not_suspend = `must_not_suspend` attribute should be applied to a struct, enum, or trait
     .label = is not a struct, enum, or trait
 
-passes-cold = {passes-should-be-applied-to-fn}
-    .warn = {-passes-previously-accepted}
-    .label = {passes-should-be-applied-to-fn.label}
+passes_cold = {passes_should_be_applied_to_fn}
+    .warn = {-passes_previously_accepted}
+    .label = {passes_should_be_applied_to_fn.label}
 
-passes-link = attribute should be applied to an `extern` block with non-Rust ABI
-    .warn = {-passes-previously-accepted}
+passes_link = attribute should be applied to an `extern` block with non-Rust ABI
+    .warn = {-passes_previously_accepted}
     .label = not an `extern` block
 
-passes-link-name = attribute should be applied to a foreign function or static
-    .warn = {-passes-previously-accepted}
+passes_link_name = attribute should be applied to a foreign function or static
+    .warn = {-passes_previously_accepted}
     .label = not a foreign function or static
     .help = try `#[link(name = "{$value}")]` instead
 
-passes-no-link = attribute should be applied to an `extern crate` item
+passes_no_link = attribute should be applied to an `extern crate` item
     .label = not an `extern crate` item
 
-passes-export-name = attribute should be applied to a free function, impl method or static
+passes_export_name = attribute should be applied to a free function, impl method or static
     .label = not a free function, impl method or static
 
-passes-rustc-layout-scalar-valid-range-not-struct = attribute should be applied to a struct
+passes_rustc_layout_scalar_valid_range_not_struct = attribute should be applied to a struct
     .label = not a struct
 
-passes-rustc-layout-scalar-valid-range-arg = expected exactly one integer literal argument
+passes_rustc_layout_scalar_valid_range_arg = expected exactly one integer literal argument
 
-passes-rustc-legacy-const-generics-only = #[rustc_legacy_const_generics] functions must only have const generics
+passes_rustc_legacy_const_generics_only = #[rustc_legacy_const_generics] functions must only have const generics
     .label = non-const generic parameter
 
-passes-rustc-legacy-const-generics-index = #[rustc_legacy_const_generics] must have one index for each generic parameter
+passes_rustc_legacy_const_generics_index = #[rustc_legacy_const_generics] must have one index for each generic parameter
     .label = generic parameters
 
-passes-rustc-legacy-const-generics-index-exceed = index exceeds number of arguments
+passes_rustc_legacy_const_generics_index_exceed = index exceeds number of arguments
     .label = there {$arg_count ->
         [one] is
         *[other] are
@@ -181,87 +181,87 @@ passes-rustc-legacy-const-generics-index-exceed = index exceeds number of argume
         *[other] arguments
     }
 
-passes-rustc-legacy-const-generics-index-negative = arguments should be non-negative integers
+passes_rustc_legacy_const_generics_index_negative = arguments should be non-negative integers
 
-passes-rustc-dirty-clean = attribute requires -Z query-dep-graph to be enabled
+passes_rustc_dirty_clean = attribute requires -Z query-dep-graph to be enabled
 
-passes-link-section = attribute should be applied to a function or static
-    .warn = {-passes-previously-accepted}
+passes_link_section = attribute should be applied to a function or static
+    .warn = {-passes_previously_accepted}
     .label = not a function or static
 
-passes-no-mangle-foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
-    .warn = {-passes-previously-accepted}
+passes_no_mangle_foreign = `#[no_mangle]` has no effect on a foreign {$foreign_item_kind}
+    .warn = {-passes_previously_accepted}
     .label = foreign {$foreign_item_kind}
     .note = symbol names in extern blocks are not mangled
     .suggestion = remove this attribute
 
-passes-no-mangle = attribute should be applied to a free function, impl method or static
-    .warn = {-passes-previously-accepted}
+passes_no_mangle = attribute should be applied to a free function, impl method or static
+    .warn = {-passes_previously_accepted}
     .label = not a free function, impl method or static
 
-passes-repr-ident = meta item in `repr` must be an identifier
+passes_repr_ident = meta item in `repr` must be an identifier
 
-passes-repr-conflicting = conflicting representation hints
+passes_repr_conflicting = conflicting representation hints
 
-passes-used-static = attribute must be applied to a `static` variable
+passes_used_static = attribute must be applied to a `static` variable
 
-passes-used-compiler-linker = `used(compiler)` and `used(linker)` can't be used together
+passes_used_compiler_linker = `used(compiler)` and `used(linker)` can't be used together
 
-passes-allow-internal-unstable = attribute should be applied to a macro
+passes_allow_internal_unstable = attribute should be applied to a macro
     .label = not a macro
 
-passes-debug-visualizer-placement = attribute should be applied to a module
+passes_debug_visualizer_placement = attribute should be applied to a module
 
-passes-debug-visualizer-invalid = invalid argument
-    .note-1 = expected: `natvis_file = "..."`
-    .note-2 = OR
-    .note-3 = expected: `gdb_script_file = "..."`
+passes_debug_visualizer_invalid = invalid argument
+    .note_1 = expected: `natvis_file = "..."`
+    .note_2 = OR
+    .note_3 = expected: `gdb_script_file = "..."`
 
-passes-rustc-allow-const-fn-unstable = attribute should be applied to `const fn`
+passes_rustc_allow_const_fn_unstable = attribute should be applied to `const fn`
     .label = not a `const fn`
 
-passes-rustc-std-internal-symbol = attribute should be applied to functions or statics
+passes_rustc_std_internal_symbol = attribute should be applied to functions or statics
     .label = not a function or static
 
-passes-const-trait = attribute should be applied to a trait
+passes_const_trait = attribute should be applied to a trait
 
-passes-stability-promotable = attribute cannot be applied to an expression
+passes_stability_promotable = attribute cannot be applied to an expression
 
-passes-deprecated = attribute is ignored here
+passes_deprecated = attribute is ignored here
 
-passes-macro-use = `#[{$name}]` only has an effect on `extern crate` and modules
+passes_macro_use = `#[{$name}]` only has an effect on `extern crate` and modules
 
-passes-macro-export = `#[macro_export]` only has an effect on macro definitions
+passes_macro_export = `#[macro_export]` only has an effect on macro definitions
 
-passes-plugin-registrar = `#[plugin_registrar]` only has an effect on functions
+passes_plugin_registrar = `#[plugin_registrar]` only has an effect on functions
 
-passes-unused-empty-lints-note = attribute `{$name}` with an empty list has no effect
+passes_unused_empty_lints_note = attribute `{$name}` with an empty list has no effect
 
-passes-unused-no-lints-note = attribute `{$name}` without any lints has no effect
+passes_unused_no_lints_note = attribute `{$name}` without any lints has no effect
 
-passes-unused-default-method-body-const-note =
+passes_unused_default_method_body_const_note =
     `default_method_body_is_const` has been replaced with `#[const_trait]` on traits
 
-passes-unused = unused attribute
+passes_unused = unused attribute
     .suggestion = remove this attribute
 
-passes-non-exported-macro-invalid-attrs = attribute should be applied to function or closure
+passes_non_exported_macro_invalid_attrs = attribute should be applied to function or closure
     .label = not a function or closure
 
-passes-unused-duplicate = unused attribute
+passes_unused_duplicate = unused attribute
     .suggestion = remove this attribute
     .note = attribute also specified here
-    .warn = {-passes-previously-accepted}
+    .warn = {-passes_previously_accepted}
 
-passes-unused-multiple = multiple `{$name}` attributes
+passes_unused_multiple = multiple `{$name}` attributes
     .suggestion = remove this attribute
     .note = attribute also specified here
 
-passes-rustc-lint-opt-ty = `#[rustc_lint_opt_ty]` should be applied to a struct
+passes_rustc_lint_opt_ty = `#[rustc_lint_opt_ty]` should be applied to a struct
     .label = not a struct
 
-passes-rustc-lint-opt-deny-field-access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
+passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` should be applied to a field
     .label = not a field
 
-passes-link-ordinal = attribute should be applied to a foreign function or static
-    .label = not a foreign function or static
\ No newline at end of file
+passes_link_ordinal = attribute should be applied to a foreign function or static
+    .label = not a foreign function or static
diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_error_messages/locales/en-US/privacy.ftl
index f8a750da93f..97050635f45 100644
--- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/privacy.ftl
@@ -1,20 +1,20 @@
-privacy-field-is-private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
-privacy-field-is-private-is-update-syntax-label = field `{$field_name}` is private
-privacy-field-is-private-label = private field
+privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
+privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
+privacy_field_is_private_label = private field
 
-privacy-item-is-private = {$kind} `{$descr}` is private
+privacy_item_is_private = {$kind} `{$descr}` is private
     .label = private {$kind}
-privacy-unnamed-item-is-private = {$kind} is private
+privacy_unnamed_item_is_private = {$kind} is private
     .label = private {$kind}
 
-privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
+privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface
     .label = can't leak {$vis_descr} {$kind}
-    .visibility-label = `{$descr}` declared as {$vis_descr}
+    .visibility_label = `{$descr}` declared as {$vis_descr}
 
-privacy-from-private-dep-in-public-interface =
+privacy_from_private_dep_in_public_interface =
     {$kind} `{$descr}` from private dependency '{$krate}' in public interface
 
-private-in-public-lint =
+private_in_public_lint =
     {$vis_descr} {$kind} `{$descr}` in public interface (error {$kind ->
         [trait] E0445
         *[other] E0446
diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
index c61735a57e1..494b8f91393 100644
--- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/typeck.ftl
@@ -1,101 +1,101 @@
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
     field `{$ident}` specified more than once
     .label = used more than once
-    .previous-use-label = first use of `{$ident}`
+    .previous_use_label = first use of `{$ident}`
 
-typeck-unrecognized-atomic-operation =
+typeck_unrecognized_atomic_operation =
     unrecognized atomic operation function: `{$op}`
     .label = unrecognized atomic operation
 
-typeck-wrong-number-of-generic-arguments-to-intrinsic =
+typeck_wrong_number_of_generic_arguments_to_intrinsic =
     intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
     .label = expected {$expected} {$descr} {$expected ->
         [one] parameter
         *[other] parameters
     }
 
-typeck-unrecognized-intrinsic-function =
+typeck_unrecognized_intrinsic_function =
     unrecognized intrinsic function: `{$name}`
     .label = unrecognized intrinsic
 
-typeck-lifetimes-or-bounds-mismatch-on-trait =
+typeck_lifetimes_or_bounds_mismatch_on_trait =
     lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
     .label = lifetimes do not match {$item_kind} in trait
-    .generics-label = lifetimes in impl do not match this {$item_kind} in trait
+    .generics_label = lifetimes in impl do not match this {$item_kind} in trait
 
-typeck-drop-impl-on-wrong-item =
+typeck_drop_impl_on_wrong_item =
     the `Drop` trait may only be implemented for structs, enums, and unions
     .label = must be a struct, enum, or union
 
-typeck-field-already-declared =
+typeck_field_already_declared =
     field `{$field_name}` is already declared
     .label = field already declared
-    .previous-decl-label = `{$field_name}` first declared here
+    .previous_decl_label = `{$field_name}` first declared here
 
-typeck-copy-impl-on-type-with-dtor =
+typeck_copy_impl_on_type_with_dtor =
     the trait `Copy` may not be implemented for this type; the type has a destructor
     .label = `Copy` not allowed on types with destructors
 
-typeck-multiple-relaxed-default-bounds =
+typeck_multiple_relaxed_default_bounds =
     type parameter has more than one relaxed default bound, only one is supported
 
-typeck-copy-impl-on-non-adt =
+typeck_copy_impl_on_non_adt =
     the trait `Copy` may not be implemented for this type
     .label = type is not a structure or enumeration
 
-typeck-trait-object-declared-with-no-traits =
+typeck_trait_object_declared_with_no_traits =
     at least one trait is required for an object type
-    .alias-span = this alias does not contain a trait
+    .alias_span = this alias does not contain a trait
 
-typeck-ambiguous-lifetime-bound =
+typeck_ambiguous_lifetime_bound =
     ambiguous lifetime bound, explicit lifetime bound required
 
-typeck-assoc-type-binding-not-allowed =
+typeck_assoc_type_binding_not_allowed =
     associated type bindings are not allowed here
     .label = associated type not allowed here
 
-typeck-functional-record-update-on-non-struct =
+typeck_functional_record_update_on_non_struct =
     functional record update syntax requires a struct
 
-typeck-typeof-reserved-keyword-used =
+typeck_typeof_reserved_keyword_used =
     `typeof` is a reserved keyword but unimplemented
     .suggestion = consider replacing `typeof(...)` with an actual type
     .label = reserved keyword
 
-typeck-return-stmt-outside-of-fn-body =
+typeck_return_stmt_outside_of_fn_body =
     return statement outside of function body
-    .encl-body-label = the return is part of this body...
-    .encl-fn-label = ...not the enclosing function body
+    .encl_body_label = the return is part of this body...
+    .encl_fn_label = ...not the enclosing function body
 
-typeck-yield-expr-outside-of-generator =
+typeck_yield_expr_outside_of_generator =
     yield expression outside of generator literal
 
-typeck-struct-expr-non-exhaustive =
+typeck_struct_expr_non_exhaustive =
     cannot create non-exhaustive {$what} using struct expression
 
-typeck-method-call-on-unknown-type =
+typeck_method_call_on_unknown_type =
     the type of this value must be known to call a method on a raw pointer on it
 
-typeck-value-of-associated-struct-already-specified =
+typeck_value_of_associated_struct_already_specified =
     the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
     .label = re-bound here
-    .previous-bound-label = `{$item_name}` bound here first
+    .previous_bound_label = `{$item_name}` bound here first
 
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
     .label = temporary value
 
-typeck-add-return-type-add = try adding a return type
+typeck_add_return_type_add = try adding a return type
 
-typeck-add-return-type-missing-here = a return type might be missing here
+typeck_add_return_type_missing_here = a return type might be missing here
 
-typeck-expected-default-return-type = expected `()` because of default return type
+typeck_expected_default_return_type = expected `()` because of default return type
 
-typeck-expected-return-type = expected `{$expected}` because of return type
+typeck_expected_return_type = expected `{$expected}` because of return type
 
-typeck-unconstrained-opaque-type = unconstrained opaque type
+typeck_unconstrained_opaque_type = unconstrained opaque type
     .note = `{$name}` must be used in combination with a concrete type within the same module
 
-typeck-missing-type-params =
+typeck_missing_type_params =
     the type {$parameterCount ->
         [one] parameter
         *[other] parameters
@@ -111,15 +111,15 @@ typeck-missing-type-params =
         [one] type
         *[other] types
     }
-    .no-suggestion-label = missing {$parameterCount ->
+    .no_suggestion_label = missing {$parameterCount ->
         [one] reference
         *[other] references
     } to {$parameters}
     .note = because of the default `Self` reference, type parameters must be specified on object types
 
-typeck-manual-implementation =
+typeck_manual_implementation =
     manual implementations of `{$trait_name}` are experimental
     .label = manual implementations of `{$trait_name}` are experimental
     .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
-typeck-substs-on-overridden-impl = could not resolve substs on overridden impl
+typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs
index 562d5e9f4d2..2e7652ad333 100644
--- a/compiler/rustc_macros/src/diagnostics/fluent.rs
+++ b/compiler/rustc_macros/src/diagnostics/fluent.rs
@@ -189,13 +189,25 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
             if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
                 let _ = previous_defns.entry(name.to_string()).or_insert(ident_span);
 
-                // `typeck-foo-bar` => `foo_bar` (in `typeck.ftl`)
-                // `const-eval-baz` => `baz` (in `const_eval.ftl`)
+                if name.contains('-') {
+                    Diagnostic::spanned(
+                        ident_span,
+                        Level::Error,
+                        format!("name `{name}` contains a '-' character"),
+                    )
+                    .help("replace any '-'s with '_'s")
+                    .emit();
+                }
+
+                // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
+                // `const_eval_baz` => `baz` (in `const_eval.ftl`)
+                // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
+                // The last case we error about above, but we want to fall back gracefully
+                // so that only the error is being emitted and not also one about the macro
+                // failing.
                 let snake_name = Ident::new(
                     // FIXME: should probably trim prefix, not replace all occurrences
-                    &name
-                        .replace(&format!("{}-", res.ident).replace('_', "-"), "")
-                        .replace('-', "_"),
+                    &name.replace('-', "_").replace(&format!("{}_", res.ident), ""),
                     span,
                 );
                 constants.extend(quote! {
@@ -212,6 +224,16 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
                         continue;
                     }
 
+                    if attr_name.contains('-') {
+                        Diagnostic::spanned(
+                            ident_span,
+                            Level::Error,
+                            format!("attribute `{attr_name}` contains a '-' character"),
+                        )
+                        .help("replace any '-'s with '_'s")
+                        .emit();
+                    }
+
                     constants.extend(quote! {
                         pub const #snake_name: crate::SubdiagnosticMessage =
                             crate::SubdiagnosticMessage::FluentAttr(
diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs
index 39979002666..733454cb2a7 100644
--- a/compiler/rustc_macros/src/diagnostics/mod.rs
+++ b/compiler/rustc_macros/src/diagnostics/mod.rs
@@ -38,9 +38,9 @@ use synstructure::Structure;
 /// ```
 ///
 /// ```fluent
-/// move-out-of-borrow = cannot move out of {$name} because it is borrowed
+/// move_out_of_borrow = cannot move out of {$name} because it is borrowed
 ///     .label = cannot move out of borrow
-///     .first-borrow-label = `{$ty}` first borrowed here
+///     .first_borrow_label = `{$ty}` first borrowed here
 ///     .suggestion = consider cloning here
 /// ```
 ///
@@ -84,9 +84,9 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 /// ```
 ///
 /// ```fluent
-/// lint-atomic-ordering-invalid-fail-success = `{$method}`'s success ordering must be at least as strong as its failure ordering
-///     .fail-label = `{$fail_ordering}` failure ordering
-///     .success-label = `{$success_ordering}` success ordering
+/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering
+///     .fail_label = `{$fail_ordering}` failure ordering
+///     .success_label = `{$success_ordering}` success ordering
 ///     .suggestion = consider using `{$success_suggestion}` success ordering instead
 /// ```
 ///
@@ -140,11 +140,11 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
 /// ```
 ///
 /// ```fluent
-/// parser-expected-identifier = expected identifier
+/// parser_expected_identifier = expected identifier
 ///
-/// parser-expected-identifier-found = expected identifier, found {$found}
+/// parser_expected_identifier-found = expected identifier, found {$found}
 ///
-/// parser-raw-identifier = escape `{$ident}` to use it as an identifier
+/// parser_raw_identifier = escape `{$ident}` to use it as an identifier
 /// ```
 ///
 /// Then, later, to add the subdiagnostic:
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index ab509b26f1c..2f9c13cf817 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -65,10 +65,10 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
 /// ..where `typeck.ftl` has the following contents..
 ///
 /// ```fluent
-/// typeck-field-multiply-specified-in-initializer =
+/// typeck_field_multiply_specified_in_initializer =
 ///     field `{$ident}` specified more than once
 ///     .label = used more than once
-///     .label-previous-use = first use of `{$ident}`
+///     .label_previous_use = first use of `{$ident}`
 /// ```
 /// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and
 /// will generate the following code:
@@ -81,11 +81,11 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
 /// mod fluent_generated {
 ///     mod typeck {
 ///         pub const field_multiply_specified_in_initializer: DiagnosticMessage =
-///             DiagnosticMessage::fluent("typeck-field-multiply-specified-in-initializer");
+///             DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer");
 ///         pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage =
 ///             DiagnosticMessage::fluent_attr(
-///                 "typeck-field-multiply-specified-in-initializer",
-///                 "previous-use-label"
+///                 "typeck_field_multiply_specified_in_initializer",
+///                 "previous_use_label"
 ///             );
 ///     }
 /// }
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 018f0ad71ef..93e70e9abda 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -734,7 +734,7 @@ impl<'a> Parser<'a> {
             let mut snapshot = self.create_snapshot_for_diagnostic();
             let path =
                 Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None };
-            let struct_expr = snapshot.parse_struct_expr(None, path, AttrVec::new(), false);
+            let struct_expr = snapshot.parse_struct_expr(None, path, false);
             let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No);
             return Some(match (struct_expr, block_tail) {
                 (Ok(expr), Err(mut err)) => {
@@ -1188,8 +1188,7 @@ impl<'a> Parser<'a> {
             outer_op.node,
         );
 
-        let mk_err_expr =
-            |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err, AttrVec::new())));
+        let mk_err_expr = |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err)));
 
         match inner_op.kind {
             ExprKind::Binary(op, ref l1, ref r1) if op.node.is_comparison() => {
@@ -1647,7 +1646,6 @@ impl<'a> Parser<'a> {
         &mut self,
         lo: Span,
         await_sp: Span,
-        attrs: AttrVec,
     ) -> PResult<'a, P<Expr>> {
         let (hi, expr, is_question) = if self.token == token::Not {
             // Handle `await!(<expr>)`.
@@ -1662,7 +1660,7 @@ impl<'a> Parser<'a> {
             ExprKind::Try(_) => ExprKind::Err,
             _ => ExprKind::Await(expr),
         };
-        let expr = self.mk_expr(lo.to(sp), kind, attrs);
+        let expr = self.mk_expr(lo.to(sp), kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
@@ -1680,7 +1678,7 @@ impl<'a> Parser<'a> {
             // Handle `await { <expr> }`.
             // This needs to be handled separately from the next arm to avoid
             // interpreting `await { <expr> }?` as `<expr>?.await`.
-            self.parse_block_expr(None, self.token.span, BlockCheckMode::Default, AttrVec::new())
+            self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)
         } else {
             self.parse_expr()
         }
@@ -1823,7 +1821,7 @@ impl<'a> Parser<'a> {
                 err.emit();
                 // Recover from parse error, callers expect the closing delim to be consumed.
                 self.consume_block(delim, ConsumeClosingDelim::Yes);
-                self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err, AttrVec::new())
+                self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err)
             }
         }
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 33bebfc2c9a..9d6d632c2e8 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -20,7 +20,6 @@ use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty
 use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
 use rustc_ast::{ClosureBinder, StmtKind};
 use rustc_ast_pretty::pprust;
-use rustc_data_structures::thin_vec::ThinVec;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
 use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
 use rustc_session::lint::BuiltinLintDiagnostics;
@@ -45,20 +44,12 @@ macro_rules! maybe_whole_expr {
                 token::NtPath(path) => {
                     let path = (**path).clone();
                     $p.bump();
-                    return Ok($p.mk_expr(
-                        $p.prev_token.span,
-                        ExprKind::Path(None, path),
-                        AttrVec::new(),
-                    ));
+                    return Ok($p.mk_expr($p.prev_token.span, ExprKind::Path(None, path)));
                 }
                 token::NtBlock(block) => {
                     let block = block.clone();
                     $p.bump();
-                    return Ok($p.mk_expr(
-                        $p.prev_token.span,
-                        ExprKind::Block(block, None),
-                        AttrVec::new(),
-                    ));
+                    return Ok($p.mk_expr($p.prev_token.span, ExprKind::Block(block, None)));
                 }
                 _ => {}
             };
@@ -120,7 +111,7 @@ impl<'a> Parser<'a> {
                     // Special-case handling of `foo(_, _, _)`
                     err.emit();
                     self.bump();
-                    Ok(self.mk_expr(self.prev_token.span, ExprKind::Err, AttrVec::new()))
+                    Ok(self.mk_expr(self.prev_token.span, ExprKind::Err))
                 }
                 _ => Err(err),
             },
@@ -329,11 +320,9 @@ impl<'a> Parser<'a> {
                 | AssocOp::GreaterEqual => {
                     let ast_op = op.to_ast_binop().unwrap();
                     let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
-                    self.mk_expr(span, binary, AttrVec::new())
-                }
-                AssocOp::Assign => {
-                    self.mk_expr(span, ExprKind::Assign(lhs, rhs, cur_op_span), AttrVec::new())
+                    self.mk_expr(span, binary)
                 }
+                AssocOp::Assign => self.mk_expr(span, ExprKind::Assign(lhs, rhs, cur_op_span)),
                 AssocOp::AssignOp(k) => {
                     let aop = match k {
                         token::Plus => BinOpKind::Add,
@@ -348,7 +337,7 @@ impl<'a> Parser<'a> {
                         token::Shr => BinOpKind::Shr,
                     };
                     let aopexpr = self.mk_assign_op(source_map::respan(cur_op_span, aop), lhs, rhs);
-                    self.mk_expr(span, aopexpr, AttrVec::new())
+                    self.mk_expr(span, aopexpr)
                 }
                 AssocOp::As | AssocOp::Colon | AssocOp::DotDot | AssocOp::DotDotEq => {
                     self.span_bug(span, "AssocOp should have been handled by special case")
@@ -491,7 +480,7 @@ impl<'a> Parser<'a> {
         let limits =
             if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
         let range = self.mk_range(Some(lhs), rhs, limits);
-        Ok(self.mk_expr(span, range, AttrVec::new()))
+        Ok(self.mk_expr(span, range))
     }
 
     fn is_at_start_of_range_notation_rhs(&self) -> bool {
@@ -540,7 +529,7 @@ impl<'a> Parser<'a> {
                 (lo, None)
             };
             let range = this.mk_range(None, opt_end, limits);
-            Ok(this.mk_expr(span, range, attrs.into()))
+            Ok(this.mk_expr_with_attrs(span, range, attrs))
         })
     }
 
@@ -553,7 +542,7 @@ impl<'a> Parser<'a> {
             ($this:ident, $attrs:expr, |this, _| $body:expr) => {
                 $this.collect_tokens_for_expr($attrs, |$this, attrs| {
                     let (hi, ex) = $body?;
-                    Ok($this.mk_expr(lo.to(hi), ex, attrs.into()))
+                    Ok($this.mk_expr_with_attrs(lo.to(hi), ex, attrs))
                 })
             };
         }
@@ -705,11 +694,7 @@ impl<'a> Parser<'a> {
         expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind,
     ) -> PResult<'a, P<Expr>> {
         let mk_expr = |this: &mut Self, lhs: P<Expr>, rhs: P<Ty>| {
-            this.mk_expr(
-                this.mk_expr_sp(&lhs, lhs_span, rhs.span),
-                expr_kind(lhs, rhs),
-                AttrVec::new(),
-            )
+            this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs))
         };
 
         // Save the state of the parser before parsing type normally, in case there is a
@@ -737,7 +722,7 @@ impl<'a> Parser<'a> {
                                 segments[0].ident.span,
                             ),
                         };
-                        match self.parse_labeled_expr(label, AttrVec::new(), false) {
+                        match self.parse_labeled_expr(label, false) {
                             Ok(expr) => {
                                 type_err.cancel();
                                 self.struct_span_err(label.ident.span, "malformed loop label")
@@ -990,7 +975,7 @@ impl<'a> Parser<'a> {
             };
             if has_question {
                 // `expr?`
-                e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e), AttrVec::new());
+                e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e));
                 continue;
             }
             let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
@@ -1168,7 +1153,7 @@ impl<'a> Parser<'a> {
         let span = self.prev_token.span;
         let field = ExprKind::Field(base, Ident::new(field, span));
         self.expect_no_suffix(span, "a tuple index", suffix);
-        self.mk_expr(lo.to(span), field, AttrVec::new())
+        self.mk_expr(lo.to(span), field)
     }
 
     /// Parse a function call expression, `expr(...)`.
@@ -1182,9 +1167,9 @@ impl<'a> Parser<'a> {
         };
         let open_paren = self.token.span;
 
-        let mut seq = self.parse_paren_expr_seq().map(|args| {
-            self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args), AttrVec::new())
-        });
+        let mut seq = self
+            .parse_paren_expr_seq()
+            .map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args)));
         if let Some(expr) =
             self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot)
         {
@@ -1264,7 +1249,7 @@ impl<'a> Parser<'a> {
         let index = self.parse_expr()?;
         self.suggest_missing_semicolon_before_array(prev_span, open_delim_span)?;
         self.expect(&token::CloseDelim(Delimiter::Bracket))?;
-        Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index), AttrVec::new()))
+        Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_index(base, index)))
     }
 
     /// Assuming we have just parsed `.`, continue parsing into an expression.
@@ -1283,11 +1268,7 @@ impl<'a> Parser<'a> {
             let args = self.parse_paren_expr_seq()?;
             let fn_span = fn_span_lo.to(self.prev_token.span);
             let span = lo.to(self.prev_token.span);
-            Ok(self.mk_expr(
-                span,
-                ExprKind::MethodCall(segment, self_arg, args, fn_span),
-                AttrVec::new(),
-            ))
+            Ok(self.mk_expr(span, ExprKind::MethodCall(segment, self_arg, args, fn_span)))
         } else {
             // Field access `expr.f`
             if let Some(args) = segment.args {
@@ -1299,7 +1280,7 @@ impl<'a> Parser<'a> {
             }
 
             let span = lo.to(self.prev_token.span);
-            Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident), AttrVec::new()))
+            Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident)))
         }
     }
 
@@ -1314,10 +1295,6 @@ impl<'a> Parser<'a> {
 
         // Outer attributes are already parsed and will be
         // added to the return value after the fact.
-        //
-        // Therefore, prevent sub-parser from parsing
-        // attributes by giving them an empty "already-parsed" list.
-        let attrs = AttrVec::new();
 
         // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
         let lo = self.token.span;
@@ -1325,13 +1302,13 @@ impl<'a> Parser<'a> {
             // This match arm is a special-case of the `_` match arm below and
             // could be removed without changing functionality, but it's faster
             // to have it here, especially for programs with large constants.
-            self.parse_lit_expr(attrs)
+            self.parse_lit_expr()
         } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
-            self.parse_tuple_parens_expr(attrs)
+            self.parse_tuple_parens_expr()
         } else if self.check(&token::OpenDelim(Delimiter::Brace)) {
-            self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs)
+            self.parse_block_expr(None, lo, BlockCheckMode::Default)
         } else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) {
-            self.parse_closure_expr(attrs).map_err(|mut err| {
+            self.parse_closure_expr().map_err(|mut err| {
                 // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
                 // then suggest parens around the lhs.
                 if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
@@ -1340,65 +1317,66 @@ impl<'a> Parser<'a> {
                 err
             })
         } else if self.check(&token::OpenDelim(Delimiter::Bracket)) {
-            self.parse_array_or_repeat_expr(attrs, Delimiter::Bracket)
+            self.parse_array_or_repeat_expr(Delimiter::Bracket)
         } else if self.check_path() {
-            self.parse_path_start_expr(attrs)
+            self.parse_path_start_expr()
         } else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
-            self.parse_closure_expr(attrs)
+            self.parse_closure_expr()
         } else if self.eat_keyword(kw::If) {
-            self.parse_if_expr(attrs)
+            self.parse_if_expr()
         } else if self.check_keyword(kw::For) {
             if self.choose_generics_over_qpath(1) {
-                self.parse_closure_expr(attrs)
+                self.parse_closure_expr()
             } else {
                 assert!(self.eat_keyword(kw::For));
-                self.parse_for_expr(None, self.prev_token.span, attrs)
+                self.parse_for_expr(None, self.prev_token.span)
             }
         } else if self.eat_keyword(kw::While) {
-            self.parse_while_expr(None, self.prev_token.span, attrs)
+            self.parse_while_expr(None, self.prev_token.span)
         } else if let Some(label) = self.eat_label() {
-            self.parse_labeled_expr(label, attrs, true)
+            self.parse_labeled_expr(label, true)
         } else if self.eat_keyword(kw::Loop) {
             let sp = self.prev_token.span;
-            self.parse_loop_expr(None, self.prev_token.span, attrs).map_err(|mut err| {
+            self.parse_loop_expr(None, self.prev_token.span).map_err(|mut err| {
                 err.span_label(sp, "while parsing this `loop` expression");
                 err
             })
         } else if self.eat_keyword(kw::Continue) {
             let kind = ExprKind::Continue(self.eat_label());
-            Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
+            Ok(self.mk_expr(lo.to(self.prev_token.span), kind))
         } else if self.eat_keyword(kw::Match) {
             let match_sp = self.prev_token.span;
-            self.parse_match_expr(attrs).map_err(|mut err| {
+            self.parse_match_expr().map_err(|mut err| {
                 err.span_label(match_sp, "while parsing this `match` expression");
                 err
             })
         } else if self.eat_keyword(kw::Unsafe) {
             let sp = self.prev_token.span;
-            self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
-                .map_err(|mut err| {
+            self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err(
+                |mut err| {
                     err.span_label(sp, "while parsing this `unsafe` expression");
                     err
-                })
+                },
+            )
         } else if self.check_inline_const(0) {
             self.parse_const_block(lo.to(self.token.span), false)
         } else if self.is_do_catch_block() {
-            self.recover_do_catch(attrs)
+            self.recover_do_catch()
         } else if self.is_try_block() {
             self.expect_keyword(kw::Try)?;
-            self.parse_try_block(lo, attrs)
+            self.parse_try_block(lo)
         } else if self.eat_keyword(kw::Return) {
-            self.parse_return_expr(attrs)
+            self.parse_return_expr()
         } else if self.eat_keyword(kw::Break) {
-            self.parse_break_expr(attrs)
+            self.parse_break_expr()
         } else if self.eat_keyword(kw::Yield) {
-            self.parse_yield_expr(attrs)
+            self.parse_yield_expr()
         } else if self.is_do_yeet() {
-            self.parse_yeet_expr(attrs)
+            self.parse_yeet_expr()
         } else if self.check_keyword(kw::Let) {
-            self.parse_let_expr(attrs)
+            self.parse_let_expr()
         } else if self.eat_keyword(kw::Underscore) {
-            Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
+            Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore))
         } else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
             // Don't complain about bare semicolons after unclosed braces
             // recovery in order to keep the error count down. Fixing the
@@ -1417,32 +1395,32 @@ impl<'a> Parser<'a> {
             if self.check_keyword(kw::Async) {
                 if self.is_async_block() {
                     // Check for `async {` and `async move {`.
-                    self.parse_async_block(attrs)
+                    self.parse_async_block()
                 } else {
-                    self.parse_closure_expr(attrs)
+                    self.parse_closure_expr()
                 }
             } else if self.eat_keyword(kw::Await) {
-                self.recover_incorrect_await_syntax(lo, self.prev_token.span, attrs)
+                self.recover_incorrect_await_syntax(lo, self.prev_token.span)
             } else {
-                self.parse_lit_expr(attrs)
+                self.parse_lit_expr()
             }
         } else {
-            self.parse_lit_expr(attrs)
+            self.parse_lit_expr()
         }
     }
 
-    fn parse_lit_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_lit_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         match self.parse_opt_lit() {
             Some(literal) => {
-                let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs);
+                let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal));
                 self.maybe_recover_from_bad_qpath(expr)
             }
             None => self.try_macro_suggestion(),
         }
     }
 
-    fn parse_tuple_parens_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_tuple_parens_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
         let (es, trailing_comma) = match self.parse_seq_to_end(
@@ -1462,15 +1440,11 @@ impl<'a> Parser<'a> {
             // `(e,)` is a tuple with only one field, `e`.
             ExprKind::Tup(es)
         };
-        let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
+        let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn parse_array_or_repeat_expr(
-        &mut self,
-        attrs: AttrVec,
-        close_delim: Delimiter,
-    ) -> PResult<'a, P<Expr>> {
+    fn parse_array_or_repeat_expr(&mut self, close_delim: Delimiter) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         self.bump(); // `[` or other open delim
 
@@ -1499,45 +1473,42 @@ impl<'a> Parser<'a> {
                 ExprKind::Array(vec![first_expr])
             }
         };
-        let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
+        let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
-    fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_path_start_expr(&mut self) -> PResult<'a, P<Expr>> {
         let (qself, path) = if self.eat_lt() {
             let (qself, path) = self.parse_qpath(PathStyle::Expr)?;
             (Some(qself), path)
         } else {
             (None, self.parse_path(PathStyle::Expr)?)
         };
-        let lo = path.span;
 
         // `!`, as an operator, is prefix, so we know this isn't that.
-        let (hi, kind) = if self.eat(&token::Not) {
+        let (span, kind) = if self.eat(&token::Not) {
             // MACRO INVOCATION expression
             if qself.is_some() {
                 self.struct_span_err(path.span, "macros cannot use qualified paths").emit();
             }
+            let lo = path.span;
             let mac = MacCall {
                 path,
                 args: self.parse_mac_args()?,
                 prior_type_ascription: self.last_type_ascription,
             };
-            (self.prev_token.span, ExprKind::MacCall(mac))
-        } else if self.check(&token::OpenDelim(Delimiter::Brace)) {
-            if let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path, &attrs) {
+            (lo.to(self.prev_token.span), ExprKind::MacCall(mac))
+        } else if self.check(&token::OpenDelim(Delimiter::Brace)) &&
+            let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path) {
                 if qself.is_some() {
                     self.sess.gated_spans.gate(sym::more_qualified_paths, path.span);
                 }
                 return expr;
-            } else {
-                (path.span, ExprKind::Path(qself, path))
-            }
         } else {
             (path.span, ExprKind::Path(qself, path))
         };
 
-        let expr = self.mk_expr(lo.to(hi), kind, attrs);
+        let expr = self.mk_expr(span, kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
@@ -1545,22 +1516,21 @@ impl<'a> Parser<'a> {
     fn parse_labeled_expr(
         &mut self,
         label: Label,
-        attrs: AttrVec,
         mut consume_colon: bool,
     ) -> PResult<'a, P<Expr>> {
         let lo = label.ident.span;
         let label = Some(label);
         let ate_colon = self.eat(&token::Colon);
         let expr = if self.eat_keyword(kw::While) {
-            self.parse_while_expr(label, lo, attrs)
+            self.parse_while_expr(label, lo)
         } else if self.eat_keyword(kw::For) {
-            self.parse_for_expr(label, lo, attrs)
+            self.parse_for_expr(label, lo)
         } else if self.eat_keyword(kw::Loop) {
-            self.parse_loop_expr(label, lo, attrs)
+            self.parse_loop_expr(label, lo)
         } else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace))
             || self.token.is_whole_block()
         {
-            self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
+            self.parse_block_expr(label, lo, BlockCheckMode::Default)
         } else if !ate_colon
             && (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
         {
@@ -1626,7 +1596,7 @@ impl<'a> Parser<'a> {
                 // Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to supress future errors about `break 'label`.
                 let stmt = self.mk_stmt(span, StmtKind::Expr(expr));
                 let blk = self.mk_block(vec![stmt], BlockCheckMode::Default, span);
-                self.mk_expr(span, ExprKind::Block(blk, label), ThinVec::new())
+                self.mk_expr(span, ExprKind::Block(blk, label))
             });
 
             err.emit();
@@ -1654,7 +1624,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Recover on the syntax `do catch { ... }` suggesting `try { ... }` instead.
-    fn recover_do_catch(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn recover_do_catch(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         self.bump(); // `do`
@@ -1671,7 +1641,7 @@ impl<'a> Parser<'a> {
             .note("following RFC #2388, the new non-placeholder syntax is `try`")
             .emit();
 
-        self.parse_try_block(lo, attrs)
+        self.parse_try_block(lo)
     }
 
     /// Parse an expression if the token can begin one.
@@ -1680,15 +1650,15 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `"return" expr?`.
-    fn parse_return_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_return_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Ret(self.parse_expr_opt()?);
-        let expr = self.mk_expr(lo.to(self.prev_token.span), kind, attrs);
+        let expr = self.mk_expr(lo.to(self.prev_token.span), kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
     /// Parse `"do" "yeet" expr?`.
-    fn parse_yeet_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_yeet_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         self.bump(); // `do`
@@ -1698,7 +1668,7 @@ impl<'a> Parser<'a> {
 
         let span = lo.to(self.prev_token.span);
         self.sess.gated_spans.gate(sym::yeet_expr, span);
-        let expr = self.mk_expr(span, kind, attrs);
+        let expr = self.mk_expr(span, kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
@@ -1710,13 +1680,13 @@ impl<'a> Parser<'a> {
     /// `break 'lbl: loop {}`); a labeled break with an unlabeled loop as its value
     /// expression only gets a warning for compatibility reasons; and a labeled break
     /// with a labeled loop does not even get a warning because there is no ambiguity.
-    fn parse_break_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_break_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let mut label = self.eat_label();
         let kind = if label.is_some() && self.token == token::Colon {
             // The value expression can be a labeled loop, see issue #86948, e.g.:
             // `loop { break 'label: loop { break 'label 42; }; }`
-            let lexpr = self.parse_labeled_expr(label.take().unwrap(), AttrVec::new(), true)?;
+            let lexpr = self.parse_labeled_expr(label.take().unwrap(), true)?;
             self.struct_span_err(
                 lexpr.span,
                 "parentheses are required around this expression to avoid confusion with a labeled break expression",
@@ -1758,17 +1728,17 @@ impl<'a> Parser<'a> {
         } else {
             None
         };
-        let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Break(label, kind), attrs);
+        let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Break(label, kind));
         self.maybe_recover_from_bad_qpath(expr)
     }
 
     /// Parse `"yield" expr?`.
-    fn parse_yield_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_yield_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let kind = ExprKind::Yield(self.parse_expr_opt()?);
         let span = lo.to(self.prev_token.span);
         self.sess.gated_spans.gate(sym::generators, span);
-        let expr = self.mk_expr(span, kind, attrs);
+        let expr = self.mk_expr(span, kind);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
@@ -2012,14 +1982,10 @@ impl<'a> Parser<'a> {
         let lo = self.token.span;
         let minus_present = self.eat(&token::BinOp(token::Minus));
         let lit = self.parse_lit()?;
-        let expr = self.mk_expr(lit.span, ExprKind::Lit(lit), AttrVec::new());
+        let expr = self.mk_expr(lit.span, ExprKind::Lit(lit));
 
         if minus_present {
-            Ok(self.mk_expr(
-                lo.to(self.prev_token.span),
-                self.mk_unary(UnOp::Neg, expr),
-                AttrVec::new(),
-            ))
+            Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_unary(UnOp::Neg, expr)))
         } else {
             Ok(expr)
         }
@@ -2034,13 +2000,9 @@ impl<'a> Parser<'a> {
     /// Emits a suggestion if it looks like the user meant an array but
     /// accidentally used braces, causing the code to be interpreted as a block
     /// expression.
-    fn maybe_suggest_brackets_instead_of_braces(
-        &mut self,
-        lo: Span,
-        attrs: AttrVec,
-    ) -> Option<P<Expr>> {
+    fn maybe_suggest_brackets_instead_of_braces(&mut self, lo: Span) -> Option<P<Expr>> {
         let mut snapshot = self.create_snapshot_for_diagnostic();
-        match snapshot.parse_array_or_repeat_expr(attrs, Delimiter::Brace) {
+        match snapshot.parse_array_or_repeat_expr(Delimiter::Brace) {
             Ok(arr) => {
                 let hi = snapshot.prev_token.span;
                 self.struct_span_err(arr.span, "this is a block expression, not an array")
@@ -2106,10 +2068,9 @@ impl<'a> Parser<'a> {
         opt_label: Option<Label>,
         lo: Span,
         blk_mode: BlockCheckMode,
-        mut attrs: AttrVec,
     ) -> PResult<'a, P<Expr>> {
         if self.is_array_like_block() {
-            if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo, attrs.clone()) {
+            if let Some(arr) = self.maybe_suggest_brackets_instead_of_braces(lo) {
                 return Ok(arr);
             }
         }
@@ -2124,19 +2085,18 @@ impl<'a> Parser<'a> {
                 .emit();
         }
 
-        let (inner_attrs, blk) = self.parse_block_common(lo, blk_mode)?;
-        attrs.extend(inner_attrs);
-        Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
+        let (attrs, blk) = self.parse_block_common(lo, blk_mode)?;
+        Ok(self.mk_expr_with_attrs(blk.span, ExprKind::Block(blk, opt_label), attrs))
     }
 
     /// Parse a block which takes no attributes and has no label
     fn parse_simple_block(&mut self) -> PResult<'a, P<Expr>> {
         let blk = self.parse_block()?;
-        Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()))
+        Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None)))
     }
 
     /// Parses a closure expression (e.g., `move |args| expr`).
-    fn parse_closure_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         let binder = if self.check_keyword(kw::For) {
@@ -2171,7 +2131,7 @@ impl<'a> Parser<'a> {
             _ => {
                 // If an explicit return type is given, require a block to appear (RFC 968).
                 let body_lo = self.token.span;
-                self.parse_block_expr(None, body_lo, BlockCheckMode::Default, AttrVec::new())?
+                self.parse_block_expr(None, body_lo, BlockCheckMode::Default)?
             }
         };
 
@@ -2202,7 +2162,6 @@ impl<'a> Parser<'a> {
                 body,
                 lo.to(decl_hi),
             ),
-            attrs,
         );
 
         // Disable recovery for closure body
@@ -2278,19 +2237,13 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an `if` expression (`if` token already eaten).
-    fn parse_if_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_if_expr(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.prev_token.span;
         let cond = self.parse_cond_expr()?;
-
-        self.parse_if_after_cond(attrs, lo, cond)
+        self.parse_if_after_cond(lo, cond)
     }
 
-    fn parse_if_after_cond(
-        &mut self,
-        attrs: AttrVec,
-        lo: Span,
-        mut cond: P<Expr>,
-    ) -> PResult<'a, P<Expr>> {
+    fn parse_if_after_cond(&mut self, lo: Span, mut cond: P<Expr>) -> PResult<'a, P<Expr>> {
         let cond_span = cond.span;
         // Tries to interpret `cond` as either a missing expression if it's a block,
         // or as an unfinished expression if it's a binop and the RHS is a block.
@@ -2346,7 +2299,7 @@ impl<'a> Parser<'a> {
             block
         };
         let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None };
-        Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els), attrs))
+        Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els)))
     }
 
     fn error_missing_if_then_block(
@@ -2388,7 +2341,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `let $pat = $expr` pseudo-expression.
-    fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_let_expr(&mut self) -> PResult<'a, P<Expr>> {
         // This is a *approximate* heuristic that detects if `let` chains are
         // being parsed in the right position. It's approximate because it
         // doesn't deny all invalid `let` expressions, just completely wrong usages.
@@ -2414,7 +2367,7 @@ impl<'a> Parser<'a> {
             this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
         })?;
         let span = lo.to(expr.span);
-        Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span), attrs))
+        Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span)))
     }
 
     /// Parses an `else { ... }` expression (`else` token already eaten).
@@ -2422,7 +2375,7 @@ impl<'a> Parser<'a> {
         let else_span = self.prev_token.span; // `else`
         let attrs = self.parse_outer_attributes()?.take_for_recovery(); // For recovery.
         let expr = if self.eat_keyword(kw::If) {
-            self.parse_if_expr(AttrVec::new())?
+            self.parse_if_expr()?
         } else if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) {
             self.parse_simple_block()?
         } else {
@@ -2445,7 +2398,7 @@ impl<'a> Parser<'a> {
                             Applicability::MaybeIncorrect,
                         )
                         .emit();
-                    self.parse_if_after_cond(AttrVec::new(), cond.span.shrink_to_lo(), cond)?
+                    self.parse_if_after_cond(cond.span.shrink_to_lo(), cond)?
                 }
                 Err(e) => {
                     e.cancel();
@@ -2482,12 +2435,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten).
-    fn parse_for_expr(
-        &mut self,
-        opt_label: Option<Label>,
-        lo: Span,
-        mut attrs: AttrVec,
-    ) -> PResult<'a, P<Expr>> {
+    fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         // Record whether we are about to parse `for (`.
         // This is used below for recovery in case of `for ( $stuff ) $block`
         // in which case we will suggest `for $stuff $block`.
@@ -2510,11 +2458,10 @@ impl<'a> Parser<'a> {
 
         let pat = self.recover_parens_around_for_head(pat, begin_paren);
 
-        let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
-        attrs.extend(iattrs);
+        let (attrs, loop_block) = self.parse_inner_attrs_and_block()?;
 
         let kind = ExprKind::ForLoop(pat, expr, loop_block, opt_label);
-        Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
+        Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
     }
 
     fn error_missing_in_for_loop(&mut self) {
@@ -2538,35 +2485,31 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `while` or `while let` expression (`while` token already eaten).
-    fn parse_while_expr(
-        &mut self,
-        opt_label: Option<Label>,
-        lo: Span,
-        mut attrs: AttrVec,
-    ) -> PResult<'a, P<Expr>> {
+    fn parse_while_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
         let cond = self.parse_cond_expr().map_err(|mut err| {
             err.span_label(lo, "while parsing the condition of this `while` expression");
             err
         })?;
-        let (iattrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| {
+        let (attrs, body) = self.parse_inner_attrs_and_block().map_err(|mut err| {
             err.span_label(lo, "while parsing the body of this `while` expression");
             err.span_label(cond.span, "this `while` condition successfully parsed");
             err
         })?;
-        attrs.extend(iattrs);
-        Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::While(cond, body, opt_label), attrs))
+        Ok(self.mk_expr_with_attrs(
+            lo.to(self.prev_token.span),
+            ExprKind::While(cond, body, opt_label),
+            attrs,
+        ))
     }
 
     /// Parses `loop { ... }` (`loop` token already eaten).
-    fn parse_loop_expr(
-        &mut self,
-        opt_label: Option<Label>,
-        lo: Span,
-        mut attrs: AttrVec,
-    ) -> PResult<'a, P<Expr>> {
-        let (iattrs, body) = self.parse_inner_attrs_and_block()?;
-        attrs.extend(iattrs);
-        Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::Loop(body, opt_label), attrs))
+    fn parse_loop_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> {
+        let (attrs, body) = self.parse_inner_attrs_and_block()?;
+        Ok(self.mk_expr_with_attrs(
+            lo.to(self.prev_token.span),
+            ExprKind::Loop(body, opt_label),
+            attrs,
+        ))
     }
 
     pub(crate) fn eat_label(&mut self) -> Option<Label> {
@@ -2577,7 +2520,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `match ... { ... }` expression (`match` token already eaten).
-    fn parse_match_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_match_expr(&mut self) -> PResult<'a, P<Expr>> {
         let match_span = self.prev_token.span;
         let lo = self.prev_token.span;
         let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
@@ -2597,7 +2540,7 @@ impl<'a> Parser<'a> {
                 return Err(e);
             }
         }
-        attrs.extend(self.parse_inner_attributes()?);
+        let attrs = self.parse_inner_attributes()?;
 
         let mut arms: Vec<Arm> = Vec::new();
         while self.token != token::CloseDelim(Delimiter::Brace) {
@@ -2611,13 +2554,17 @@ impl<'a> Parser<'a> {
                     if self.token == token::CloseDelim(Delimiter::Brace) {
                         self.bump();
                     }
-                    return Ok(self.mk_expr(span, ExprKind::Match(scrutinee, arms), attrs));
+                    return Ok(self.mk_expr_with_attrs(
+                        span,
+                        ExprKind::Match(scrutinee, arms),
+                        attrs,
+                    ));
                 }
             }
         }
         let hi = self.token.span;
         self.bump();
-        Ok(self.mk_expr(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
+        Ok(self.mk_expr_with_attrs(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
     }
 
     /// Attempt to recover from match arm body with statements and no surrounding braces.
@@ -2877,9 +2824,8 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a `try {...}` expression (`try` token already eaten).
-    fn parse_try_block(&mut self, span_lo: Span, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
-        let (iattrs, body) = self.parse_inner_attrs_and_block()?;
-        attrs.extend(iattrs);
+    fn parse_try_block(&mut self, span_lo: Span) -> PResult<'a, P<Expr>> {
+        let (attrs, body) = self.parse_inner_attrs_and_block()?;
         if self.eat_keyword(kw::Catch) {
             let mut error = self.struct_span_err(
                 self.prev_token.span,
@@ -2891,7 +2837,7 @@ impl<'a> Parser<'a> {
         } else {
             let span = span_lo.to(body.span);
             self.sess.gated_spans.gate(sym::try_blocks, span);
-            Ok(self.mk_expr(span, ExprKind::TryBlock(body), attrs))
+            Ok(self.mk_expr_with_attrs(span, ExprKind::TryBlock(body), attrs))
         }
     }
 
@@ -2913,14 +2859,13 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an `async move? {...}` expression.
-    fn parse_async_block(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
+    fn parse_async_block(&mut self) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
         self.expect_keyword(kw::Async)?;
         let capture_clause = self.parse_capture_clause()?;
-        let (iattrs, body) = self.parse_inner_attrs_and_block()?;
-        attrs.extend(iattrs);
+        let (attrs, body) = self.parse_inner_attrs_and_block()?;
         let kind = ExprKind::Async(capture_clause, DUMMY_NODE_ID, body);
-        Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
+        Ok(self.mk_expr_with_attrs(lo.to(self.prev_token.span), kind, attrs))
     }
 
     fn is_async_block(&self) -> bool {
@@ -2954,14 +2899,13 @@ impl<'a> Parser<'a> {
         &mut self,
         qself: Option<&ast::QSelf>,
         path: &ast::Path,
-        attrs: &AttrVec,
     ) -> Option<PResult<'a, P<Expr>>> {
         let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
         if struct_allowed || self.is_certainly_not_a_block() {
             if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) {
                 return Some(Err(err));
             }
-            let expr = self.parse_struct_expr(qself.cloned(), path.clone(), attrs.clone(), true);
+            let expr = self.parse_struct_expr(qself.cloned(), path.clone(), true);
             if let (Ok(expr), false) = (&expr, struct_allowed) {
                 // This is a struct literal, but we don't can't accept them here.
                 self.error_struct_lit_not_allowed_here(path.span, expr.span);
@@ -3098,7 +3042,6 @@ impl<'a> Parser<'a> {
         &mut self,
         qself: Option<ast::QSelf>,
         pth: ast::Path,
-        attrs: AttrVec,
         recover: bool,
     ) -> PResult<'a, P<Expr>> {
         let lo = pth.span;
@@ -3111,7 +3054,7 @@ impl<'a> Parser<'a> {
         } else {
             ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
         };
-        Ok(self.mk_expr(span, expr, attrs))
+        Ok(self.mk_expr(span, expr))
     }
 
     /// Use in case of error after field-looking code: `S { foo: () with a }`.
@@ -3166,7 +3109,7 @@ impl<'a> Parser<'a> {
                 // Mimic `x: x` for the `x` field shorthand.
                 let ident = this.parse_ident_common(false)?;
                 let path = ast::Path::from_ident(ident);
-                (ident, this.mk_expr(ident.span, ExprKind::Path(None, path), AttrVec::new()))
+                (ident, this.mk_expr(ident.span, ExprKind::Path(None, path)))
             } else {
                 let ident = this.parse_field_name()?;
                 this.error_on_eq_field_init(ident);
@@ -3271,17 +3214,25 @@ impl<'a> Parser<'a> {
 
     fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> {
         let span = lo.to(self.prev_token.span);
-        let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), AttrVec::new());
+        let await_expr = self.mk_expr(span, ExprKind::Await(self_arg));
         self.recover_from_await_method_call();
         await_expr
     }
 
-    pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
-        P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
+    pub(crate) fn mk_expr_with_attrs<A>(&self, span: Span, kind: ExprKind, attrs: A) -> P<Expr>
+    where
+        A: Into<AttrVec>,
+    {
+        P(Expr { kind, span, attrs: attrs.into(), id: DUMMY_NODE_ID, tokens: None })
+    }
+
+    // njn: rename
+    pub(crate) fn mk_expr(&self, span: Span, kind: ExprKind) -> P<Expr> {
+        P(Expr { kind, span, attrs: AttrVec::new(), id: DUMMY_NODE_ID, tokens: None })
     }
 
     pub(super) fn mk_expr_err(&self, span: Span) -> P<Expr> {
-        self.mk_expr(span, ExprKind::Err, AttrVec::new())
+        self.mk_expr(span, ExprKind::Err)
     }
 
     /// Create expression span ensuring the span of the parent node
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 81d0e4733d0..f3f070e6eb0 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2338,7 +2338,7 @@ impl<'a> Parser<'a> {
                 }
             };
 
-            let span = lo.until(this.token.span);
+            let span = lo.to(this.prev_token.span);
 
             Ok((
                 Param {
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index c088b6e1e0e..d61da7b6cc0 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1116,10 +1116,14 @@ impl<'a> Parser<'a> {
         let (attrs, blk) = self.parse_inner_attrs_and_block()?;
         let anon_const = AnonConst {
             id: DUMMY_NODE_ID,
-            value: self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()),
+            value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
         };
         let blk_span = anon_const.value.span;
-        Ok(self.mk_expr(span.to(blk_span), ExprKind::ConstBlock(anon_const), AttrVec::from(attrs)))
+        Ok(self.mk_expr_with_attrs(
+            span.to(blk_span),
+            ExprKind::ConstBlock(anon_const),
+            AttrVec::from(attrs),
+        ))
     }
 
     /// Parses mutability (`mut` or nothing).
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index ba77a395840..98c974420eb 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -4,8 +4,8 @@ use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter};
 use rustc_ast::{
-    self as ast, AttrVec, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat,
-    PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
+    self as ast, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat, PatField,
+    PatKind, Path, QSelf, RangeEnd, RangeSyntax,
 };
 use rustc_ast_pretty::pprust;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
@@ -385,7 +385,7 @@ impl<'a> Parser<'a> {
             if qself.is_none() && self.check(&token::Not) {
                 self.parse_pat_mac_invoc(path)?
             } else if let Some(form) = self.parse_range_end() {
-                let begin = self.mk_expr(span, ExprKind::Path(qself, path), AttrVec::new());
+                let begin = self.mk_expr(span, ExprKind::Path(qself, path));
                 self.parse_pat_range_begin_with(begin, form)?
             } else if self.check(&token::OpenDelim(Delimiter::Brace)) {
                 self.parse_pat_struct(qself, path)?
@@ -807,7 +807,7 @@ impl<'a> Parser<'a> {
                 (None, self.parse_path(PathStyle::Expr)?)
             };
             let hi = self.prev_token.span;
-            Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path), AttrVec::new()))
+            Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path)))
         } else {
             self.parse_literal_maybe_minus()
         }
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 5cf1758c31f..8332c171a9c 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -652,12 +652,7 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> {
         // Parse const argument.
         let value = if let token::OpenDelim(Delimiter::Brace) = self.token.kind {
-            self.parse_block_expr(
-                None,
-                self.token.span,
-                BlockCheckMode::Default,
-                ast::AttrVec::new(),
-            )?
+            self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)?
         } else {
             self.handle_unambiguous_unbraced_const_arg()?
         };
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index d8b39a406cc..ade0f4fbc86 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -143,10 +143,10 @@ impl<'a> Parser<'a> {
             }
 
             let expr = if this.eat(&token::OpenDelim(Delimiter::Brace)) {
-                this.parse_struct_expr(None, path, AttrVec::new(), true)?
+                this.parse_struct_expr(None, path, true)?
             } else {
                 let hi = this.prev_token.span;
-                this.mk_expr(lo.to(hi), ExprKind::Path(None, path), AttrVec::new())
+                this.mk_expr(lo.to(hi), ExprKind::Path(None, path))
             };
 
             let expr = this.with_res(Restrictions::STMT_EXPR, |this| {
@@ -192,7 +192,7 @@ impl<'a> Parser<'a> {
             StmtKind::MacCall(P(MacCallStmt { mac, style, attrs, tokens: None }))
         } else {
             // Since none of the above applied, this is an expression statement macro.
-            let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac), AttrVec::new());
+            let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
             let e = self.maybe_recover_from_bad_qpath(e)?;
             let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?;
             let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?;
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 461dd52b9f2..7124b84bfef 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -98,7 +98,7 @@ use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, DefIdTree, RootVariableMinCaptureList, Ty, TyCtxt};
 use rustc_session::lint;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
 
 use std::collections::VecDeque;
 use std::io;
@@ -1549,6 +1549,8 @@ impl<'tcx> Liveness<'_, 'tcx> {
                 .or_insert_with(|| (ln, var, vec![id_and_sp]));
         });
 
+        let can_remove = matches!(&pat.kind, hir::PatKind::Struct(_, _, true));
+
         for (_, (ln, var, hir_ids_and_spans)) in vars {
             if self.used_on_entry(ln, var) {
                 let id = hir_ids_and_spans[0].0;
@@ -1556,16 +1558,18 @@ impl<'tcx> Liveness<'_, 'tcx> {
                     hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect();
                 on_used_on_entry(spans, id, ln, var);
             } else {
-                self.report_unused(hir_ids_and_spans, ln, var);
+                self.report_unused(hir_ids_and_spans, ln, var, can_remove);
             }
         }
     }
 
+    #[tracing::instrument(skip(self), level = "INFO")]
     fn report_unused(
         &self,
         hir_ids_and_spans: Vec<(HirId, Span, Span)>,
         ln: LiveNode,
         var: Variable,
+        can_remove: bool,
     ) {
         let first_hir_id = hir_ids_and_spans[0].0;
 
@@ -1590,6 +1594,32 @@ impl<'tcx> Liveness<'_, 'tcx> {
                             .emit();
                     },
                 )
+            } else if can_remove {
+                self.ir.tcx.struct_span_lint_hir(
+                    lint::builtin::UNUSED_VARIABLES,
+                    first_hir_id,
+                    hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(),
+                    |lint| {
+                        let mut err = lint.build(&format!("unused variable: `{}`", name));
+                        err.multipart_suggestion(
+                            "try removing the field",
+                            hir_ids_and_spans
+                                .iter()
+                                .map(|(_, pat_span, _)| {
+                                    let span = self
+                                        .ir
+                                        .tcx
+                                        .sess
+                                        .source_map()
+                                        .span_extend_to_next_char(*pat_span, ',', true);
+                                    (span.with_hi(BytePos(span.hi().0 + 1)), String::new())
+                                })
+                                .collect(),
+                            Applicability::MachineApplicable,
+                        );
+                        err.emit();
+                    },
+                );
             } else {
                 let (shorthands, non_shorthands): (Vec<_>, Vec<_>) =
                     hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| {
diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml
index 37cfc4a0dc3..6b1eaa4d399 100644
--- a/compiler/rustc_session/Cargo.toml
+++ b/compiler/rustc_session/Cargo.toml
@@ -15,6 +15,5 @@ rustc_serialize = { path = "../rustc_serialize" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_span = { path = "../rustc_span" }
 rustc_fs_util = { path = "../rustc_fs_util" }
-num_cpus = "1.0"
 rustc_ast = { path = "../rustc_ast" }
 rustc_lint_defs = { path = "../rustc_lint_defs" }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 63ae91f8e6c..46bba02537d 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -582,7 +582,7 @@ mod parse {
     pub(crate) fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool {
         match v.and_then(|s| s.parse().ok()) {
             Some(0) => {
-                *slot = ::num_cpus::get();
+                *slot = std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get);
                 true
             }
             Some(i) => {
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 28381157d50..ad9f5ba85a1 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -722,7 +722,7 @@ impl SourceMap {
         })
     }
 
-    /// Extends the given `Span` to just after the next occurrence of `c`.
+    /// Extends the given `Span` to just before the next occurrence of `c`.
     pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
         if let Ok(next_source) = self.span_to_next_source(sp) {
             let next_source = next_source.split(c).next().unwrap_or("");
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index a54b36262b2..9bb41b900b8 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -307,7 +307,13 @@ fn negative_impl<'cx, 'tcx>(
             tcx.impl_subject(impl1_def_id),
         ) {
             Ok(s) => s,
-            Err(err) => bug!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+            Err(err) => {
+                tcx.sess.delay_span_bug(
+                    tcx.def_span(impl1_def_id),
+                    format!("failed to fully normalize {:?}: {:?}", impl1_def_id, err),
+                );
+                return false;
+            }
         };
 
         // Attempt to prove that impl2 applies, given all of the above.
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 664ffa1ddd2..84c06fdce70 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -53,7 +53,6 @@ dependencies = [
  "hex",
  "ignore",
  "libc",
- "num_cpus",
  "once_cell",
  "opener",
  "pretty_assertions",
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 84f6aaf99c1..2dad41bb18f 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -38,7 +38,6 @@ test = false
 cmake = "0.1.38"
 fd-lock = "3.0.6"
 filetime = "0.2"
-num_cpus = "1.0"
 getopts = "0.2.19"
 cc = "1.0.69"
 libc = "0.2"
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index c4983accc68..203db2d3876 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -1465,7 +1465,7 @@ fn set<T>(field: &mut T, val: Option<T>) {
 
 fn threads_from_config(v: u32) -> u32 {
     match v {
-        0 => num_cpus::get() as u32,
+        0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32,
         n => n,
     }
 }
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 1edb513f0b6..789da748100 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -220,7 +220,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
         let j_msg = format!(
             "number of jobs to run in parallel; \
              defaults to {} (this host's logical CPU count)",
-            num_cpus::get()
+            std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get)
         );
         opts.optopt("j", "jobs", &j_msg, "JOBS");
         opts.optflag("h", "help", "print this help message");
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index a242243aaaf..dcfa92d1004 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1008,7 +1008,9 @@ impl Build {
     /// Returns the number of parallel jobs that have been configured for this
     /// build.
     fn jobs(&self) -> u32 {
-        self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32)
+        self.config.jobs.unwrap_or_else(|| {
+            std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
+        })
     }
 
     fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> {
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 5f3793ead42..1fedb0144d1 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -662,12 +662,10 @@ impl FromWithTcx<clean::Variant> for Variant {
             Tuple(fields) => Variant::Tuple(
                 fields
                     .into_iter()
-                    .map(|f| {
-                        if let clean::StructFieldItem(ty) = *f.kind {
-                            ty.into_tcx(tcx)
-                        } else {
-                            unreachable!()
-                        }
+                    .filter_map(|f| match *f.kind {
+                        clean::StructFieldItem(ty) => Some(ty.into_tcx(tcx)),
+                        clean::StrippedItem(_) => None,
+                        _ => unreachable!(),
                     })
                     .collect(),
             ),
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index 3f069e8393f..83ed3752a82 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -88,7 +88,17 @@ impl<'a> DocFolder for Stripper<'a> {
             }
 
             // handled in the `strip-priv-imports` pass
-            clean::ExternCrateItem { .. } | clean::ImportItem(..) => {}
+            clean::ExternCrateItem { .. } => {}
+            clean::ImportItem(ref imp) => {
+                // Because json doesn't inline imports from private modules, we need to mark
+                // the imported item as retained so it's impls won't be stripped.i
+                //
+                // FIXME: Is it necessary to check for json output here: See
+                // https://github.com/rust-lang/rust/pull/100325#discussion_r941495215
+                if let Some(did) = imp.source.did && self.is_json_output {
+                    self.retained.insert(did.into());
+                }
+            }
 
             clean::ImplItem(..) => {}
 
diff --git a/src/test/run-make/translation/broken.ftl b/src/test/run-make/translation/broken.ftl
index 1482dd2824a..4e358583528 100644
--- a/src/test/run-make/translation/broken.ftl
+++ b/src/test/run-make/translation/broken.ftl
@@ -1,3 +1,3 @@
 # `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
-parser-struct-literal-body-without-path = this is a {$foo} message
+parser_struct_literal_body_without_path = this is a {$foo} message
     .suggestion = this is a test suggestion
diff --git a/src/test/run-make/translation/missing.ftl b/src/test/run-make/translation/missing.ftl
index 43076b1d6ae..77bbda3575b 100644
--- a/src/test/run-make/translation/missing.ftl
+++ b/src/test/run-make/translation/missing.ftl
@@ -1,3 +1,3 @@
-# `parser-struct-literal-body-without-path` isn't provided by this resource at all, so the
+# `parser_struct_literal_body_without_path` isn't provided by this resource at all, so the
 # fallback should be used.
 foo = bar
diff --git a/src/test/run-make/translation/working.ftl b/src/test/run-make/translation/working.ftl
index 4681b879cda..d5ea8673875 100644
--- a/src/test/run-make/translation/working.ftl
+++ b/src/test/run-make/translation/working.ftl
@@ -1,2 +1,2 @@
-parser-struct-literal-body-without-path = this is a test message
+parser_struct_literal_body_without_path = this is a test message
     .suggestion = this is a test suggestion
diff --git a/src/test/rustdoc-json/enum_variant_hidden.rs b/src/test/rustdoc-json/enum_variant_hidden.rs
new file mode 100644
index 00000000000..96c96a975d3
--- /dev/null
+++ b/src/test/rustdoc-json/enum_variant_hidden.rs
@@ -0,0 +1,13 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/100529>.
+
+#![no_core]
+#![feature(no_core)]
+
+// @has enum_variant_hidden.json "$.index[*][?(@.name=='ParseError')]"
+// @has - "$.index[*][?(@.name=='UnexpectedEndTag')]"
+// @is - "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_kind" '"tuple"'
+// @is - "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_inner" []
+
+pub enum ParseError {
+    UnexpectedEndTag(#[doc(hidden)] u32),
+}
diff --git a/src/test/rustdoc-json/impls/import_from_private.rs b/src/test/rustdoc-json/impls/import_from_private.rs
new file mode 100644
index 00000000000..ef4d8aa39f8
--- /dev/null
+++ b/src/test/rustdoc-json/impls/import_from_private.rs
@@ -0,0 +1,24 @@
+// https://github.com/rust-lang/rust/issues/100252
+
+#![feature(no_core)]
+#![no_core]
+
+mod bar {
+    // @set baz = import_from_private.json "$.index[*][?(@.kind=='struct')].id"
+    pub struct Baz;
+    // @set impl = - "$.index[*][?(@.kind=='impl')].id"
+    impl Baz {
+        // @set doit = - "$.index[*][?(@.kind=='method')].id"
+        pub fn doit() {}
+    }
+}
+
+// @set import = - "$.index[*][?(@.kind=='import')].id"
+pub use bar::Baz;
+
+// FIXME(adotinthevoid): Use hasexact once #99474 lands
+
+// @has - "$.index[*][?(@.kind=='module')].inner.items[*]" $import
+// @is  - "$.index[*][?(@.kind=='import')].inner.id" $baz
+// @has - "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
+// @has - "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
diff --git a/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
new file mode 100644
index 00000000000..84b6c3e6c00
--- /dev/null
+++ b/src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
@@ -0,0 +1,2 @@
+some_slug = hi
+    .label-has-hyphens = test
diff --git a/src/test/ui-fulldeps/fluent-messages/missing-message.ftl b/src/test/ui-fulldeps/fluent-messages/missing-message.ftl
index 372b1a2e453..74b2aa1d44d 100644
--- a/src/test/ui-fulldeps/fluent-messages/missing-message.ftl
+++ b/src/test/ui-fulldeps/fluent-messages/missing-message.ftl
@@ -1 +1 @@
-missing-message = 
+missing_message =
diff --git a/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
new file mode 100644
index 00000000000..07517c9a243
--- /dev/null
+++ b/src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
@@ -0,0 +1 @@
+this-slug-has-hyphens = hi
diff --git a/src/test/ui-fulldeps/fluent-messages/test.rs b/src/test/ui-fulldeps/fluent-messages/test.rs
index 0390a07850b..f0f35780666 100644
--- a/src/test/ui-fulldeps/fluent-messages/test.rs
+++ b/src/test/ui-fulldeps/fluent-messages/test.rs
@@ -55,6 +55,24 @@ mod duplicate {
     }
 }
 
+mod slug_with_hyphens {
+    use super::fluent_messages;
+
+    fluent_messages! {
+        slug_with_hyphens => "./slug-with-hyphens.ftl",
+//~^ ERROR name `this-slug-has-hyphens` contains a '-' character
+    }
+}
+
+mod label_with_hyphens {
+    use super::fluent_messages;
+
+    fluent_messages! {
+        label_with_hyphens => "./label-with-hyphens.ftl",
+//~^ ERROR attribute `label-has-hyphens` contains a '-' character
+    }
+}
+
 mod valid {
     use super::fluent_messages;
 
diff --git a/src/test/ui-fulldeps/fluent-messages/test.stderr b/src/test/ui-fulldeps/fluent-messages/test.stderr
index 526bca43f69..856642c4818 100644
--- a/src/test/ui-fulldeps/fluent-messages/test.stderr
+++ b/src/test/ui-fulldeps/fluent-messages/test.stderr
@@ -22,11 +22,11 @@ LL |         missing_message => "./missing-message.ftl",
    |
    = help: see additional errors emitted
 
-error: expected a message field for "missing-message"
+error: expected a message field for "missing_message"
  --> ./missing-message.ftl:1:1
   |
-1 | missing-message = 
-  | ^^^^^^^^^^^^^^^^^^
+1 | missing_message =
+  | ^^^^^^^^^^^^^^^^^
   |
 
 error: overrides existing message: `key`
@@ -41,5 +41,21 @@ help: previously defined in this resource
 LL |         a => "./duplicate-a.ftl",
    |         ^
 
-error: aborting due to 4 previous errors
+error: name `this-slug-has-hyphens` contains a '-' character
+  --> $DIR/test.rs:62:9
+   |
+LL |         slug_with_hyphens => "./slug-with-hyphens.ftl",
+   |         ^^^^^^^^^^^^^^^^^
+   |
+   = help: replace any '-'s with '_'s
+
+error: attribute `label-has-hyphens` contains a '-' character
+  --> $DIR/test.rs:71:9
+   |
+LL |         label_with_hyphens => "./label-with-hyphens.ftl",
+   |         ^^^^^^^^^^^^^^^^^^
+   |
+   = help: replace any '-'s with '_'s
+
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/argument-suggestions/complex.stderr b/src/test/ui/argument-suggestions/complex.stderr
index fa030a8f49d..bf49e744458 100644
--- a/src/test/ui/argument-suggestions/complex.stderr
+++ b/src/test/ui/argument-suggestions/complex.stderr
@@ -8,7 +8,7 @@ note: function defined here
   --> $DIR/complex.rs:11:4
    |
 LL | fn complex(_i: u32, _s: &str, _e: E, _f: F, _g: G, _x: X, _y: Y, _z: Z ) {}
-   |    ^^^^^^^ -------  --------  -----  -----  -----  -----  -----  ------
+   |    ^^^^^^^ -------  --------  -----  -----  -----  -----  -----  -----
 help: did you mean
    |
 LL |   complex(/* u32 */, &"", /* E */, F::X2, G{}, X {}, Y {}, Z {});
diff --git a/src/test/ui/c-variadic/issue-86053-1.stderr b/src/test/ui/c-variadic/issue-86053-1.stderr
index 5d119bb8557..60b379faf4e 100644
--- a/src/test/ui/c-variadic/issue-86053-1.stderr
+++ b/src/test/ui/c-variadic/issue-86053-1.stderr
@@ -44,19 +44,19 @@ error: `...` must be the last argument of a C-variadic function
   --> $DIR/issue-86053-1.rs:11:12
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |            ^^^^
+   |            ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
   --> $DIR/issue-86053-1.rs:11:12
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |            ^^^^
+   |            ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
   --> $DIR/issue-86053-1.rs:11:36
    |
 LL |     self , ... ,   self ,   self , ... ) where F : FnOnce ( & 'a & 'b usize ) {
-   |                                    ^^^^
+   |                                    ^^^
 
 error[E0412]: cannot find type `F` in this scope
   --> $DIR/issue-86053-1.rs:11:48
diff --git a/src/test/ui/coherence/issue-100191-2.rs b/src/test/ui/coherence/issue-100191-2.rs
new file mode 100644
index 00000000000..1c8316f87fa
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191-2.rs
@@ -0,0 +1,12 @@
+//~ ERROR overflow evaluating the requirement `T: Trait<_>`
+
+#![feature(specialization, with_negative_coherence)]
+#![allow(incomplete_features)]
+
+pub trait Trait<T> {}
+
+default impl<T, U> Trait<T> for U {}
+
+impl<T> Trait<<T as Iterator>::Item> for T {}
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191-2.stderr b/src/test/ui/coherence/issue-100191-2.stderr
new file mode 100644
index 00000000000..ea09fb15bdf
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191-2.stderr
@@ -0,0 +1,14 @@
+error[E0275]: overflow evaluating the requirement `T: Trait<_>`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_100191_2`)
+note: required because of the requirements on the impl of `Trait<_>` for `T`
+  --> $DIR/issue-100191-2.rs:8:20
+   |
+LL | default impl<T, U> Trait<T> for U {}
+   |                    ^^^^^^^^     ^
+   = note: 128 redundant requirements hidden
+   = note: required because of the requirements on the impl of `Trait<_>` for `T`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/src/test/ui/coherence/issue-100191.rs b/src/test/ui/coherence/issue-100191.rs
new file mode 100644
index 00000000000..e8597fde54d
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191.rs
@@ -0,0 +1,21 @@
+#![crate_type = "lib"]
+#![feature(specialization, with_negative_coherence)]
+#![allow(incomplete_features)]
+
+trait X {}
+trait Y: X {}
+trait Z {
+    type Assoc: Y;
+}
+struct A<T>(T);
+
+impl<T> Y for T where T: X {}
+impl<T: X> Z for A<T> {
+    type Assoc = T;
+}
+
+// this impl is invalid, but causes an ICE anyway
+impl<T> From<<A<T> as Z>::Assoc> for T {}
+//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+
+fn main() {}
diff --git a/src/test/ui/coherence/issue-100191.stderr b/src/test/ui/coherence/issue-100191.stderr
new file mode 100644
index 00000000000..1adb0f1e4fa
--- /dev/null
+++ b/src/test/ui/coherence/issue-100191.stderr
@@ -0,0 +1,12 @@
+error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
+  --> $DIR/issue-100191.rs:18:6
+   |
+LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
+   |      ^ type parameter `T` must be used as the type parameter for some local type
+   |
+   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
+   = note: only traits defined in the current crate can be implemented for a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0210`.
diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.rs b/src/test/ui/suggestions/dont-try-removing-the-field.rs
new file mode 100644
index 00000000000..948aa2b94d9
--- /dev/null
+++ b/src/test/ui/suggestions/dont-try-removing-the-field.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+    foo: i32,
+    bar: i32,
+    baz: (),
+}
+
+fn use_foo(x: Foo) -> (i32, i32) {
+    let Foo { foo, bar, baz } = x; //~ WARNING unused variable: `baz`
+                                   //~| help: try ignoring the field
+    return (foo, bar);
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/dont-try-removing-the-field.stderr b/src/test/ui/suggestions/dont-try-removing-the-field.stderr
new file mode 100644
index 00000000000..263171a4ac4
--- /dev/null
+++ b/src/test/ui/suggestions/dont-try-removing-the-field.stderr
@@ -0,0 +1,10 @@
+warning: unused variable: `baz`
+  --> $DIR/dont-try-removing-the-field.rs:12:25
+   |
+LL |     let Foo { foo, bar, baz } = x;
+   |                         ^^^ help: try ignoring the field: `baz: _`
+   |
+   = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/suggestions/suggest-ref-macro.stderr b/src/test/ui/suggestions/suggest-ref-macro.stderr
index 84cbc93571a..17de49fbd84 100644
--- a/src/test/ui/suggestions/suggest-ref-macro.stderr
+++ b/src/test/ui/suggestions/suggest-ref-macro.stderr
@@ -10,14 +10,8 @@ LL | #[hello]
 note: function defined here
   --> $DIR/suggest-ref-macro.rs:8:1
    |
-LL |   #[hello]
-   |  _-^^^^^^^
-LL | | fn abc() {}
-LL | |
-LL | | fn x(_: &mut i32) {}
-LL | |
-LL | | macro_rules! bla {
-   | |_____________-
+LL | #[hello]
+   | ^^^^^^^^
    = note: this error originates in the attribute macro `hello` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0308]: mismatched types
diff --git a/src/test/ui/suggestions/try-removing-the-field.rs b/src/test/ui/suggestions/try-removing-the-field.rs
new file mode 100644
index 00000000000..9d0573ca255
--- /dev/null
+++ b/src/test/ui/suggestions/try-removing-the-field.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![allow(dead_code)]
+
+struct Foo {
+    foo: i32,
+    bar: (),
+    baz: (),
+}
+
+fn use_foo(x: Foo) -> i32 {
+    let Foo { foo, bar, .. } = x; //~ WARNING unused variable: `bar`
+                                  //~| help: try removing the field
+    return foo;
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/try-removing-the-field.stderr b/src/test/ui/suggestions/try-removing-the-field.stderr
new file mode 100644
index 00000000000..448a2c3d2ec
--- /dev/null
+++ b/src/test/ui/suggestions/try-removing-the-field.stderr
@@ -0,0 +1,12 @@
+warning: unused variable: `bar`
+  --> $DIR/try-removing-the-field.rs:12:20
+   |
+LL |     let Foo { foo, bar, .. } = x;
+   |                    ^^^-
+   |                    |
+   |                    help: try removing the field
+   |
+   = note: `#[warn(unused_variables)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
index 615fd2ccb04..847bc517ea3 100644
--- a/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
+++ b/src/test/ui/type/type-check/issue-88577-check-fn-with-more-than-65535-arguments.stderr
@@ -1,13 +1,13 @@
 error: function can not have more than 65535 arguments
-  --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:24
+  --> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:22
    |
-LL |           fn _f($($t: ()),*) {}
-   |  ________________________^
-LL | |     }
-LL | | }
-LL | |
-LL | | many_args!{[_]########## ######}
-   | |____________^
+LL |         fn _f($($t: ()),*) {}
+   |                      ^
+...
+LL | many_args!{[_]########## ######}
+   | -------------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `many_args` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index c022d3aa0ac..c437bde5ae6 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -13,4 +13,3 @@ tar = "0.4.29"
 sha2 = "0.10.1"
 rayon = "1.5.1"
 hex = "0.4.2"
-num_cpus = "1.13.0"
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index efe3f2b618b..1a6760d8c68 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -210,7 +210,7 @@ fn main() {
     let num_threads = if let Some(num) = env::var_os("BUILD_MANIFEST_NUM_THREADS") {
         num.to_str().unwrap().parse().expect("invalid number for BUILD_MANIFEST_NUM_THREADS")
     } else {
-        num_cpus::get()
+        std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get)
     };
     rayon::ThreadPoolBuilder::new()
         .num_threads(num_threads)